Home Home > GIT Browse > SLE15-SP1-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-08-09 14:35:21 +0200
committerTakashi Iwai <tiwai@suse.de>2018-08-09 14:35:21 +0200
commit1941ed2980a7bc781f747516e741523e8f81d714 (patch)
treea247347e01ef5a9956fff6b9284d2b37ce93c783
parent6b617162c17f62f28590e20f6d8d4cd8669e5fb7 (diff)
parentbde2473fe6c8cb8f68d88523d9a8b0a6ef874fa0 (diff)
Merge branch 'SLE15' into SLE15_EMBARGO
Conflicts: series.conf
-rw-r--r--blacklist.conf10
-rw-r--r--config/arm64/default2
-rw-r--r--config/ppc64le/default2
-rw-r--r--config/ppc64le/vanilla1
-rw-r--r--config/s390x/default2
-rw-r--r--config/s390x/vanilla1
-rw-r--r--config/s390x/zfcpdump2
-rw-r--r--config/x86_64/default3
-rw-r--r--config/x86_64/vanilla1
-rw-r--r--kabi/severities1
-rw-r--r--patches.arch/KVM-PPC-Check-if-IOMMU-page-is-contained-in-the-pinn.patch2
-rw-r--r--patches.drivers/RDMA-qedr-Fix-NULL-pointer-dereference-when-running-.patch39
-rw-r--r--patches.drivers/RDMA-qedr-fix-spelling-mistake-adrresses-addresses.patch27
-rw-r--r--patches.drivers/RDMA-qedr-fix-spelling-mistake-failes-fails.patch27
-rw-r--r--patches.drivers/clk-at91-fix-clk-generated-compilation33
-rw-r--r--patches.drivers/ibmvnic-Remove-code-to-request-error-information.patch292
-rw-r--r--patches.drivers/ibmvnic-Revise-RX-TX-queue-error-messages.patch107
-rw-r--r--patches.drivers/ibmvnic-Update-firmware-error-reporting-with-cause-s.patch74
-rw-r--r--patches.drivers/pinctrl-intel-Add-Intel-Lewisburg-GPIO-support.patch404
-rw-r--r--patches.drivers/qed-Add-link-change-count-value-to-ethtool-statistic.patch96
-rw-r--r--patches.drivers/qed-Add-qed-APIs-for-PHY-module-query.patch221
-rw-r--r--patches.drivers/qed-Add-srq-core-support-for-RoCE-and-iWARP.patch445
-rw-r--r--patches.drivers/qed-Make-some-functions-static.patch348
-rw-r--r--patches.drivers/qed-Utilize-FW-8.37.2.0.patch2340
-rw-r--r--patches.drivers/qed-fix-spelling-mistake-successffuly-successfully.patch27
-rw-r--r--patches.drivers/qed-remove-redundant-functions-qed_get_cm_pq_idx_rl.patch37
-rw-r--r--patches.drivers/qed-remove-redundant-functions-qed_set_gft_event_id_.patch39
-rw-r--r--patches.drivers/qed-remove-redundant-pointer-name.patch39
-rw-r--r--patches.drivers/qed-use-dma_zalloc_coherent-instead-of-allocator-mem.patch38
-rw-r--r--patches.drivers/qede-Add-driver-callbacks-for-eeprom-module-query.patch122
-rw-r--r--patches.drivers/scsi-ata-enhance-the-definition-of-set-max-feature-field-value.patch33
-rw-r--r--patches.drivers/scsi-hisi_sas-add-an-mechanism-to-do-reset-work-synchronously.patch110
-rw-r--r--patches.drivers/scsi-hisi_sas-add-check-of-device-in-hisi_sas_task_exec.patch95
-rw-r--r--patches.drivers/scsi-hisi_sas-add-internal-abort-dev-in-some-places.patch73
-rw-r--r--patches.drivers/scsi-hisi_sas-add-led-feature-for-v3-hw.patch95
-rw-r--r--patches.drivers/scsi-hisi_sas-add-ras-feature-for-v3-hw.patch200
-rw-r--r--patches.drivers/scsi-hisi_sas-add-readl-poll-timeout-helper-wrappers.patch78
-rw-r--r--patches.drivers/scsi-hisi_sas-add-some-checks-to-avoid-free-ing-a-sas_task-twice.patch161
-rw-r--r--patches.drivers/scsi-hisi_sas-add-some-print-to-enhance-debugging.patch240
-rw-r--r--patches.drivers/scsi-hisi_sas-add-v2-hw-force-phy-function-for-internal-ata-command.patch73
-rw-r--r--patches.drivers/scsi-hisi_sas-add-v2-hw-port-axi-error-handling-support.patch106
-rw-r--r--patches.drivers/scsi-hisi_sas-add-v3-hw-module_device_table.patch39
-rw-r--r--patches.drivers/scsi-hisi_sas-add-v3-hw-suspend-and-resume.patch172
-rw-r--r--patches.drivers/scsi-hisi_sas-allocate-slot-buffer-earlier.patch141
-rw-r--r--patches.drivers/scsi-hisi_sas-change-common-allocation-mode-of-device-id.patch61
-rw-r--r--patches.drivers/scsi-hisi_sas-change-frame-type-for-set-max-commands.patch106
-rw-r--r--patches.drivers/scsi-hisi_sas-change-ncq-process-for-v3-hw.patch78
-rw-r--r--patches.drivers/scsi-hisi_sas-change-slot-index-allocation-mode.patch64
-rw-r--r--patches.drivers/scsi-hisi_sas-check-host-frozen-before-calling-done-function.patch164
-rw-r--r--patches.drivers/scsi-hisi_sas-check-iptt-is-valid-before-using-it-for-v3-hw.patch53
-rw-r--r--patches.drivers/scsi-hisi_sas-check-sas_dev-gone-earlier-in-hisi_sas_abort_task.patch55
-rw-r--r--patches.drivers/scsi-hisi_sas-code-cleanup-and-minor-bug-fixes.patch244
-rw-r--r--patches.drivers/scsi-hisi_sas-config-ata-de-reset-as-an-constrained-command-for-v3-hw.patch62
-rw-r--r--patches.drivers/scsi-hisi_sas-consolidate-command-check-in-hisi_sas_get_ata_protocol.patch63
-rw-r--r--patches.drivers/scsi-hisi_sas-create-a-scsi_host_template-per-hw-module.patch287
-rw-r--r--patches.drivers/scsi-hisi_sas-delete-timer-when-removing-hisi_sas-driver.patch62
-rw-r--r--patches.drivers/scsi-hisi_sas-directly-attached-disk-LED-feature-for.patch28
-rw-r--r--patches.drivers/scsi-hisi_sas-do-link-reset-for-some-chl_int2-ints.patch180
-rw-r--r--patches.drivers/scsi-hisi_sas-don-t-lock-dq-for-complete-task-sending.patch338
-rw-r--r--patches.drivers/scsi-hisi_sas-dt-bindings-add-an-property-of-signal-attenuation.patch44
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-a-bug-in-hisi_sas_dev_gone.patch35
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-a-typo-in-hisi_sas_task_prep.patch31
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-dma_unmap_sg-parameter.patch45
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-pi-memory-size.patch35
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-return-value-of-hisi_sas_task_prep.patch58
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-return-value-when-get_free_slot-failed.patch43
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-sas_queue_full-problem-while-running-io.patch42
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-the-issue-of-link-rate-inconsistency.patch124
-rw-r--r--patches.drivers/scsi-hisi_sas-fix-the-issue-of-setting-linkrate-register.patch77
-rw-r--r--patches.drivers/scsi-hisi_sas-improve-int_chnl_int_v2_hw-consistency-with-v3-hw.patch92
-rw-r--r--patches.drivers/scsi-hisi_sas-include-tmf-elements-in-struct-hisi_sas_slot.patch256
-rw-r--r--patches.drivers/scsi-hisi_sas-increase-timer-expire-of-internal-abort-task.patch44
-rw-r--r--patches.drivers/scsi-hisi_sas-init-disks-after-controller-reset.patch79
-rw-r--r--patches.drivers/scsi-hisi_sas-initialize-dq-spinlock-before-use.patch32
-rw-r--r--patches.drivers/scsi-hisi_sas-introduce-hisi_sas_phy_set_linkrate.patch191
-rw-r--r--patches.drivers/scsi-hisi_sas-judge-result-of-internal-abort.patch137
-rw-r--r--patches.drivers/scsi-hisi_sas-make-local-symbol-host_attrs-static.patch34
-rw-r--r--patches.drivers/scsi-hisi_sas-make-return-type-of-prep-functions-void.patch532
-rw-r--r--patches.drivers/scsi-hisi_sas-make-sas-address-of-sata-disks-unique.patch31
-rw-r--r--patches.drivers/scsi-hisi_sas-mark-phy-as-in-reset-for-nexus-reset.patch202
-rw-r--r--patches.drivers/scsi-hisi_sas-modify-hisi_sas_dev_gone-for-reset.patch54
-rw-r--r--patches.drivers/scsi-hisi_sas-modify-some-register-config-for-hip08.patch81
-rw-r--r--patches.drivers/scsi-hisi_sas-optimise-port-id-refresh-function.patch115
-rw-r--r--patches.drivers/scsi-hisi_sas-optimise-the-usage-of-dq-locking.patch78
-rw-r--r--patches.drivers/scsi-hisi_sas-print-device-id-for-errors.patch54
-rw-r--r--patches.drivers/scsi-hisi_sas-re-add-the-lldd_port_deformed.patch47
-rw-r--r--patches.drivers/scsi-hisi_sas-relocate-clearing-itct-and-freeing-device.patch161
-rw-r--r--patches.drivers/scsi-hisi_sas-relocate-smp-sg-map.patch309
-rw-r--r--patches.drivers/scsi-hisi_sas-remove-depends-on-has_dma-in-case-of-platform-dependency.patch42
-rw-r--r--patches.drivers/scsi-hisi_sas-remove-redundant-handling-to-event95-for-v3.patch49
-rw-r--r--patches.drivers/scsi-hisi_sas-remove-some-unneeded-structure-members.patch104
-rw-r--r--patches.drivers/scsi-hisi_sas-remove-unused-variable-hisi_sas_devices-running_req.patch89
-rw-r--r--patches.drivers/scsi-hisi_sas-reset-disks-when-discovered.patch111
-rw-r--r--patches.drivers/scsi-hisi_sas-some-optimizations-of-host-controller-reset.patch77
-rw-r--r--patches.drivers/scsi-hisi_sas-stop-controller-timer-for-reset.patch33
-rw-r--r--patches.drivers/scsi-hisi_sas-support-the-property-of-signal-attenuation-for-v2-hw.patch93
-rw-r--r--patches.drivers/scsi-hisi_sas-terminate-stp-reject-quickly-for-v2-hw.patch127
-rw-r--r--patches.drivers/scsi-hisi_sas-try-wait-commands-before-before-controller-reset.patch148
-rw-r--r--patches.drivers/scsi-hisi_sas-update-phy-linkrate-after-a-controller-reset.patch181
-rw-r--r--patches.drivers/scsi-hisi_sas-update-ras-feature-for-later-revision-of-v3-hw.patch158
-rw-r--r--patches.drivers/scsi-hisi_sas-use-an-general-way-to-delay-phy-work.patch142
-rw-r--r--patches.drivers/scsi-hisi_sas-use-device-lock-to-protect-slot-alloc-free.patch246
-rw-r--r--patches.drivers/scsi-hisi_sas-use-dma_zalloc_coherent.patch38
-rw-r--r--patches.drivers/scsi-hisi_sas-workaround-a-v3-hw-hilink-bug.patch91
-rw-r--r--patches.drivers/scsi-lpfc-Add-Buffer-overflow-check-when-nvme_info-l.patch550
-rw-r--r--patches.drivers/scsi-lpfc-Correct-LCB-ACCept-payload.patch46
-rw-r--r--patches.drivers/scsi-lpfc-Fix-ELS-abort-on-SLI-3-adapters.patch89
-rw-r--r--patches.drivers/scsi-lpfc-Fix-NVME-Target-crash-in-defer-rcv-logic.patch61
-rw-r--r--patches.drivers/scsi-lpfc-Fix-abort-error-path-for-NVMET.patch94
-rw-r--r--patches.drivers/scsi-lpfc-Fix-driver-crash-when-re-registering-NVME-.patch109
-rw-r--r--patches.drivers/scsi-lpfc-Fix-driver-not-setting-dpp-bits-correctly-.patch54
-rw-r--r--patches.drivers/scsi-lpfc-Fix-list-corruption-on-the-completion-queu.patch143
-rw-r--r--patches.drivers/scsi-lpfc-Fix-panic-if-driver-unloaded-when-port-is-.patch50
-rw-r--r--patches.drivers/scsi-lpfc-Fix-sysfs-Speed-value-on-CNA-ports.patch52
-rw-r--r--patches.drivers/scsi-lpfc-Limit-tracking-of-tgt-queue-depth-in-fast-.patch325
-rw-r--r--patches.drivers/scsi-lpfc-Make-PBDE-optimizations-configurable.patch257
-rw-r--r--patches.drivers/scsi-lpfc-Remove-lpfc_enable_pbde-as-module-paramete.patch68
-rw-r--r--patches.drivers/scsi-lpfc-Revise-copyright-for-new-company-language.patch412
-rw-r--r--patches.drivers/scsi-lpfc-Support-duration-field-in-Link-Cable-Beaco.patch294
-rw-r--r--patches.drivers/scsi-lpfc-devloss-timeout-race-condition-caused-null.patch94
-rw-r--r--patches.drivers/scsi-lpfc-update-driver-version-to-12.0.0.5.patch34
-rw-r--r--patches.drivers/scsi-lpfc-update-driver-version-to-12.0.0.6.patch34
-rw-r--r--patches.drivers/scsi-smartpqi-add-in-new-supported-controllers.patch88
-rw-r--r--patches.drivers/scsi-smartpqi-add-inspur-advantech-ids.patch61
-rw-r--r--patches.drivers/scsi-smartpqi-bump-driver-version-to-1.1.4-130.patch38
-rw-r--r--patches.drivers/scsi-smartpqi-fix-critical-ARM-issue-reading-PQI-ind.patch224
-rw-r--r--patches.drivers/scsi-smartpqi-improve-error-checking-for-sync-reques.patch130
-rw-r--r--patches.drivers/scsi-smartpqi-improve-handling-for-sync-requests.patch125
-rw-r--r--patches.drivers/scsi-smartpqi-update-driver-version.patch40
-rw-r--r--patches.drivers/scsi-smartpqi-workaround-fw-bug-for-oq-deletion.patch100
-rw-r--r--patches.fixes/0001-fscache-Allow-cancelled-operations-to-be-enqueued.patch44
-rw-r--r--patches.fixes/0002-cachefiles-Fix-refcounting-bug-in-backing-file-read-.patch117
-rw-r--r--patches.fixes/0003-fscache-Fix-reference-overput-in-fscache_attach_obje.patch176
-rw-r--r--patches.fixes/0004-cachefiles-Fix-missing-clear-of-the-CACHEFILES_OBJEC.patch73
-rw-r--r--patches.fixes/0005-cachefiles-Wait-rather-than-BUG-ing-on-Unexpected-ob.patch36
-rw-r--r--patches.fixes/Force-log-to-disk-before-reading-the-AGF-during-a-fs.patch73
-rw-r--r--patches.fixes/afs-Fix-directory-permissions-check.patch69
-rw-r--r--patches.fixes/bdi-Move-cgroup-bdi_writeback-to-a-dedicated-low-con.patch110
-rw-r--r--patches.fixes/befs_lookup-use-d_splice_alias.patch55
-rw-r--r--patches.fixes/block-Fix-transfer-when-chunk-sectors-exceeds-max.patch42
-rw-r--r--patches.fixes/cdrom-do-not-call-check_disk_change-inside-cdrom_ope.patch167
-rw-r--r--patches.fixes/dax-check-for-queue_flag_dax-in-bdev_dax_supported.patch17
-rw-r--r--patches.fixes/delayacct-fix-crash-in-delayacct_blkio_end-after-del.patch83
-rw-r--r--patches.fixes/dm-prevent-dax-mounts-if-not-supported.patch69
-rw-r--r--patches.fixes/ext2-fix-a-block-leak.patch53
-rw-r--r--patches.fixes/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch45
-rw-r--r--patches.fixes/ext4-add-more-inode-number-paranoia-checks.patch77
-rw-r--r--patches.fixes/ext4-add-more-mount-time-checks-of-the-superblock.patch103
-rw-r--r--patches.fixes/ext4-always-check-block-group-bounds-in-ext4_init_bl.patch59
-rw-r--r--patches.fixes/ext4-always-verify-the-magic-number-in-xattr-blocks.patch53
-rw-r--r--patches.fixes/ext4-avoid-running-out-of-journal-credits-when-appen.patch124
-rw-r--r--patches.fixes/ext4-bubble-errors-from-ext4_find_inline_data_nolock.patch70
-rw-r--r--patches.fixes/ext4-check-superblock-mapped-prior-to-committing.patch59
-rw-r--r--patches.fixes/ext4-clear-i_data-in-ext4_inode_info-when-removing-i.patch53
-rw-r--r--patches.fixes/ext4-do-not-update-s_last_mounted-of-a-frozen-fs.patch82
-rw-r--r--patches.fixes/ext4-factor-out-helper-ext4_sample_last_mounted.patch119
-rw-r--r--patches.fixes/ext4-fix-check-to-prevent-initializing-reserved-inod.patch70
-rw-r--r--patches.fixes/ext4-fix-fencepost-error-in-check-for-inode-count-ov.patch42
-rw-r--r--patches.fixes/ext4-include-the-illegal-physical-block-in-the-bad-m.patch36
-rw-r--r--patches.fixes/ext4-make-sure-bitmaps-and-the-inode-table-don-t-ove.patch79
-rw-r--r--patches.fixes/ext4-never-move-the-system.data-xattr-out-of-the-ino.patch39
-rw-r--r--patches.fixes/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch141
-rw-r--r--patches.fixes/ext4-report-delalloc-reserve-as-non-free-in-statfs-f.patch39
-rw-r--r--patches.fixes/ext4-update-mtime-in-ext4_punch_hole-even-if-no-bloc.patch80
-rw-r--r--patches.fixes/ext4-verify-the-depth-of-extent-tree-in-ext4_find_ex.patch57
-rw-r--r--patches.fixes/f2fs-call-unlock_new_inode-before-d_instantiate.patch77
-rw-r--r--patches.fixes/fix-io_destroy-aio_complete-race.patch46
-rw-r--r--patches.fixes/fs-allow-per-device-dax-status-checking-for-filesystems.patch223
-rw-r--r--patches.fixes/fs-clear-writeback-errors-in-inode_init_always.patch45
-rw-r--r--patches.fixes/fs-don-t-scan-the-inode-cache-before-SB_BORN-is-set.patch99
-rw-r--r--patches.fixes/fscache-Fix-hanging-wait-on-page-discarded-by-writeb.patch75
-rw-r--r--patches.fixes/isofs-fix-potential-memory-leak-in-mount-option-pars.patch40
-rw-r--r--patches.fixes/jbd2-don-t-mark-block-as-modified-if-the-handle-is-o.patch63
-rw-r--r--patches.fixes/libnvdimm-dimm-fix-dpa-reservation-vs-uninitialized-.patch53
-rw-r--r--patches.fixes/linvdimm-pmem-Preserve-read-only-setting-for-pmem-de.patch77
-rw-r--r--patches.fixes/mm-fix-__gup_device_huge-vs-unmap.patch101
-rw-r--r--patches.fixes/nvme-fabrics-Ignore-nr_io_queues-option-for-discover.patch47
-rw-r--r--patches.fixes/nvme-fixup-crash-on-failed-discovery.patch34
-rw-r--r--patches.fixes/nvme-use-hw-qid-in-trace-events.patch214
-rw-r--r--patches.fixes/nvme.h-fixup-ANA-group-descriptor-format.patch35
-rw-r--r--patches.fixes/orangefs-report-attributes_mask-and-attributes-for-s.patch45
-rw-r--r--patches.fixes/orangefs-set-i_size-on-new-symlink.patch63
-rw-r--r--patches.fixes/pmem-only-set-queue_flag_dax-for-fsdax-mode.patch37
-rw-r--r--patches.fixes/reiserfs-fix-buffer-overflow-with-long-warning-messa.patch256
-rw-r--r--patches.fixes/udf-Detect-incorrect-directory-size.patch40
-rw-r--r--patches.fixes/udf-Provide-saner-default-for-invalid-uid-gid.patch47
-rw-r--r--patches.fixes/vfs-add-the-sb_start_intwrite_trylock-helper.patch38
-rw-r--r--patches.fixes/xfs-catch-inode-allocation-state-mismatch-corruption.patch183
-rw-r--r--patches.fixes/xfs-prevent-creating-negative-sized-file-via-INSERT_.patch73
-rw-r--r--patches.kabi/kabi-fixup-bdev_dax_supported.patch141
-rw-r--r--patches.suse/0201-dax-dm-allow-device-mapper-to-operate-without-dax-su.patch291
-rw-r--r--patches.suse/branch-check-fix-long-int-truncation-when-profiling-.patch45
-rw-r--r--patches.suse/dm-add-writecache-target.patch2447
-rw-r--r--patches.suse/dm-writecache-support-optional-offset-for-start-of-d.patch159
-rw-r--r--patches.suse/dm-writecache-use-2-factor-allocator-arguments.patch60
-rw-r--r--patches.suse/ompiler.h-enable-builtin-overflow-checkers-and-add-.patch324
-rw-r--r--patches.suse/overflow.h-Add-allocation-size-calculation-helpers.patch148
-rw-r--r--patches.suse/sched-fair-Consider-RT-IRQ-pressure-in-capacity_spare_wake.patch126
-rw-r--r--patches.suse/sched-fair-Fix-find_idlest_group-when-local-group-is-not-allowed.patch50
-rw-r--r--patches.suse/sched-fair-Fix-usage-of-find_idlest_group-when-no-groups-are-allowed.patch61
-rw-r--r--patches.suse/sched-fair-Fix-usage-of-find_idlest_group-when-the-local-group-is-idlest.patch49
-rw-r--r--patches.suse/sched-fair-Move-select_task_rq_fair-slow-path-into-its-own-function.patch147
-rw-r--r--patches.suse/sched-fair-Remove-impossible-condition-from-find_idlest_group_cpu.patch65
-rw-r--r--patches.suse/sched-fair-Remove-unnecessary-comparison-with-1.patch47
-rw-r--r--patches.suse/sched-fair-Restructure-wake_affine-to-return-a-CPU-id.patch2
-rw-r--r--patches.suse/sched-fair-Spare-idle-load-balancing-on-nohz_full-CPUs.patch46
-rw-r--r--patches.suse/sched-fair-Use-a-recently-used-CPU-as-an-idle-candidate-and-the-basis-for-SIS.patch6
-rw-r--r--patches.suse/sched-fair-Use-unsigned-long-for-utilization-consistently.patch86
-rw-r--r--patches.suse/xfs-unsupported-features.patch21
-rwxr-xr-xscripts/git_sort/git_sort.py5
-rw-r--r--series.conf196
-rw-r--r--supported.conf2
212 files changed, 25410 insertions, 343 deletions
diff --git a/blacklist.conf b/blacklist.conf
index eeae2c4637..17e8fa77cc 100644
--- a/blacklist.conf
+++ b/blacklist.conf
@@ -433,3 +433,13 @@ be0f272bfc83797f70d44faca86954df62e2bbc0 # arm64: no support for ftrace far bran
acfb3b883f6d6a4b5d27ad7fdded11f6a09ae6dd # arm64: KVM: already in with mainline commit id 20e8175d246e
bb48711800e6d7aedbf4dfd3367e0ab1270a6bea # arm64: we don't support kyro
6f6060a5c9cc76fdbc22748264e6aa3779ec2427 # apm is not enabled in config
+001ab5a67ee5d191c64aebf4b4ef8c7a0dcfd2bc # AFS not supported & requires d2ddc776a4581 which is huge rewrite
+a86b06d1ccd218a6a50d6a3a88fbd2abcd0eaa94 # AFS not supported & server logic got changed
+a9af3fdcc4258af406879eca63d82e9d6baa892e # Just a cleanup
+428edade4e6c70e5b51fcd4188d944fbb744d84c # AFS not supported & server logic got changed
+80660f20252d6f76c9f203874ad7c7a4a8508cf8 # Just a cleanup
+92183a42898dc400b89da35685d1814ac6acd3d8 # Just a cleanup
+174d1232ebc84fcde8f5889d1171c9c7e74a10a7 # GFS2 is unsupported & this is only a performance fix
+98c4f78dcdd8cec112d1cbc5e9a792ee6e5ab7a6 # Bug introduced by 43518812d2 which we don't have in SLE15
+0d9366d67bcf066b028e57d09c9a86ce879bcc28 # Cosmetic bug fix
+117166efb1ee8f13c38f9e96b258f16d4923f888 # bug requires e50e5129f384 "ext4: xattr-in-inode support"
diff --git a/config/arm64/default b/config/arm64/default
index 0c89d82c6e..40911ccfe7 100644
--- a/config/arm64/default
+++ b/config/arm64/default
@@ -2239,6 +2239,7 @@ CONFIG_DM_SNAPSHOT=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_DM_CACHE=m
CONFIG_DM_CACHE_SMQ=m
+CONFIG_DM_WRITECACHE=m
CONFIG_DM_ERA=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
@@ -3594,6 +3595,7 @@ CONFIG_PINCTRL_INTEL=m
CONFIG_PINCTRL_CANNONLAKE=m
# CONFIG_PINCTRL_DENVERTON is not set
# CONFIG_PINCTRL_GEMINILAKE is not set
+# CONFIG_PINCTRL_LEWISBURG is not set
# CONFIG_PINCTRL_SUNRISEPOINT is not set
CONFIG_PINCTRL_ARMADA_37XX=y
CONFIG_PINCTRL_MSM=y
diff --git a/config/ppc64le/default b/config/ppc64le/default
index cfdc2dbe9e..c4baa63ea2 100644
--- a/config/ppc64le/default
+++ b/config/ppc64le/default
@@ -2028,6 +2028,7 @@ CONFIG_DM_SNAPSHOT=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_DM_CACHE=m
CONFIG_DM_CACHE_SMQ=m
+CONFIG_DM_WRITECACHE=m
CONFIG_DM_ERA=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
@@ -4347,7 +4348,6 @@ CONFIG_REMOTEPROC=m
#
# CONFIG_SUNXI_SRAM is not set
# CONFIG_SOC_TI is not set
-# CONFIG_SOC_ZTE is not set
CONFIG_PM_DEVFREQ=y
#
diff --git a/config/ppc64le/vanilla b/config/ppc64le/vanilla
index fdac697475..74659e4db5 100644
--- a/config/ppc64le/vanilla
+++ b/config/ppc64le/vanilla
@@ -9,6 +9,7 @@ CONFIG_PPC_ICSWX=y
CONFIG_PPC_ICSWX_PID=y
# CONFIG_PPC_ICSWX_USE_SIGILL is not set
CONFIG_PPC_STD_MMU_64=y
+# CONFIG_SOC_ZTE is not set
# CONFIG_SYSTEM_DATA_VERIFICATION is not set
CONFIG_TREE_RCU_TRACE=y
CONFIG_MODULES=y
diff --git a/config/s390x/default b/config/s390x/default
index bc29eb9629..78d6c9715d 100644
--- a/config/s390x/default
+++ b/config/s390x/default
@@ -1573,6 +1573,7 @@ CONFIG_DM_SNAPSHOT=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_DM_CACHE=m
CONFIG_DM_CACHE_SMQ=m
+CONFIG_DM_WRITECACHE=m
CONFIG_DM_ERA=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
@@ -2192,7 +2193,6 @@ CONFIG_S390_IOMMU=y
#
# CONFIG_SUNXI_SRAM is not set
# CONFIG_SOC_TI is not set
-# CONFIG_SOC_ZTE is not set
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
diff --git a/config/s390x/vanilla b/config/s390x/vanilla
index 73937e1199..5538344903 100644
--- a/config/s390x/vanilla
+++ b/config/s390x/vanilla
@@ -5,6 +5,7 @@ CONFIG_CISS_SCSI_TAPE=y
# CONFIG_DP83867_PHY is not set
CONFIG_LOCALVERSION="-vanilla"
# CONFIG_MODULE_SIG is not set
+# CONFIG_SOC_ZTE is not set
# CONFIG_SYSTEM_DATA_VERIFICATION is not set
CONFIG_TREE_RCU_TRACE=y
CONFIG_MODULES=y
diff --git a/config/s390x/zfcpdump b/config/s390x/zfcpdump
index f195b89f07..98c101bb32 100644
--- a/config/s390x/zfcpdump
+++ b/config/s390x/zfcpdump
@@ -680,6 +680,7 @@ CONFIG_BLK_DEV_DM=y
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_THIN_PROVISIONING is not set
# CONFIG_DM_CACHE is not set
+CONFIG_DM_WRITECACHE=y
# CONFIG_DM_ERA is not set
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_RAID is not set
@@ -874,7 +875,6 @@ CONFIG_VIRTIO=y
#
# CONFIG_SUNXI_SRAM is not set
# CONFIG_SOC_TI is not set
-# CONFIG_SOC_ZTE is not set
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
diff --git a/config/x86_64/default b/config/x86_64/default
index c92addb21a..1a21f41c0a 100644
--- a/config/x86_64/default
+++ b/config/x86_64/default
@@ -2395,6 +2395,7 @@ CONFIG_DM_SNAPSHOT=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_DM_CACHE=m
CONFIG_DM_CACHE_SMQ=m
+CONFIG_DM_WRITECACHE=m
CONFIG_DM_ERA=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
@@ -3684,6 +3685,7 @@ CONFIG_PINCTRL_BROXTON=m
CONFIG_PINCTRL_CANNONLAKE=m
CONFIG_PINCTRL_DENVERTON=m
CONFIG_PINCTRL_GEMINILAKE=m
+CONFIG_PINCTRL_LEWISBURG=m
CONFIG_PINCTRL_SUNRISEPOINT=m
CONFIG_GPIOLIB=y
CONFIG_GPIO_ACPI=y
@@ -6173,7 +6175,6 @@ CONFIG_REMOTEPROC=m
#
# CONFIG_SUNXI_SRAM is not set
# CONFIG_SOC_TI is not set
-# CONFIG_SOC_ZTE is not set
CONFIG_PM_DEVFREQ=y
#
diff --git a/config/x86_64/vanilla b/config/x86_64/vanilla
index f6224858f5..bcffbdcb58 100644
--- a/config/x86_64/vanilla
+++ b/config/x86_64/vanilla
@@ -10,6 +10,7 @@ CONFIG_INTEL_RDT_A=y
# CONFIG_KEXEC_VERIFY_SIG is not set
CONFIG_LOCALVERSION="-vanilla"
# CONFIG_MODULE_SIG is not set
+# CONFIG_SOC_ZTE is not set
# CONFIG_SYSTEM_DATA_VERIFICATION is not set
CONFIG_TREE_RCU_TRACE=y
CONFIG_UCSI=m
diff --git a/kabi/severities b/kabi/severities
index 1719c7f385..c48ba2cbf6 100644
--- a/kabi/severities
+++ b/kabi/severities
@@ -36,6 +36,7 @@ drivers/infiniband/hw/qede/* PASS
drivers/scsi/qedf/* PASS
drivers/scsi/qedi/* PASS
include/linux/qed/* PASS
+drivers/scsi/hisi_sas/* PASS
# only inter-module local symbols
drivers/nvdimm/btt.h PASS
diff --git a/patches.arch/KVM-PPC-Check-if-IOMMU-page-is-contained-in-the-pinn.patch b/patches.arch/KVM-PPC-Check-if-IOMMU-page-is-contained-in-the-pinn.patch
index 65d3258cf7..3e5422d07b 100644
--- a/patches.arch/KVM-PPC-Check-if-IOMMU-page-is-contained-in-the-pinn.patch
+++ b/patches.arch/KVM-PPC-Check-if-IOMMU-page-is-contained-in-the-pinn.patch
@@ -4,7 +4,7 @@ Date: Tue, 24 Jul 2018 15:32:47 +1000
Subject: [PATCH] KVM: PPC: Check if IOMMU page is contained in the pinned
physical page
-References: bsc#1077761, git-fixes
+References: bsc#1077761, git-fixes, bsc#1103948, bsc#1103949
Patch-mainline: v4.18-rc6
Git-commit: 76fa4975f3ed12d15762bc979ca44078598ed8ee
diff --git a/patches.drivers/RDMA-qedr-Fix-NULL-pointer-dereference-when-running-.patch b/patches.drivers/RDMA-qedr-Fix-NULL-pointer-dereference-when-running-.patch
new file mode 100644
index 0000000000..22f9087887
--- /dev/null
+++ b/patches.drivers/RDMA-qedr-Fix-NULL-pointer-dereference-when-running-.patch
@@ -0,0 +1,39 @@
+From: "Kalderon, Michal" <Michal.Kalderon@cavium.com>
+Date: Mon, 11 Jun 2018 10:20:20 +0300
+Subject: RDMA/qedr: Fix NULL pointer dereference when running over iWARP
+ without RDMA-CM
+Patch-mainline: v4.18-rc2
+Git-commit: 425cf5c1350a98b81f3ddda160b99c3be613a213
+References: bsc#1086314 FATE#324886
+
+Some RoCE specific code in qedr_modify_qp was run over an iWARP device
+when running perftest benchmarks without the -R option.
+
+The commit 3e44e0ee0893 ("IB/providers: Avoid null netdev check for RoCE")
+exposed this. Dropping the check for NULL pointer on ndev in
+qedr_modify_qp lead to a null pointer dereference when running over
+iWARP. Before the code would identify ndev as being NULL and return an
+error.
+
+Fixes: 3e44e0ee0893 ("IB/providers: Avoid null netdev check for RoCE")
+Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
+Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
+Reviewed-by: Parav Pandit <parav@mellanox.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/infiniband/hw/qedr/verbs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -1983,6 +1983,9 @@ int qedr_modify_qp(struct ib_qp *ibqp, s
+ }
+
+ if (attr_mask & (IB_QP_AV | IB_QP_PATH_MTU)) {
++ if (rdma_protocol_iwarp(&dev->ibdev, 1))
++ return -EINVAL;
++
+ if (attr_mask & IB_QP_PATH_MTU) {
+ if (attr->path_mtu < IB_MTU_256 ||
+ attr->path_mtu > IB_MTU_4096) {
diff --git a/patches.drivers/RDMA-qedr-fix-spelling-mistake-adrresses-addresses.patch b/patches.drivers/RDMA-qedr-fix-spelling-mistake-adrresses-addresses.patch
new file mode 100644
index 0000000000..ac1f7f8cc5
--- /dev/null
+++ b/patches.drivers/RDMA-qedr-fix-spelling-mistake-adrresses-addresses.patch
@@ -0,0 +1,27 @@
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 30 May 2018 10:40:29 +0100
+Subject: RDMA/qedr: fix spelling mistake: "adrresses" -> "addresses"
+Patch-mainline: v4.18-rc1
+Git-commit: 367d2f0787e8363f30cbac4d5270a772b69828c1
+References: bsc#1086314 FATE#324886
+
+Trivial fix to spelling mistake in DP_ERR error message
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/infiniband/hw/qedr/verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -435,7 +435,7 @@ int qedr_mmap(struct ib_ucontext *contex
+
+ if ((vma->vm_start & (PAGE_SIZE - 1)) || (len & (PAGE_SIZE - 1))) {
+ DP_ERR(dev,
+- "failed mmap, adrresses must be page aligned: start=0x%pK, end=0x%pK\n",
++ "failed mmap, addresses must be page aligned: start=0x%pK, end=0x%pK\n",
+ (void *)vma->vm_start, (void *)vma->vm_end);
+ return -EINVAL;
+ }
diff --git a/patches.drivers/RDMA-qedr-fix-spelling-mistake-failes-fails.patch b/patches.drivers/RDMA-qedr-fix-spelling-mistake-failes-fails.patch
new file mode 100644
index 0000000000..67de3e240c
--- /dev/null
+++ b/patches.drivers/RDMA-qedr-fix-spelling-mistake-failes-fails.patch
@@ -0,0 +1,27 @@
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 1 May 2018 09:25:49 +0100
+Subject: RDMA/qedr: fix spelling mistake: "failes" -> "fails"
+Patch-mainline: v4.18-rc1
+Git-commit: ffab8c89ba59c4e01f9c277f1baaad12bd5a3c0c
+References: bsc#1086314 FATE#324886
+
+Trivial fix to spelling mistake in DP_ERR error message
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/infiniband/hw/qedr/verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -2603,7 +2603,7 @@ static int qedr_set_page(struct ib_mr *i
+ u32 pbes_in_page;
+
+ if (unlikely(mr->npages == mr->info.pbl_info.num_pbes)) {
+- DP_ERR(mr->dev, "qedr_set_page failes when %d\n", mr->npages);
++ DP_ERR(mr->dev, "qedr_set_page fails when %d\n", mr->npages);
+ return -ENOMEM;
+ }
+
diff --git a/patches.drivers/clk-at91-fix-clk-generated-compilation b/patches.drivers/clk-at91-fix-clk-generated-compilation
new file mode 100644
index 0000000000..3adcf6b42e
--- /dev/null
+++ b/patches.drivers/clk-at91-fix-clk-generated-compilation
@@ -0,0 +1,33 @@
+From 4a5f06a01cfd1f7a9141bdb760bf5b68cca7f224 Mon Sep 17 00:00:00 2001
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Mon, 5 Jun 2017 00:02:57 +0200
+Subject: [PATCH] clk: at91: fix clk-generated compilation
+Git-commit: 4a5f06a01cfd1f7a9141bdb760bf5b68cca7f224
+Patch-mainline: v4.13-rc1
+References: bsc#1051510
+
+Fix missing }
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/clk/at91/clk-generated.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
+index 70474bd97a10..07c8f701e51c 100644
+--- a/drivers/clk/at91/clk-generated.c
++++ b/drivers/clk/at91/clk-generated.c
+@@ -266,6 +266,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
+ if (ret) {
+ kfree(gck);
+ hw = ERR_PTR(ret);
++ }
+
+ return hw;
+ }
+--
+2.18.0
+
diff --git a/patches.drivers/ibmvnic-Remove-code-to-request-error-information.patch b/patches.drivers/ibmvnic-Remove-code-to-request-error-information.patch
new file mode 100644
index 0000000000..5d19a52db7
--- /dev/null
+++ b/patches.drivers/ibmvnic-Remove-code-to-request-error-information.patch
@@ -0,0 +1,292 @@
+From 79dabbb7161f43ed29ca888a2488f59e47171aee Mon Sep 17 00:00:00 2001
+From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Date: Mon, 6 Aug 2018 21:39:58 -0500
+Subject: [PATCH] ibmvnic: Remove code to request error information
+
+References: bsc#1104174
+Patch-mainline: queued
+Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: 79dabbb7161f43ed29ca888a2488f59e47171aee
+
+When backing device firmware reports an error, it provides an
+error ID, which is meant to be queried for more detailed error
+information. Currently, however, an error ID is not provided by
+the Virtual I/O server and there are not any plans to do so. For
+now, it is always unfilled or zero, so request_error_information
+will never be called. Remove it.
+
+Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Michal Suchanek <msuchanek@suse.de>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 144 +------------------------------------
+ drivers/net/ethernet/ibm/ibmvnic.h | 33 ---------
+ 2 files changed, 1 insertion(+), 176 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index ffe7acbeaa22..109e4a58efad 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -718,23 +718,6 @@ static int init_tx_pools(struct net_device *netdev)
+ return 0;
+ }
+
+-static void release_error_buffers(struct ibmvnic_adapter *adapter)
+-{
+- struct device *dev = &adapter->vdev->dev;
+- struct ibmvnic_error_buff *error_buff, *tmp;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&adapter->error_list_lock, flags);
+- list_for_each_entry_safe(error_buff, tmp, &adapter->errors, list) {
+- list_del(&error_buff->list);
+- dma_unmap_single(dev, error_buff->dma, error_buff->len,
+- DMA_FROM_DEVICE);
+- kfree(error_buff->buff);
+- kfree(error_buff);
+- }
+- spin_unlock_irqrestore(&adapter->error_list_lock, flags);
+-}
+-
+ static void ibmvnic_napi_enable(struct ibmvnic_adapter *adapter)
+ {
+ int i;
+@@ -896,7 +879,6 @@ static void release_resources(struct ibmvnic_adapter *adapter)
+ release_tx_pools(adapter);
+ release_rx_pools(adapter);
+
+- release_error_buffers(adapter);
+ release_napi(adapter);
+ release_login_rsp_buffer(adapter);
+ }
+@@ -3843,133 +3825,16 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
+ ibmvnic_send_crq(adapter, &crq);
+ }
+
+-static void handle_error_info_rsp(union ibmvnic_crq *crq,
+- struct ibmvnic_adapter *adapter)
+-{
+- struct device *dev = &adapter->vdev->dev;
+- struct ibmvnic_error_buff *error_buff, *tmp;
+- unsigned long flags;
+- bool found = false;
+- int i;
+-
+- if (!crq->request_error_rsp.rc.code) {
+- dev_info(dev, "Request Error Rsp returned with rc=%x\n",
+- crq->request_error_rsp.rc.code);
+- return;
+- }
+-
+- spin_lock_irqsave(&adapter->error_list_lock, flags);
+- list_for_each_entry_safe(error_buff, tmp, &adapter->errors, list)
+- if (error_buff->error_id == crq->request_error_rsp.error_id) {
+- found = true;
+- list_del(&error_buff->list);
+- break;
+- }
+- spin_unlock_irqrestore(&adapter->error_list_lock, flags);
+-
+- if (!found) {
+- dev_err(dev, "Couldn't find error id %x\n",
+- be32_to_cpu(crq->request_error_rsp.error_id));
+- return;
+- }
+-
+- dev_err(dev, "Detailed info for error id %x:",
+- be32_to_cpu(crq->request_error_rsp.error_id));
+-
+- for (i = 0; i < error_buff->len; i++) {
+- pr_cont("%02x", (int)error_buff->buff[i]);
+- if (i % 8 == 7)
+- pr_cont(" ");
+- }
+- pr_cont("\n");
+-
+- dma_unmap_single(dev, error_buff->dma, error_buff->len,
+- DMA_FROM_DEVICE);
+- kfree(error_buff->buff);
+- kfree(error_buff);
+-}
+-
+-static void request_error_information(struct ibmvnic_adapter *adapter,
+- union ibmvnic_crq *err_crq)
+-{
+- struct device *dev = &adapter->vdev->dev;
+- struct net_device *netdev = adapter->netdev;
+- struct ibmvnic_error_buff *error_buff;
+- unsigned long timeout = msecs_to_jiffies(30000);
+- union ibmvnic_crq crq;
+- unsigned long flags;
+- int rc, detail_len;
+-
+- error_buff = kmalloc(sizeof(*error_buff), GFP_ATOMIC);
+- if (!error_buff)
+- return;
+-
+- detail_len = be32_to_cpu(err_crq->error_indication.detail_error_sz);
+- error_buff->buff = kmalloc(detail_len, GFP_ATOMIC);
+- if (!error_buff->buff) {
+- kfree(error_buff);
+- return;
+- }
+-
+- error_buff->dma = dma_map_single(dev, error_buff->buff, detail_len,
+- DMA_FROM_DEVICE);
+- if (dma_mapping_error(dev, error_buff->dma)) {
+- netdev_err(netdev, "Couldn't map error buffer\n");
+- kfree(error_buff->buff);
+- kfree(error_buff);
+- return;
+- }
+-
+- error_buff->len = detail_len;
+- error_buff->error_id = err_crq->error_indication.error_id;
+-
+- spin_lock_irqsave(&adapter->error_list_lock, flags);
+- list_add_tail(&error_buff->list, &adapter->errors);
+- spin_unlock_irqrestore(&adapter->error_list_lock, flags);
+-
+- memset(&crq, 0, sizeof(crq));
+- crq.request_error_info.first = IBMVNIC_CRQ_CMD;
+- crq.request_error_info.cmd = REQUEST_ERROR_INFO;
+- crq.request_error_info.ioba = cpu_to_be32(error_buff->dma);
+- crq.request_error_info.len = cpu_to_be32(detail_len);
+- crq.request_error_info.error_id = err_crq->error_indication.error_id;
+-
+- rc = ibmvnic_send_crq(adapter, &crq);
+- if (rc) {
+- netdev_err(netdev, "failed to request error information\n");
+- goto err_info_fail;
+- }
+-
+- if (!wait_for_completion_timeout(&adapter->init_done, timeout)) {
+- netdev_err(netdev, "timeout waiting for error information\n");
+- goto err_info_fail;
+- }
+-
+- return;
+-
+-err_info_fail:
+- spin_lock_irqsave(&adapter->error_list_lock, flags);
+- list_del(&error_buff->list);
+- spin_unlock_irqrestore(&adapter->error_list_lock, flags);
+-
+- kfree(error_buff->buff);
+- kfree(error_buff);
+-}
+-
+ static void handle_error_indication(union ibmvnic_crq *crq,
+ struct ibmvnic_adapter *adapter)
+ {
+ struct device *dev = &adapter->vdev->dev;
+
+- dev_err(dev, "Firmware reports %serror id %x, cause %d\n",
++ dev_err(dev, "Firmware reports %serror, cause %d\n",
+ crq->error_indication.flags
+ & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
+- be32_to_cpu(crq->error_indication.error_id),
+ be16_to_cpu(crq->error_indication.error_cause));
+
+- if (be32_to_cpu(crq->error_indication.error_id))
+- request_error_information(adapter, crq);
+-
+ if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
+ ibmvnic_reset(adapter, VNIC_RESET_FATAL);
+ else
+@@ -4468,10 +4333,6 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
+ netdev_dbg(netdev, "Got Error Indication\n");
+ handle_error_indication(crq, adapter);
+ break;
+- case REQUEST_ERROR_RSP:
+- netdev_dbg(netdev, "Got Error Detail Response\n");
+- handle_error_info_rsp(crq, adapter);
+- break;
+ case REQUEST_STATISTICS_RSP:
+ netdev_dbg(netdev, "Got Statistics Response\n");
+ complete(&adapter->stats_done);
+@@ -4830,9 +4691,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+
+ spin_lock_init(&adapter->stats_lock);
+
+- INIT_LIST_HEAD(&adapter->errors);
+- spin_lock_init(&adapter->error_list_lock);
+-
+ INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset);
+ INIT_LIST_HEAD(&adapter->rwi_list);
+ mutex_init(&adapter->reset_lock);
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
+index f9fb780102ac..f06eec145ca6 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.h
++++ b/drivers/net/ethernet/ibm/ibmvnic.h
+@@ -512,24 +512,6 @@ struct ibmvnic_error_indication {
+ u8 reserved2[2];
+ } __packed __aligned(8);
+
+-struct ibmvnic_request_error_info {
+- u8 first;
+- u8 cmd;
+- u8 reserved[2];
+- __be32 ioba;
+- __be32 len;
+- __be32 error_id;
+-} __packed __aligned(8);
+-
+-struct ibmvnic_request_error_rsp {
+- u8 first;
+- u8 cmd;
+- u8 reserved[2];
+- __be32 error_id;
+- __be32 len;
+- struct ibmvnic_rc rc;
+-} __packed __aligned(8);
+-
+ struct ibmvnic_link_state_indication {
+ u8 first;
+ u8 cmd;
+@@ -709,8 +691,6 @@ union ibmvnic_crq {
+ struct ibmvnic_request_debug_stats request_debug_stats;
+ struct ibmvnic_request_debug_stats request_debug_stats_rsp;
+ struct ibmvnic_error_indication error_indication;
+- struct ibmvnic_request_error_info request_error_info;
+- struct ibmvnic_request_error_rsp request_error_rsp;
+ struct ibmvnic_link_state_indication link_state_indication;
+ struct ibmvnic_change_mac_addr change_mac_addr;
+ struct ibmvnic_change_mac_addr change_mac_addr_rsp;
+@@ -809,8 +789,6 @@ enum ibmvnic_commands {
+ SET_PHYS_PARMS = 0x07,
+ SET_PHYS_PARMS_RSP = 0x87,
+ ERROR_INDICATION = 0x08,
+- REQUEST_ERROR_INFO = 0x09,
+- REQUEST_ERROR_RSP = 0x89,
+ LOGICAL_LINK_STATE = 0x0C,
+ LOGICAL_LINK_STATE_RSP = 0x8C,
+ REQUEST_STATISTICS = 0x0D,
+@@ -945,14 +923,6 @@ struct ibmvnic_rx_pool {
+ struct ibmvnic_long_term_buff long_term_buff;
+ };
+
+-struct ibmvnic_error_buff {
+- char *buff;
+- dma_addr_t dma;
+- int len;
+- struct list_head list;
+- __be32 error_id;
+-};
+-
+ struct ibmvnic_vpd {
+ unsigned char *buff;
+ dma_addr_t dma_addr;
+@@ -1047,9 +1017,6 @@ struct ibmvnic_adapter {
+ struct completion init_done;
+ int init_done_rc;
+
+- struct list_head errors;
+- spinlock_t error_list_lock;
+-
+ struct completion fw_done;
+ int fw_done_rc;
+
+--
+2.13.7
+
diff --git a/patches.drivers/ibmvnic-Revise-RX-TX-queue-error-messages.patch b/patches.drivers/ibmvnic-Revise-RX-TX-queue-error-messages.patch
new file mode 100644
index 0000000000..fff3f0c3af
--- /dev/null
+++ b/patches.drivers/ibmvnic-Revise-RX-TX-queue-error-messages.patch
@@ -0,0 +1,107 @@
+From 2d14d3795294d42aacc278948984a480569bcc23 Mon Sep 17 00:00:00 2001
+From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Date: Fri, 13 Jul 2018 12:03:32 -0500
+Subject: [PATCH] ibmvnic: Revise RX/TX queue error messages
+
+References: bsc#1101331
+Patch-mainline: v4.18-rc6
+Git-commit: 2d14d3795294d42aacc278948984a480569bcc23
+
+During a device failover, there may be latency between the loss
+of the current backing device and a notification from firmware that
+a failover has occurred. This latency can result in a large amount of
+error printouts as firmware returns outgoing traffic with a generic
+error code. These are not necessarily errors in this case as the
+firmware is busy swapping in a new backing adapter and is not ready
+to send packets yet. This patch reclassifies those error codes as
+warnings with an explanation that a failover may be pending. All
+other return codes will be considered errors.
+
+Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Michal Suchanek <msuchanek@suse.de>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 39 ++++++++++++++++++++++++++------------
+ 1 file changed, 27 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index d0e196bff081..c50963680f30 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -329,7 +329,8 @@ static void replenish_rx_pool(struct ibmvnic_adapter *adapter,
+ return;
+
+ failure:
+- dev_info(dev, "replenish pools failure\n");
++ if (lpar_rc != H_PARAMETER && lpar_rc != H_CLOSED)
++ dev_err_ratelimited(dev, "rx: replenish packet buffer failed\n");
+ pool->free_map[pool->next_free] = index;
+ pool->rx_buff[index].skb = NULL;
+
+@@ -1617,7 +1618,8 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+ &tx_crq);
+ }
+ if (lpar_rc != H_SUCCESS) {
+- dev_err(dev, "tx failed with code %ld\n", lpar_rc);
++ if (lpar_rc != H_CLOSED && lpar_rc != H_PARAMETER)
++ dev_err_ratelimited(dev, "tx: send failed\n");
+ dev_kfree_skb_any(skb);
+ tx_buff->skb = NULL;
+
+@@ -3204,6 +3206,25 @@ static union ibmvnic_crq *ibmvnic_next_crq(struct ibmvnic_adapter *adapter)
+ return crq;
+ }
+
++static void print_subcrq_error(struct device *dev, int rc, const char *func)
++{
++ switch (rc) {
++ case H_PARAMETER:
++ dev_warn_ratelimited(dev,
++ "%s failed: Send request is malformed or adapter failover pending. (rc=%d)\n",
++ func, rc);
++ break;
++ case H_CLOSED:
++ dev_warn_ratelimited(dev,
++ "%s failed: Backing queue closed. Adapter is down or failover pending. (rc=%d)\n",
++ func, rc);
++ break;
++ default:
++ dev_err_ratelimited(dev, "%s failed: (rc=%d)\n", func, rc);
++ break;
++ }
++}
++
+ static int send_subcrq(struct ibmvnic_adapter *adapter, u64 remote_handle,
+ union sub_crq *sub_crq)
+ {
+@@ -3230,11 +3251,8 @@ static int send_subcrq(struct ibmvnic_adapter *adapter, u64 remote_handle,
+ cpu_to_be64(u64_crq[2]),
+ cpu_to_be64(u64_crq[3]));
+
+- if (rc) {
+- if (rc == H_CLOSED)
+- dev_warn(dev, "CRQ Queue closed\n");
+- dev_err(dev, "Send error (rc=%d)\n", rc);
+- }
++ if (rc)
++ print_subcrq_error(dev, rc, __func__);
+
+ return rc;
+ }
+@@ -3252,11 +3270,8 @@ static int send_subcrq_indirect(struct ibmvnic_adapter *adapter,
+ cpu_to_be64(remote_handle),
+ ioba, num_entries);
+
+- if (rc) {
+- if (rc == H_CLOSED)
+- dev_warn(dev, "CRQ Queue closed\n");
+- dev_err(dev, "Send (indirect) error (rc=%d)\n", rc);
+- }
++ if (rc)
++ print_subcrq_error(dev, rc, __func__);
+
+ return rc;
+ }
+--
+2.13.7
+
diff --git a/patches.drivers/ibmvnic-Update-firmware-error-reporting-with-cause-s.patch b/patches.drivers/ibmvnic-Update-firmware-error-reporting-with-cause-s.patch
new file mode 100644
index 0000000000..5bf44ade54
--- /dev/null
+++ b/patches.drivers/ibmvnic-Update-firmware-error-reporting-with-cause-s.patch
@@ -0,0 +1,74 @@
+From c9008d339bc40301a486ea62f36f106c4b2aad0e Mon Sep 17 00:00:00 2001
+From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Date: Mon, 6 Aug 2018 21:39:59 -0500
+Subject: [PATCH] ibmvnic: Update firmware error reporting with cause string
+
+References: bsc#1104174
+Patch-mainline: queued
+Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: c9008d339bc40301a486ea62f36f106c4b2aad0e
+
+Print a string instead of the error code. Since there is a
+possibility that the driver can recover, classify it as a
+warning instead of an error.
+
+Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Michal Suchanek <msuchanek@suse.de>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 34 ++++++++++++++++++++++++++++++----
+ 1 file changed, 30 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 109e4a58efad..dafdd4ade705 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -3825,15 +3825,41 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
+ ibmvnic_send_crq(adapter, &crq);
+ }
+
++static const char *ibmvnic_fw_err_cause(u16 cause)
++{
++ switch (cause) {
++ case ADAPTER_PROBLEM:
++ return "adapter problem";
++ case BUS_PROBLEM:
++ return "bus problem";
++ case FW_PROBLEM:
++ return "firmware problem";
++ case DD_PROBLEM:
++ return "device driver problem";
++ case EEH_RECOVERY:
++ return "EEH recovery";
++ case FW_UPDATED:
++ return "firmware updated";
++ case LOW_MEMORY:
++ return "low Memory";
++ default:
++ return "unknown";
++ }
++}
++
+ static void handle_error_indication(union ibmvnic_crq *crq,
+ struct ibmvnic_adapter *adapter)
+ {
+ struct device *dev = &adapter->vdev->dev;
++ u16 cause;
++
++ cause = be16_to_cpu(crq->error_indication.error_cause);
+
+- dev_err(dev, "Firmware reports %serror, cause %d\n",
+- crq->error_indication.flags
+- & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
+- be16_to_cpu(crq->error_indication.error_cause));
++ dev_warn_ratelimited(dev,
++ "Firmware reports %serror, cause: %s. Starting recovery...\n",
++ crq->error_indication.flags
++ & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
++ ibmvnic_fw_err_cause(cause));
+
+ if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
+ ibmvnic_reset(adapter, VNIC_RESET_FATAL);
+--
+2.13.7
+
diff --git a/patches.drivers/pinctrl-intel-Add-Intel-Lewisburg-GPIO-support.patch b/patches.drivers/pinctrl-intel-Add-Intel-Lewisburg-GPIO-support.patch
new file mode 100644
index 0000000000..d5d213a58f
--- /dev/null
+++ b/patches.drivers/pinctrl-intel-Add-Intel-Lewisburg-GPIO-support.patch
@@ -0,0 +1,404 @@
+From e480b745386e3911c45e5b281f3471c7aff8cc3b Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Fri, 18 Aug 2017 13:05:55 +0300
+Subject: [PATCH] pinctrl: intel: Add Intel Lewisburg GPIO support
+Git-commit: e480b745386e3911c45e5b281f3471c7aff8cc3b
+Patch-mainline: v4.14-rc1
+References: FATE#325120
+
+Intel Lewisburg has the same GPIO hardware than Intel Sunrisepoint-H
+except few differences in register offsets and pin lists. Because of
+this we add a separate pinctrl driver for Lewisburg.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/pinctrl/intel/Kconfig | 8 +
+ drivers/pinctrl/intel/Makefile | 1 +
+ drivers/pinctrl/intel/pinctrl-lewisburg.c | 343 ++++++++++++++++++++++
+ 3 files changed, 352 insertions(+)
+ create mode 100644 drivers/pinctrl/intel/pinctrl-lewisburg.c
+
+diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig
+index 9613c2a9e2b3..f30720a752f3 100644
+--- a/drivers/pinctrl/intel/Kconfig
++++ b/drivers/pinctrl/intel/Kconfig
+@@ -81,6 +81,14 @@ config PINCTRL_GEMINILAKE
+ This pinctrl driver provides an interface that allows configuring
+ of Intel Gemini Lake SoC pins and using them as GPIOs.
+
++config PINCTRL_LEWISBURG
++ tristate "Intel Lewisburg pinctrl and GPIO driver"
++ depends on ACPI
++ select PINCTRL_INTEL
++ help
++ This pinctrl driver provides an interface that allows configuring
++ of Intel Lewisburg pins and using them as GPIOs.
++
+ config PINCTRL_SUNRISEPOINT
+ tristate "Intel Sunrisepoint pinctrl and GPIO driver"
+ depends on ACPI
+diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile
+index d9b31f7e2b1b..c12874da5992 100644
+--- a/drivers/pinctrl/intel/Makefile
++++ b/drivers/pinctrl/intel/Makefile
+@@ -8,4 +8,5 @@ obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o
+ obj-$(CONFIG_PINCTRL_CANNONLAKE) += pinctrl-cannonlake.o
+ obj-$(CONFIG_PINCTRL_DENVERTON) += pinctrl-denverton.o
+ obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o
++obj-$(CONFIG_PINCTRL_LEWISBURG) += pinctrl-lewisburg.o
+ obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o
+diff --git a/drivers/pinctrl/intel/pinctrl-lewisburg.c b/drivers/pinctrl/intel/pinctrl-lewisburg.c
+new file mode 100644
+index 000000000000..14d56ea6cfdc
+--- /dev/null
++++ b/drivers/pinctrl/intel/pinctrl-lewisburg.c
+@@ -0,0 +1,343 @@
++/*
++ * Intel Lewisburg pinctrl/GPIO driver
++ *
++ * Copyright (C) 2017, Intel Corporation
++ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/acpi.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++#include <linux/pinctrl/pinctrl.h>
++
++#include "pinctrl-intel.h"
++
++#define LBG_PAD_OWN 0x020
++#define LBG_PADCFGLOCK 0x060
++#define LBG_HOSTSW_OWN 0x080
++#define LBG_GPI_IE 0x110
++
++#define LBG_COMMUNITY(b, s, e) \
++ { \
++ .barno = (b), \
++ .padown_offset = LBG_PAD_OWN, \
++ .padcfglock_offset = LBG_PADCFGLOCK, \
++ .hostown_offset = LBG_HOSTSW_OWN, \
++ .ie_offset = LBG_GPI_IE, \
++ .gpp_size = 24, \
++ .pin_base = (s), \
++ .npins = ((e) - (s) + 1), \
++ }
++
++static const struct pinctrl_pin_desc lbg_pins[] = {
++ /* GPP_A */
++ PINCTRL_PIN(0, "RCINB"),
++ PINCTRL_PIN(1, "LAD_0"),
++ PINCTRL_PIN(2, "LAD_1"),
++ PINCTRL_PIN(3, "LAD_2"),
++ PINCTRL_PIN(4, "LAD_3"),
++ PINCTRL_PIN(5, "LFRAMEB"),
++ PINCTRL_PIN(6, "SERIRQ"),
++ PINCTRL_PIN(7, "PIRQAB"),
++ PINCTRL_PIN(8, "CLKRUNB"),
++ PINCTRL_PIN(9, "CLKOUT_LPC_0"),
++ PINCTRL_PIN(10, "CLKOUT_LPC_1"),
++ PINCTRL_PIN(11, "PMEB"),
++ PINCTRL_PIN(12, "BM_BUSYB"),
++ PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"),
++ PINCTRL_PIN(14, "ESPI_RESETB"),
++ PINCTRL_PIN(15, "SUSACKB"),
++ PINCTRL_PIN(16, "CLKOUT_LPC_2"),
++ PINCTRL_PIN(17, "GPP_A_17"),
++ PINCTRL_PIN(18, "GPP_A_18"),
++ PINCTRL_PIN(19, "GPP_A_19"),
++ PINCTRL_PIN(20, "GPP_A_20"),
++ PINCTRL_PIN(21, "GPP_A_21"),
++ PINCTRL_PIN(22, "GPP_A_22"),
++ PINCTRL_PIN(23, "GPP_A_23"),
++ /* GPP_B */
++ PINCTRL_PIN(24, "CORE_VID_0"),
++ PINCTRL_PIN(25, "CORE_VID_1"),
++ PINCTRL_PIN(26, "VRALERTB"),
++ PINCTRL_PIN(27, "CPU_GP_2"),
++ PINCTRL_PIN(28, "CPU_GP_3"),
++ PINCTRL_PIN(29, "SRCCLKREQB_0"),
++ PINCTRL_PIN(30, "SRCCLKREQB_1"),
++ PINCTRL_PIN(31, "SRCCLKREQB_2"),
++ PINCTRL_PIN(32, "SRCCLKREQB_3"),
++ PINCTRL_PIN(33, "SRCCLKREQB_4"),
++ PINCTRL_PIN(34, "SRCCLKREQB_5"),
++ PINCTRL_PIN(35, "GPP_B_11"),
++ PINCTRL_PIN(36, "GLB_RST_WARN_N"),
++ PINCTRL_PIN(37, "PLTRSTB"),
++ PINCTRL_PIN(38, "SPKR"),
++ PINCTRL_PIN(39, "GPP_B_15"),
++ PINCTRL_PIN(40, "GPP_B_16"),
++ PINCTRL_PIN(41, "GPP_B_17"),
++ PINCTRL_PIN(42, "GPP_B_18"),
++ PINCTRL_PIN(43, "GPP_B_19"),
++ PINCTRL_PIN(44, "GPP_B_20"),
++ PINCTRL_PIN(45, "GPP_B_21"),
++ PINCTRL_PIN(46, "GPP_B_22"),
++ PINCTRL_PIN(47, "SML1ALERTB"),
++ /* GPP_F */
++ PINCTRL_PIN(48, "SATAXPCIE_3"),
++ PINCTRL_PIN(49, "SATAXPCIE_4"),
++ PINCTRL_PIN(50, "SATAXPCIE_5"),
++ PINCTRL_PIN(51, "SATAXPCIE_6"),
++ PINCTRL_PIN(52, "SATAXPCIE_7"),
++ PINCTRL_PIN(53, "SATA_DEVSLP_3"),
++ PINCTRL_PIN(54, "SATA_DEVSLP_4"),
++ PINCTRL_PIN(55, "SATA_DEVSLP_5"),
++ PINCTRL_PIN(56, "SATA_DEVSLP_6"),
++ PINCTRL_PIN(57, "SATA_DEVSLP_7"),
++ PINCTRL_PIN(58, "SATA_SCLOCK"),
++ PINCTRL_PIN(59, "SATA_SLOAD"),
++ PINCTRL_PIN(60, "SATA_SDATAOUT1"),
++ PINCTRL_PIN(61, "SATA_SDATAOUT0"),
++ PINCTRL_PIN(62, "SSATA_LEDB"),
++ PINCTRL_PIN(63, "USB2_OCB_4"),
++ PINCTRL_PIN(64, "USB2_OCB_5"),
++ PINCTRL_PIN(65, "USB2_OCB_6"),
++ PINCTRL_PIN(66, "USB2_OCB_7"),
++ PINCTRL_PIN(67, "GBE_SMBUS_CLK"),
++ PINCTRL_PIN(68, "GBE_SMBDATA"),
++ PINCTRL_PIN(69, "GBE_SMBALRTN"),
++ PINCTRL_PIN(70, "SSATA_SCLOCK"),
++ PINCTRL_PIN(71, "SSATA_SLOAD"),
++ /* GPP_C */
++ PINCTRL_PIN(72, "SMBCLK"),
++ PINCTRL_PIN(73, "SMBDATA"),
++ PINCTRL_PIN(74, "SMBALERTB"),
++ PINCTRL_PIN(75, "SML0CLK"),
++ PINCTRL_PIN(76, "SML0DATA"),
++ PINCTRL_PIN(77, "SML0ALERTB"),
++ PINCTRL_PIN(78, "SML1CLK"),
++ PINCTRL_PIN(79, "SML1DATA"),
++ PINCTRL_PIN(80, "GPP_C_8"),
++ PINCTRL_PIN(81, "GPP_C_9"),
++ PINCTRL_PIN(82, "GPP_C_10"),
++ PINCTRL_PIN(83, "GPP_C_11"),
++ PINCTRL_PIN(84, "GPP_C_12"),
++ PINCTRL_PIN(85, "GPP_C_13"),
++ PINCTRL_PIN(86, "GPP_C_14"),
++ PINCTRL_PIN(87, "GPP_C_15"),
++ PINCTRL_PIN(88, "GPP_C_16"),
++ PINCTRL_PIN(89, "GPP_C_17"),
++ PINCTRL_PIN(90, "GPP_C_18"),
++ PINCTRL_PIN(91, "GPP_C_19"),
++ PINCTRL_PIN(92, "GPP_C_20"),
++ PINCTRL_PIN(93, "GPP_C_21"),
++ PINCTRL_PIN(94, "GPP_C_22"),
++ PINCTRL_PIN(95, "GPP_C_23"),
++ /* GPP_D */
++ PINCTRL_PIN(96, "GPP_D_0"),
++ PINCTRL_PIN(97, "GPP_D_1"),
++ PINCTRL_PIN(98, "GPP_D_2"),
++ PINCTRL_PIN(99, "GPP_D_3"),
++ PINCTRL_PIN(100, "GPP_D_4"),
++ PINCTRL_PIN(101, "SSP0_SFRM"),
++ PINCTRL_PIN(102, "SSP0_TXD"),
++ PINCTRL_PIN(103, "SSP0_RXD"),
++ PINCTRL_PIN(104, "SSP0_SCLK"),
++ PINCTRL_PIN(105, "SSATA_DEVSLP_3"),
++ PINCTRL_PIN(106, "SSATA_DEVSLP_4"),
++ PINCTRL_PIN(107, "SSATA_DEVSLP_5"),
++ PINCTRL_PIN(108, "SSATA_SDATAOUT1"),
++ PINCTRL_PIN(109, "SML0BCLK_SML0BCLKIE"),
++ PINCTRL_PIN(110, "SML0BDATA_SML0BDATAIE"),
++ PINCTRL_PIN(111, "SSATA_SDATAOUT0"),
++ PINCTRL_PIN(112, "SML0BALERTB_SML0BALERTBIE"),
++ PINCTRL_PIN(113, "DMIC_CLK_1"),
++ PINCTRL_PIN(114, "DMIC_DATA_1"),
++ PINCTRL_PIN(115, "DMIC_CLK_0"),
++ PINCTRL_PIN(116, "DMIC_DATA_0"),
++ PINCTRL_PIN(117, "IE_UART_RXD"),
++ PINCTRL_PIN(118, "IE_UART_TXD"),
++ PINCTRL_PIN(119, "GPP_D_23"),
++ /* GPP_E */
++ PINCTRL_PIN(120, "SATAXPCIE_0"),
++ PINCTRL_PIN(121, "SATAXPCIE_1"),
++ PINCTRL_PIN(122, "SATAXPCIE_2"),
++ PINCTRL_PIN(123, "CPU_GP_0"),
++ PINCTRL_PIN(124, "SATA_DEVSLP_0"),
++ PINCTRL_PIN(125, "SATA_DEVSLP_1"),
++ PINCTRL_PIN(126, "SATA_DEVSLP_2"),
++ PINCTRL_PIN(127, "CPU_GP_1"),
++ PINCTRL_PIN(128, "SATA_LEDB"),
++ PINCTRL_PIN(129, "USB2_OCB_0"),
++ PINCTRL_PIN(130, "USB2_OCB_1"),
++ PINCTRL_PIN(131, "USB2_OCB_2"),
++ PINCTRL_PIN(132, "USB2_OCB_3"),
++ /* GPP_I */
++ PINCTRL_PIN(133, "GBE_TDO"),
++ PINCTRL_PIN(134, "GBE_TCK"),
++ PINCTRL_PIN(135, "GBE_TMS"),
++ PINCTRL_PIN(136, "GBE_TDI"),
++ PINCTRL_PIN(137, "DO_RESET_INB"),
++ PINCTRL_PIN(138, "DO_RESET_OUTB"),
++ PINCTRL_PIN(139, "RESET_DONE"),
++ PINCTRL_PIN(140, "GBE_TRST_N"),
++ PINCTRL_PIN(141, "GBE_PCI_DIS"),
++ PINCTRL_PIN(142, "GBE_LAN_DIS"),
++ PINCTRL_PIN(143, "GPP_I_10"),
++ PINCTRL_PIN(144, "GPIO_RCOMP_3P3"),
++ /* GPP_J */
++ PINCTRL_PIN(145, "GBE_LED_0_0"),
++ PINCTRL_PIN(146, "GBE_LED_0_1"),
++ PINCTRL_PIN(147, "GBE_LED_1_0"),
++ PINCTRL_PIN(148, "GBE_LED_1_1"),
++ PINCTRL_PIN(149, "GBE_LED_2_0"),
++ PINCTRL_PIN(150, "GBE_LED_2_1"),
++ PINCTRL_PIN(151, "GBE_LED_3_0"),
++ PINCTRL_PIN(152, "GBE_LED_3_1"),
++ PINCTRL_PIN(153, "GBE_SCL_0"),
++ PINCTRL_PIN(154, "GBE_SDA_0"),
++ PINCTRL_PIN(155, "GBE_SCL_1"),
++ PINCTRL_PIN(156, "GBE_SDA_1"),
++ PINCTRL_PIN(157, "GBE_SCL_2"),
++ PINCTRL_PIN(158, "GBE_SDA_2"),
++ PINCTRL_PIN(159, "GBE_SCL_3"),
++ PINCTRL_PIN(160, "GBE_SDA_3"),
++ PINCTRL_PIN(161, "GBE_SDP_0_0"),
++ PINCTRL_PIN(162, "GBE_SDP_0_1"),
++ PINCTRL_PIN(163, "GBE_SDP_1_0"),
++ PINCTRL_PIN(164, "GBE_SDP_1_1"),
++ PINCTRL_PIN(165, "GBE_SDP_2_0"),
++ PINCTRL_PIN(166, "GBE_SDP_2_1"),
++ PINCTRL_PIN(167, "GBE_SDP_3_0"),
++ PINCTRL_PIN(168, "GBE_SDP_3_1"),
++ /* GPP_K */
++ PINCTRL_PIN(169, "GBE_RMIICLK"),
++ PINCTRL_PIN(170, "GBE_RMII_TXD_0"),
++ PINCTRL_PIN(171, "GBE_RMII_TXD_1"),
++ PINCTRL_PIN(172, "GBE_RMII_TX_EN"),
++ PINCTRL_PIN(173, "GBE_RMII_CRS_DV"),
++ PINCTRL_PIN(174, "GBE_RMII_RXD_0"),
++ PINCTRL_PIN(175, "GBE_RMII_RXD_1"),
++ PINCTRL_PIN(176, "GBE_RMII_RX_ER"),
++ PINCTRL_PIN(177, "GBE_RMII_ARBIN"),
++ PINCTRL_PIN(178, "GBE_RMII_ARB_OUT"),
++ PINCTRL_PIN(179, "PE_RST_N"),
++ PINCTRL_PIN(180, "GPIO_RCOMP_1P8_3P3"),
++ /* GPP_G */
++ PINCTRL_PIN(181, "FAN_TACH_0"),
++ PINCTRL_PIN(182, "FAN_TACH_1"),
++ PINCTRL_PIN(183, "FAN_TACH_2"),
++ PINCTRL_PIN(184, "FAN_TACH_3"),
++ PINCTRL_PIN(185, "FAN_TACH_4"),
++ PINCTRL_PIN(186, "FAN_TACH_5"),
++ PINCTRL_PIN(187, "FAN_TACH_6"),
++ PINCTRL_PIN(188, "FAN_TACH_7"),
++ PINCTRL_PIN(189, "FAN_PWM_0"),
++ PINCTRL_PIN(190, "FAN_PWM_1"),
++ PINCTRL_PIN(191, "FAN_PWM_2"),
++ PINCTRL_PIN(192, "FAN_PWM_3"),
++ PINCTRL_PIN(193, "GSXDOUT"),
++ PINCTRL_PIN(194, "GSXSLOAD"),
++ PINCTRL_PIN(195, "GSXDIN"),
++ PINCTRL_PIN(196, "GSXSRESETB"),
++ PINCTRL_PIN(197, "GSXCLK"),
++ PINCTRL_PIN(198, "ADR_COMPLETE"),
++ PINCTRL_PIN(199, "NMIB"),
++ PINCTRL_PIN(200, "SMIB"),
++ PINCTRL_PIN(201, "SSATA_DEVSLP_0"),
++ PINCTRL_PIN(202, "SSATA_DEVSLP_1"),
++ PINCTRL_PIN(203, "SSATA_DEVSLP_2"),
++ PINCTRL_PIN(204, "SSATAXPCIE0_SSATAGP0"),
++ /* GPP_H */
++ PINCTRL_PIN(205, "SRCCLKREQB_6"),
++ PINCTRL_PIN(206, "SRCCLKREQB_7"),
++ PINCTRL_PIN(207, "SRCCLKREQB_8"),
++ PINCTRL_PIN(208, "SRCCLKREQB_9"),
++ PINCTRL_PIN(209, "SRCCLKREQB_10"),
++ PINCTRL_PIN(210, "SRCCLKREQB_11"),
++ PINCTRL_PIN(211, "SRCCLKREQB_12"),
++ PINCTRL_PIN(212, "SRCCLKREQB_13"),
++ PINCTRL_PIN(213, "SRCCLKREQB_14"),
++ PINCTRL_PIN(214, "SRCCLKREQB_15"),
++ PINCTRL_PIN(215, "SML2CLK"),
++ PINCTRL_PIN(216, "SML2DATA"),
++ PINCTRL_PIN(217, "SML2ALERTB"),
++ PINCTRL_PIN(218, "SML3CLK"),
++ PINCTRL_PIN(219, "SML3DATA"),
++ PINCTRL_PIN(220, "SML3ALERTB"),
++ PINCTRL_PIN(221, "SML4CLK"),
++ PINCTRL_PIN(222, "SML4DATA"),
++ PINCTRL_PIN(223, "SML4ALERTB"),
++ PINCTRL_PIN(224, "SSATAXPCIE1_SSATAGP1"),
++ PINCTRL_PIN(225, "SSATAXPCIE2_SSATAGP2"),
++ PINCTRL_PIN(226, "SSATAXPCIE3_SSATAGP3"),
++ PINCTRL_PIN(227, "SSATAXPCIE4_SSATAGP4"),
++ PINCTRL_PIN(228, "SSATAXPCIE5_SSATAGP5"),
++ /* GPP_L */
++ PINCTRL_PIN(229, "VISA2CH0_D0"),
++ PINCTRL_PIN(230, "VISA2CH0_D1"),
++ PINCTRL_PIN(231, "VISA2CH0_D2"),
++ PINCTRL_PIN(232, "VISA2CH0_D3"),
++ PINCTRL_PIN(233, "VISA2CH0_D4"),
++ PINCTRL_PIN(234, "VISA2CH0_D5"),
++ PINCTRL_PIN(235, "VISA2CH0_D6"),
++ PINCTRL_PIN(236, "VISA2CH0_D7"),
++ PINCTRL_PIN(237, "VISA2CH0_CLK"),
++ PINCTRL_PIN(238, "VISA2CH1_D0"),
++ PINCTRL_PIN(239, "VISA2CH1_D1"),
++ PINCTRL_PIN(240, "VISA2CH1_D2"),
++ PINCTRL_PIN(241, "VISA2CH1_D3"),
++ PINCTRL_PIN(242, "VISA2CH1_D4"),
++ PINCTRL_PIN(243, "VISA2CH1_D5"),
++ PINCTRL_PIN(244, "VISA2CH1_D6"),
++ PINCTRL_PIN(245, "VISA2CH1_D7"),
++ PINCTRL_PIN(246, "VISA2CH1_CLK"),
++};
++
++static const struct intel_community lbg_communities[] = {
++ LBG_COMMUNITY(0, 0, 71),
++ LBG_COMMUNITY(1, 72, 132),
++ LBG_COMMUNITY(3, 133, 144),
++ LBG_COMMUNITY(4, 145, 180),
++ LBG_COMMUNITY(5, 181, 246),
++};
++
++static const struct intel_pinctrl_soc_data lbg_soc_data = {
++ .pins = lbg_pins,
++ .npins = ARRAY_SIZE(lbg_pins),
++ .communities = lbg_communities,
++ .ncommunities = ARRAY_SIZE(lbg_communities),
++};
++
++static int lbg_pinctrl_probe(struct platform_device *pdev)
++{
++ return intel_pinctrl_probe(pdev, &lbg_soc_data);
++}
++
++static const struct dev_pm_ops lbg_pinctrl_pm_ops = {
++ SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
++ intel_pinctrl_resume)
++};
++
++static const struct acpi_device_id lbg_pinctrl_acpi_match[] = {
++ { "INT3536" },
++ { }
++};
++MODULE_DEVICE_TABLE(acpi, lbg_pinctrl_acpi_match);
++
++static struct platform_driver lbg_pinctrl_driver = {
++ .probe = lbg_pinctrl_probe,
++ .driver = {
++ .name = "lewisburg-pinctrl",
++ .acpi_match_table = lbg_pinctrl_acpi_match,
++ .pm = &lbg_pinctrl_pm_ops,
++ },
++};
++
++module_platform_driver(lbg_pinctrl_driver);
++
++MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
++MODULE_DESCRIPTION("Intel Lewisburg pinctrl/GPIO driver");
++MODULE_LICENSE("GPL v2");
+--
+2.18.0
+
diff --git a/patches.drivers/qed-Add-link-change-count-value-to-ethtool-statistic.patch b/patches.drivers/qed-Add-link-change-count-value-to-ethtool-statistic.patch
new file mode 100644
index 0000000000..5f60009848
--- /dev/null
+++ b/patches.drivers/qed-Add-link-change-count-value-to-ethtool-statistic.patch
@@ -0,0 +1,96 @@
+From: Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>
+Date: Tue, 29 May 2018 02:31:24 -0700
+Subject: qed*: Add link change count value to ethtool statistics display.
+Patch-mainline: v4.18-rc1
+Git-commit: 32d26a685c1802a0e485bd674e7dd038e88019f7
+References: bsc#1086314 FATE#324886
+
+This patch adds driver changes for capturing the link change count in
+ethtool statistics display.
+
+Please consider applying this to "net-next".
+
+Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
+Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_l2.c | 12 ++++++++++--
+ drivers/net/ethernet/qlogic/qede/qede.h | 1 +
+ drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 2 ++
+ drivers/net/ethernet/qlogic/qede/qede_main.c | 1 +
+ include/linux/qed/qed_if.h | 1 +
+ 5 files changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c
+@@ -1854,6 +1854,11 @@ static void __qed_get_vport_port_stats(s
+ p_ah->tx_1519_to_max_byte_packets =
+ port_stats.eth.u1.ah1.t1519_to_max;
+ }
++
++ p_common->link_change_count = qed_rd(p_hwfn, p_ptt,
++ p_hwfn->mcp_info->port_addr +
++ offsetof(struct public_port,
++ link_change_count));
+ }
+
+ static void __qed_get_vport_stats(struct qed_hwfn *p_hwfn,
+@@ -1961,11 +1966,14 @@ void qed_reset_vport_stats(struct qed_de
+
+ /* PORT statistics are not necessarily reset, so we need to
+ * read and create a baseline for future statistics.
++ * Link change stat is maintained by MFW, return its value as is.
+ */
+- if (!cdev->reset_stats)
++ if (!cdev->reset_stats) {
+ DP_INFO(cdev, "Reset stats not allocated\n");
+- else
++ } else {
+ _qed_get_vport_stats(cdev, cdev->reset_stats);
++ cdev->reset_stats->common.link_change_count = 0;
++ }
+ }
+
+ static enum gft_profile_type
+--- a/drivers/net/ethernet/qlogic/qede/qede.h
++++ b/drivers/net/ethernet/qlogic/qede/qede.h
+@@ -87,6 +87,7 @@ struct qede_stats_common {
+ u64 coalesced_aborts_num;
+ u64 non_coalesced_pkts;
+ u64 coalesced_bytes;
++ u64 link_change_count;
+
+ /* port */
+ u64 rx_64_byte_packets;
+--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
++++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+@@ -171,6 +171,8 @@ static const struct {
+ QEDE_STAT(coalesced_aborts_num),
+ QEDE_STAT(non_coalesced_pkts),
+ QEDE_STAT(coalesced_bytes),
++
++ QEDE_STAT(link_change_count),
+ };
+
+ #define QEDE_NUM_STATS ARRAY_SIZE(qede_stats_arr)
+--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
++++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
+@@ -399,6 +399,7 @@ void qede_fill_by_demand_stats(struct qe
+ p_common->brb_truncates = stats.common.brb_truncates;
+ p_common->brb_discards = stats.common.brb_discards;
+ p_common->tx_mac_ctrl_frames = stats.common.tx_mac_ctrl_frames;
++ p_common->link_change_count = stats.common.link_change_count;
+
+ if (QEDE_IS_BB(edev)) {
+ struct qede_stats_bb *p_bb = &edev->stats.bb;
+--- a/include/linux/qed/qed_if.h
++++ b/include/linux/qed/qed_if.h
+@@ -1180,6 +1180,7 @@ struct qed_eth_stats_common {
+ u64 tx_mac_mc_packets;
+ u64 tx_mac_bc_packets;
+ u64 tx_mac_ctrl_frames;
++ u64 link_change_count;
+ };
+
+ struct qed_eth_stats_bb {
diff --git a/patches.drivers/qed-Add-qed-APIs-for-PHY-module-query.patch b/patches.drivers/qed-Add-qed-APIs-for-PHY-module-query.patch
new file mode 100644
index 0000000000..36fdeee8c8
--- /dev/null
+++ b/patches.drivers/qed-Add-qed-APIs-for-PHY-module-query.patch
@@ -0,0 +1,221 @@
+From: Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>
+Date: Wed, 18 Jul 2018 06:27:22 -0700
+Subject: qed: Add qed APIs for PHY module query.
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: b51dab46c6adfbb7e80cd0f59ae17b8a30d94b1a
+References: bsc#1086314 FATE#324886
+
+This patch adds qed APIs for reading the PHY module.
+
+Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
+Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_hsi.h | 16 +++++++++
+ drivers/net/ethernet/qlogic/qed/qed_main.c | 23 +++++++++++++
+ drivers/net/ethernet/qlogic/qed/qed_mcp.c | 49 +++++++++++++++++++++++++++++
+ drivers/net/ethernet/qlogic/qed/qed_mcp.h | 16 +++++++++
+ include/linux/qed/qed_if.h | 15 ++++++++
+ 5 files changed, 119 insertions(+)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+@@ -12444,6 +12444,8 @@ struct public_drv_mb {
+ #define DRV_MSG_CODE_STATS_TYPE_ISCSI 3
+ #define DRV_MSG_CODE_STATS_TYPE_RDMA 4
+
++#define DRV_MSG_CODE_TRANSCEIVER_READ 0x00160000
++
+ #define DRV_MSG_CODE_MASK_PARITIES 0x001a0000
+
+ #define DRV_MSG_CODE_BIST_TEST 0x001e0000
+@@ -12543,6 +12545,15 @@ struct public_drv_mb {
+ #define DRV_MB_PARAM_SET_LED_MODE_ON 0x1
+ #define DRV_MB_PARAM_SET_LED_MODE_OFF 0x2
+
++#define DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET 0
++#define DRV_MB_PARAM_TRANSCEIVER_PORT_MASK 0x00000003
++#define DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET 2
++#define DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK 0x000000FC
++#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET 8
++#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK 0x0000FF00
++#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET 16
++#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK 0xFFFF0000
++
+ /* Resource Allocation params - Driver version support */
+ #define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000
+ #define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
+@@ -12596,6 +12607,9 @@ struct public_drv_mb {
+ #define FW_MSG_CODE_PHY_OK 0x00110000
+ #define FW_MSG_CODE_OK 0x00160000
+ #define FW_MSG_CODE_ERROR 0x00170000
++#define FW_MSG_CODE_TRANSCEIVER_DIAG_OK 0x00160000
++#define FW_MSG_CODE_TRANSCEIVER_DIAG_ERROR 0x00170000
++#define FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT 0x00020000
+
+ #define FW_MSG_CODE_OS_WOL_SUPPORTED 0x00800000
+ #define FW_MSG_CODE_OS_WOL_NOT_SUPPORTED 0x00810000
+@@ -12687,6 +12701,8 @@ struct mcp_public_data {
+ struct public_func func[MCP_GLOB_FUNC_MAX];
+ };
+
++#define MAX_I2C_TRANSACTION_SIZE 16
++
+ /* OCBB definitions */
+ enum tlvs {
+ /* Category 1: Device Properties */
+--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
+@@ -2102,6 +2102,28 @@ out:
+ return status;
+ }
+
++static int qed_read_module_eeprom(struct qed_dev *cdev, char *buf,
++ u8 dev_addr, u32 offset, u32 len)
++{
++ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
++ struct qed_ptt *ptt;
++ int rc = 0;
++
++ if (IS_VF(cdev))
++ return 0;
++
++ ptt = qed_ptt_acquire(hwfn);
++ if (!ptt)
++ return -EAGAIN;
++
++ rc = qed_mcp_phy_sfp_read(hwfn, ptt, MFW_PORT(hwfn), dev_addr,
++ offset, len, buf);
++
++ qed_ptt_release(hwfn, ptt);
++
++ return rc;
++}
++
+ static struct qed_selftest_ops qed_selftest_ops_pass = {
+ .selftest_memory = &qed_selftest_memory,
+ .selftest_interrupt = &qed_selftest_interrupt,
+@@ -2144,6 +2166,7 @@ const struct qed_common_ops qed_common_o
+ .update_mac = &qed_update_mac,
+ .update_mtu = &qed_update_mtu,
+ .update_wol = &qed_update_wol,
++ .read_module_eeprom = &qed_read_module_eeprom,
+ };
+
+ void qed_get_protocol_stats(struct qed_dev *cdev,
+--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+@@ -2473,6 +2473,55 @@ out:
+ return rc;
+ }
+
++int qed_mcp_phy_sfp_read(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
++ u32 port, u32 addr, u32 offset, u32 len, u8 *p_buf)
++{
++ u32 bytes_left, bytes_to_copy, buf_size, nvm_offset = 0;
++ u32 resp, param;
++ int rc;
++
++ nvm_offset |= (port << DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET) &
++ DRV_MB_PARAM_TRANSCEIVER_PORT_MASK;
++ nvm_offset |= (addr << DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET) &
++ DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK;
++
++ addr = offset;
++ offset = 0;
++ bytes_left = len;
++ while (bytes_left > 0) {
++ bytes_to_copy = min_t(u32, bytes_left,
++ MAX_I2C_TRANSACTION_SIZE);
++ nvm_offset &= (DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK |
++ DRV_MB_PARAM_TRANSCEIVER_PORT_MASK);
++ nvm_offset |= ((addr + offset) <<
++ DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET) &
++ DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK;
++ nvm_offset |= (bytes_to_copy <<
++ DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET) &
++ DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK;
++ rc = qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
++ DRV_MSG_CODE_TRANSCEIVER_READ,
++ nvm_offset, &resp, &param, &buf_size,
++ (u32 *)(p_buf + offset));
++ if (rc) {
++ DP_NOTICE(p_hwfn,
++ "Failed to send a transceiver read command to the MFW. rc = %d.\n",
++ rc);
++ return rc;
++ }
++
++ if (resp == FW_MSG_CODE_TRANSCEIVER_NOT_PRESENT)
++ return -ENODEV;
++ else if (resp != FW_MSG_CODE_TRANSCEIVER_DIAG_OK)
++ return -EINVAL;
++
++ offset += buf_size;
++ bytes_left -= buf_size;
++ }
++
++ return 0;
++}
++
+ int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
+ {
+ u32 drv_mb_param = 0, rsp, param;
+--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+@@ -840,6 +840,22 @@ int qed_mcp_nvm_rd_cmd(struct qed_hwfn *
+ u32 *o_mcp_param, u32 *o_txn_size, u32 *o_buf);
+
+ /**
++ * @brief Read from sfp
++ *
++ * @param p_hwfn - hw function
++ * @param p_ptt - PTT required for register access
++ * @param port - transceiver port
++ * @param addr - I2C address
++ * @param offset - offset in sfp
++ * @param len - buffer length
++ * @param p_buf - buffer to read into
++ *
++ * @return int - 0 - operation was successful.
++ */
++int qed_mcp_phy_sfp_read(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
++ u32 port, u32 addr, u32 offset, u32 len, u8 *p_buf);
++
++/**
+ * @brief indicates whether the MFW objects [under mcp_info] are accessible
+ *
+ * @param p_hwfn
+--- a/include/linux/qed/qed_if.h
++++ b/include/linux/qed/qed_if.h
+@@ -759,6 +759,9 @@ struct qed_generic_tlvs {
+ u8 mac[QED_TLV_MAC_COUNT][ETH_ALEN];
+ };
+
++#define QED_I2C_DEV_ADDR_A0 0xA0
++#define QED_I2C_DEV_ADDR_A2 0xA2
++
+ #define QED_NVM_SIGNATURE 0x12435687
+
+ enum qed_nvm_flash_cmd {
+@@ -1026,6 +1029,18 @@ struct qed_common_ops {
+ * @param enabled - true iff WoL should be enabled.
+ */
+ int (*update_wol) (struct qed_dev *cdev, bool enabled);
++
++/**
++ * @brief read_module_eeprom
++ *
++ * @param cdev
++ * @param buf - buffer
++ * @param dev_addr - PHY device memory region
++ * @param offset - offset into eeprom contents to be read
++ * @param len - buffer length, i.e., max bytes to be read
++ */
++ int (*read_module_eeprom)(struct qed_dev *cdev,
++ char *buf, u8 dev_addr, u32 offset, u32 len);
+ };
+
+ #define MASK_FIELD(_name, _value) \
diff --git a/patches.drivers/qed-Add-srq-core-support-for-RoCE-and-iWARP.patch b/patches.drivers/qed-Add-srq-core-support-for-RoCE-and-iWARP.patch
new file mode 100644
index 0000000000..eed52d6a5e
--- /dev/null
+++ b/patches.drivers/qed-Add-srq-core-support-for-RoCE-and-iWARP.patch
@@ -0,0 +1,445 @@
+From: Yuval Bason <yuval.bason@cavium.com>
+Date: Sun, 3 Jun 2018 19:13:07 +0300
+Subject: qed: Add srq core support for RoCE and iWARP
+Patch-mainline: v4.18-rc1
+Git-commit: 39dbc646fd2c67ee9b71450ce172cbd714d4e7fb
+References: bsc#1086314 FATE#324886
+
+This patch adds support for configuring SRQ and provides the necessary
+APIs for rdma upper layer driver (qedr) to enable the SRQ feature.
+
+Signed-off-by: Michal Kalderon <michal.kalderon@cavium.com>
+Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
+Signed-off-by: Yuval Bason <yuval.bason@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_cxt.c | 5
+ drivers/net/ethernet/qlogic/qed/qed_cxt.h | 1
+ drivers/net/ethernet/qlogic/qed/qed_hsi.h | 2
+ drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 23 +++
+ drivers/net/ethernet/qlogic/qed/qed_main.c | 2
+ drivers/net/ethernet/qlogic/qed/qed_rdma.c | 178 +++++++++++++++++++++++++++-
+ drivers/net/ethernet/qlogic/qed/qed_rdma.h | 2
+ drivers/net/ethernet/qlogic/qed/qed_roce.c | 17 ++
+ include/linux/qed/qed_rdma_if.h | 12 +
+ 9 files changed, 234 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+@@ -47,6 +47,7 @@
+ #include "qed_hsi.h"
+ #include "qed_hw.h"
+ #include "qed_init_ops.h"
++#include "qed_rdma.h"
+ #include "qed_reg_addr.h"
+ #include "qed_sriov.h"
+
+@@ -426,7 +427,7 @@ static void qed_cxt_set_srq_count(struct
+ p_mgr->srq_count = num_srqs;
+ }
+
+-static u32 qed_cxt_get_srq_count(struct qed_hwfn *p_hwfn)
++u32 qed_cxt_get_srq_count(struct qed_hwfn *p_hwfn)
+ {
+ struct qed_cxt_mngr *p_mgr = p_hwfn->p_cxt_mngr;
+
+@@ -2071,7 +2072,7 @@ static void qed_rdma_set_pf_params(struc
+ u32 num_cons, num_qps, num_srqs;
+ enum protocol_type proto;
+
+- num_srqs = min_t(u32, 32 * 1024, p_params->num_srqs);
++ num_srqs = min_t(u32, QED_RDMA_MAX_SRQS, p_params->num_srqs);
+
+ if (p_hwfn->mcp_info->func_info.protocol == QED_PCI_ETH_RDMA) {
+ DP_NOTICE(p_hwfn,
+--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.h
+@@ -235,6 +235,7 @@ u32 qed_cxt_get_proto_tid_count(struct q
+ enum protocol_type type);
+ u32 qed_cxt_get_proto_cid_start(struct qed_hwfn *p_hwfn,
+ enum protocol_type type);
++u32 qed_cxt_get_srq_count(struct qed_hwfn *p_hwfn);
+ int qed_cxt_free_proto_ilt(struct qed_hwfn *p_hwfn, enum protocol_type proto);
+
+ #define QED_CTX_WORKING_MEM 0
+--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+@@ -9725,6 +9725,8 @@ enum iwarp_eqe_async_opcode {
+ IWARP_EVENT_TYPE_ASYNC_EXCEPTION_DETECTED,
+ IWARP_EVENT_TYPE_ASYNC_QP_IN_ERROR_STATE,
+ IWARP_EVENT_TYPE_ASYNC_CQ_OVERFLOW,
++ IWARP_EVENT_TYPE_ASYNC_SRQ_EMPTY,
++ IWARP_EVENT_TYPE_ASYNC_SRQ_LIMIT,
+ MAX_IWARP_EQE_ASYNC_OPCODE
+ };
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+@@ -271,6 +271,8 @@ int qed_iwarp_create_qp(struct qed_hwfn
+ p_ramrod->sq_num_pages = qp->sq_num_pages;
+ p_ramrod->rq_num_pages = qp->rq_num_pages;
+
++ p_ramrod->srq_id.srq_idx = cpu_to_le16(qp->srq_id);
++ p_ramrod->srq_id.opaque_fid = cpu_to_le16(p_hwfn->hw_info.opaque_fid);
+ p_ramrod->qp_handle_for_cqe.hi = cpu_to_le32(qp->qp_handle.hi);
+ p_ramrod->qp_handle_for_cqe.lo = cpu_to_le32(qp->qp_handle.lo);
+
+@@ -3004,8 +3006,11 @@ static int qed_iwarp_async_event(struct
+ union event_ring_data *data,
+ u8 fw_return_code)
+ {
++ struct qed_rdma_events events = p_hwfn->p_rdma_info->events;
+ struct regpair *fw_handle = &data->rdma_data.async_handle;
+ struct qed_iwarp_ep *ep = NULL;
++ u16 srq_offset;
++ u16 srq_id;
+ u16 cid;
+
+ ep = (struct qed_iwarp_ep *)(uintptr_t)HILO_64(fw_handle->hi,
+@@ -3067,6 +3072,24 @@ static int qed_iwarp_async_event(struct
+ qed_iwarp_cid_cleaned(p_hwfn, cid);
+
+ break;
++ case IWARP_EVENT_TYPE_ASYNC_SRQ_EMPTY:
++ DP_NOTICE(p_hwfn, "IWARP_EVENT_TYPE_ASYNC_SRQ_EMPTY\n");
++ srq_offset = p_hwfn->p_rdma_info->srq_id_offset;
++ /* FW assigns value that is no greater than u16 */
++ srq_id = ((u16)le32_to_cpu(fw_handle->lo)) - srq_offset;
++ events.affiliated_event(events.context,
++ QED_IWARP_EVENT_SRQ_EMPTY,
++ &srq_id);
++ break;
++ case IWARP_EVENT_TYPE_ASYNC_SRQ_LIMIT:
++ DP_NOTICE(p_hwfn, "IWARP_EVENT_TYPE_ASYNC_SRQ_LIMIT\n");
++ srq_offset = p_hwfn->p_rdma_info->srq_id_offset;
++ /* FW assigns value that is no greater than u16 */
++ srq_id = ((u16)le32_to_cpu(fw_handle->lo)) - srq_offset;
++ events.affiliated_event(events.context,
++ QED_IWARP_EVENT_SRQ_LIMIT,
++ &srq_id);
++ break;
+ case IWARP_EVENT_TYPE_ASYNC_CQ_OVERFLOW:
+ DP_NOTICE(p_hwfn, "IWARP_EVENT_TYPE_ASYNC_CQ_OVERFLOW\n");
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
+@@ -64,6 +64,7 @@
+
+ #define QED_ROCE_QPS (8192)
+ #define QED_ROCE_DPIS (8)
++#define QED_RDMA_SRQS QED_ROCE_QPS
+
+ static char version[] =
+ "QLogic FastLinQ 4xxxx Core Module qed " DRV_MODULE_VERSION "\n";
+@@ -922,6 +923,7 @@ static void qed_update_pf_params(struct
+ if (IS_ENABLED(CONFIG_QED_RDMA)) {
+ params->rdma_pf_params.num_qps = QED_ROCE_QPS;
+ params->rdma_pf_params.min_dpis = QED_ROCE_DPIS;
++ params->rdma_pf_params.num_srqs = QED_RDMA_SRQS;
+ /* divide by 3 the MRs to avoid MF ILT overflow */
+ params->rdma_pf_params.gl_pi = QED_ROCE_PROTOCOL_INDEX;
+ }
+--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+@@ -259,15 +259,29 @@ static int qed_rdma_alloc(struct qed_hwf
+ goto free_cid_map;
+ }
+
++ /* Allocate bitmap for srqs */
++ p_rdma_info->num_srqs = qed_cxt_get_srq_count(p_hwfn);
++ rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->srq_map,
++ p_rdma_info->num_srqs, "SRQ");
++ if (rc) {
++ DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
++ "Failed to allocate srq bitmap, rc = %d\n", rc);
++ goto free_real_cid_map;
++ }
++
+ if (QED_IS_IWARP_PERSONALITY(p_hwfn))
+ rc = qed_iwarp_alloc(p_hwfn);
+
+ if (rc)
+- goto free_cid_map;
++ goto free_srq_map;
+
+ DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocation successful\n");
+ return 0;
+
++free_srq_map:
++ kfree(p_rdma_info->srq_map.bitmap);
++free_real_cid_map:
++ kfree(p_rdma_info->real_cid_map.bitmap);
+ free_cid_map:
+ kfree(p_rdma_info->cid_map.bitmap);
+ free_tid_map:
+@@ -351,6 +365,8 @@ static void qed_rdma_resc_free(struct qe
+ qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->cq_map, 1);
+ qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->toggle_bits, 0);
+ qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->tid_map, 1);
++ qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->srq_map, 1);
++ qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->real_cid_map, 1);
+
+ kfree(p_rdma_info->port);
+ kfree(p_rdma_info->dev);
+@@ -431,6 +447,12 @@ static void qed_rdma_init_devinfo(struct
+ if (cdev->rdma_max_sge)
+ dev->max_sge = min_t(u32, cdev->rdma_max_sge, dev->max_sge);
+
++ dev->max_srq_sge = QED_RDMA_MAX_SGE_PER_SRQ_WQE;
++ if (p_hwfn->cdev->rdma_max_srq_sge) {
++ dev->max_srq_sge = min_t(u32,
++ p_hwfn->cdev->rdma_max_srq_sge,
++ dev->max_srq_sge);
++ }
+ dev->max_inline = ROCE_REQ_MAX_INLINE_DATA_SIZE;
+
+ dev->max_inline = (cdev->rdma_max_inline) ?
+@@ -474,6 +496,8 @@ static void qed_rdma_init_devinfo(struct
+ dev->max_mr_mw_fmr_size = dev->max_mr_mw_fmr_pbl * PAGE_SIZE;
+ dev->max_pkey = QED_RDMA_MAX_P_KEY;
+
++ dev->max_srq = p_hwfn->p_rdma_info->num_srqs;
++ dev->max_srq_wr = QED_RDMA_MAX_SRQ_WQE_ELEM;
+ dev->max_qp_resp_rd_atomic_resc = RDMA_RING_PAGE_SIZE /
+ (RDMA_RESP_RD_ATOMIC_ELM_SIZE * 2);
+ dev->max_qp_req_rd_atomic_resc = RDMA_RING_PAGE_SIZE /
+@@ -1628,6 +1652,155 @@ static void *qed_rdma_get_rdma_ctx(struc
+ return QED_LEADING_HWFN(cdev);
+ }
+
++static int qed_rdma_modify_srq(void *rdma_cxt,
++ struct qed_rdma_modify_srq_in_params *in_params)
++{
++ struct rdma_srq_modify_ramrod_data *p_ramrod;
++ struct qed_sp_init_data init_data = {};
++ struct qed_hwfn *p_hwfn = rdma_cxt;
++ struct qed_spq_entry *p_ent;
++ u16 opaque_fid;
++ int rc;
++
++ init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
++ init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
++
++ rc = qed_sp_init_request(p_hwfn, &p_ent,
++ RDMA_RAMROD_MODIFY_SRQ,
++ p_hwfn->p_rdma_info->proto, &init_data);
++ if (rc)
++ return rc;
++
++ p_ramrod = &p_ent->ramrod.rdma_modify_srq;
++ p_ramrod->srq_id.srq_idx = cpu_to_le16(in_params->srq_id);
++ opaque_fid = p_hwfn->hw_info.opaque_fid;
++ p_ramrod->srq_id.opaque_fid = cpu_to_le16(opaque_fid);
++ p_ramrod->wqe_limit = cpu_to_le32(in_params->wqe_limit);
++
++ rc = qed_spq_post(p_hwfn, p_ent, NULL);
++ if (rc)
++ return rc;
++
++ DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "modified SRQ id = %x",
++ in_params->srq_id);
++
++ return rc;
++}
++
++static int
++qed_rdma_destroy_srq(void *rdma_cxt,
++ struct qed_rdma_destroy_srq_in_params *in_params)
++{
++ struct rdma_srq_destroy_ramrod_data *p_ramrod;
++ struct qed_sp_init_data init_data = {};
++ struct qed_hwfn *p_hwfn = rdma_cxt;
++ struct qed_spq_entry *p_ent;
++ struct qed_bmap *bmap;
++ u16 opaque_fid;
++ int rc;
++
++ opaque_fid = p_hwfn->hw_info.opaque_fid;
++
++ init_data.opaque_fid = opaque_fid;
++ init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
++
++ rc = qed_sp_init_request(p_hwfn, &p_ent,
++ RDMA_RAMROD_DESTROY_SRQ,
++ p_hwfn->p_rdma_info->proto, &init_data);
++ if (rc)
++ return rc;
++
++ p_ramrod = &p_ent->ramrod.rdma_destroy_srq;
++ p_ramrod->srq_id.srq_idx = cpu_to_le16(in_params->srq_id);
++ p_ramrod->srq_id.opaque_fid = cpu_to_le16(opaque_fid);
++
++ rc = qed_spq_post(p_hwfn, p_ent, NULL);
++ if (rc)
++ return rc;
++
++ bmap = &p_hwfn->p_rdma_info->srq_map;
++
++ spin_lock_bh(&p_hwfn->p_rdma_info->lock);
++ qed_bmap_release_id(p_hwfn, bmap, in_params->srq_id);
++ spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
++
++ DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "SRQ destroyed Id = %x",
++ in_params->srq_id);
++
++ return rc;
++}
++
++static int
++qed_rdma_create_srq(void *rdma_cxt,
++ struct qed_rdma_create_srq_in_params *in_params,
++ struct qed_rdma_create_srq_out_params *out_params)
++{
++ struct rdma_srq_create_ramrod_data *p_ramrod;
++ struct qed_sp_init_data init_data = {};
++ struct qed_hwfn *p_hwfn = rdma_cxt;
++ enum qed_cxt_elem_type elem_type;
++ struct qed_spq_entry *p_ent;
++ u16 opaque_fid, srq_id;
++ struct qed_bmap *bmap;
++ u32 returned_id;
++ int rc;
++
++ bmap = &p_hwfn->p_rdma_info->srq_map;
++ spin_lock_bh(&p_hwfn->p_rdma_info->lock);
++ rc = qed_rdma_bmap_alloc_id(p_hwfn, bmap, &returned_id);
++ spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
++
++ if (rc) {
++ DP_NOTICE(p_hwfn, "failed to allocate srq id\n");
++ return rc;
++ }
++
++ elem_type = QED_ELEM_SRQ;
++ rc = qed_cxt_dynamic_ilt_alloc(p_hwfn, elem_type, returned_id);
++ if (rc)
++ goto err;
++ /* returned id is no greater than u16 */
++ srq_id = (u16)returned_id;
++ opaque_fid = p_hwfn->hw_info.opaque_fid;
++
++ opaque_fid = p_hwfn->hw_info.opaque_fid;
++ init_data.opaque_fid = opaque_fid;
++ init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
++
++ rc = qed_sp_init_request(p_hwfn, &p_ent,
++ RDMA_RAMROD_CREATE_SRQ,
++ p_hwfn->p_rdma_info->proto, &init_data);
++ if (rc)
++ goto err;
++
++ p_ramrod = &p_ent->ramrod.rdma_create_srq;
++ DMA_REGPAIR_LE(p_ramrod->pbl_base_addr, in_params->pbl_base_addr);
++ p_ramrod->pages_in_srq_pbl = cpu_to_le16(in_params->num_pages);
++ p_ramrod->pd_id = cpu_to_le16(in_params->pd_id);
++ p_ramrod->srq_id.srq_idx = cpu_to_le16(srq_id);
++ p_ramrod->srq_id.opaque_fid = cpu_to_le16(opaque_fid);
++ p_ramrod->page_size = cpu_to_le16(in_params->page_size);
++ DMA_REGPAIR_LE(p_ramrod->producers_addr, in_params->prod_pair_addr);
++
++ rc = qed_spq_post(p_hwfn, p_ent, NULL);
++ if (rc)
++ goto err;
++
++ out_params->srq_id = srq_id;
++
++ DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
++ "SRQ created Id = %x\n", out_params->srq_id);
++
++ return rc;
++
++err:
++ spin_lock_bh(&p_hwfn->p_rdma_info->lock);
++ qed_bmap_release_id(p_hwfn, bmap, returned_id);
++ spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
++
++ return rc;
++}
++
+ bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn)
+ {
+ bool result;
+@@ -1773,6 +1946,9 @@ static const struct qed_rdma_ops qed_rdm
+ .rdma_free_tid = &qed_rdma_free_tid,
+ .rdma_register_tid = &qed_rdma_register_tid,
+ .rdma_deregister_tid = &qed_rdma_deregister_tid,
++ .rdma_create_srq = &qed_rdma_create_srq,
++ .rdma_modify_srq = &qed_rdma_modify_srq,
++ .rdma_destroy_srq = &qed_rdma_destroy_srq,
+ .ll2_acquire_connection = &qed_ll2_acquire_connection,
+ .ll2_establish_connection = &qed_ll2_establish_connection,
+ .ll2_terminate_connection = &qed_ll2_terminate_connection,
+--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.h
+@@ -96,6 +96,8 @@ struct qed_rdma_info {
+ u8 num_cnqs;
+ u32 num_qps;
+ u32 num_mrs;
++ u32 num_srqs;
++ u16 srq_id_offset;
+ u16 queue_zone_base;
+ u16 max_queue_zones;
+ enum protocol_type proto;
+--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c
+@@ -65,6 +65,8 @@ qed_roce_async_event(struct qed_hwfn *p_
+ u8 fw_event_code,
+ u16 echo, union event_ring_data *data, u8 fw_return_code)
+ {
++ struct qed_rdma_events events = p_hwfn->p_rdma_info->events;
++
+ if (fw_event_code == ROCE_ASYNC_EVENT_DESTROY_QP_DONE) {
+ u16 icid =
+ (u16)le32_to_cpu(data->rdma_data.rdma_destroy_qp_data.cid);
+@@ -75,11 +77,18 @@ qed_roce_async_event(struct qed_hwfn *p_
+ */
+ qed_roce_free_real_icid(p_hwfn, icid);
+ } else {
+- struct qed_rdma_events *events = &p_hwfn->p_rdma_info->events;
++ if (fw_event_code == ROCE_ASYNC_EVENT_SRQ_EMPTY ||
++ fw_event_code == ROCE_ASYNC_EVENT_SRQ_LIMIT) {
++ u16 srq_id = (u16)data->rdma_data.async_handle.lo;
++
++ events.affiliated_event(events.context, fw_event_code,
++ &srq_id);
++ } else {
++ union rdma_eqe_data rdata = data->rdma_data;
+
+- events->affiliated_event(p_hwfn->p_rdma_info->events.context,
+- fw_event_code,
+- (void *)&data->rdma_data.async_handle);
++ events.affiliated_event(events.context, fw_event_code,
++ (void *)&rdata.async_handle);
++ }
+ }
+
+ return 0;
+--- a/include/linux/qed/qed_rdma_if.h
++++ b/include/linux/qed/qed_rdma_if.h
+@@ -485,7 +485,9 @@ enum qed_iwarp_event_type {
+ QED_IWARP_EVENT_ACTIVE_MPA_REPLY,
+ QED_IWARP_EVENT_LOCAL_ACCESS_ERROR,
+ QED_IWARP_EVENT_REMOTE_OPERATION_ERROR,
+- QED_IWARP_EVENT_TERMINATE_RECEIVED
++ QED_IWARP_EVENT_TERMINATE_RECEIVED,
++ QED_IWARP_EVENT_SRQ_LIMIT,
++ QED_IWARP_EVENT_SRQ_EMPTY,
+ };
+
+ enum qed_tcp_ip_version {
+@@ -646,6 +648,14 @@ struct qed_rdma_ops {
+ int (*rdma_alloc_tid)(void *rdma_cxt, u32 *itid);
+ void (*rdma_free_tid)(void *rdma_cxt, u32 itid);
+
++ int (*rdma_create_srq)(void *rdma_cxt,
++ struct qed_rdma_create_srq_in_params *iparams,
++ struct qed_rdma_create_srq_out_params *oparams);
++ int (*rdma_destroy_srq)(void *rdma_cxt,
++ struct qed_rdma_destroy_srq_in_params *iparams);
++ int (*rdma_modify_srq)(void *rdma_cxt,
++ struct qed_rdma_modify_srq_in_params *iparams);
++
+ int (*ll2_acquire_connection)(void *rdma_cxt,
+ struct qed_ll2_acquire_data *data);
+
diff --git a/patches.drivers/qed-Make-some-functions-static.patch b/patches.drivers/qed-Make-some-functions-static.patch
new file mode 100644
index 0000000000..66fb242477
--- /dev/null
+++ b/patches.drivers/qed-Make-some-functions-static.patch
@@ -0,0 +1,348 @@
+From: YueHaibing <yuehaibing@huawei.com>
+Date: Tue, 31 Jul 2018 22:12:30 +0800
+Subject: qed: Make some functions static
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: bf774d141a33ea13e8cd11034ada395d3f23ef51
+References: bsc#1086314 FATE#324886
+
+Fixes the following sparse warning:
+
+drivers/net/ethernet/qlogic/qed/qed_cxt.c:1534:6: warning: symbol 'qed_cm_init_pf' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_dev.c:233:4: warning: symbol 'qed_init_qm_get_num_tcs' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_dev.c:238:5: warning: symbol 'qed_init_qm_get_num_vfs' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_dev.c:246:5: warning: symbol 'qed_init_qm_get_num_pf_rls' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_dev.c:264:5: warning: symbol 'qed_init_qm_get_num_vports' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_dev.c:276:5: warning: symbol 'qed_init_qm_get_num_pqs' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_mcp.c:573:5: warning: symbol 'qed_mcp_nvm_wr_cmd' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_mcp.c:3012:1: warning: symbol '__qed_mcp_resc_lock' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_dcbx.c:870:6: warning: symbol 'qed_dcbx_aen' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_debug.c:7841:5: warning: symbol 'qed_dbg_nvm_image_length' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_debug.c:7857:5: warning: symbol 'qed_dbg_nvm_image' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_sriov.c:675:6: warning: symbol '_qed_iov_pf_sanity_check' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_sriov.c:690:6: warning: symbol 'qed_iov_pf_sanity_check' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_sriov.c:3982:6: warning: symbol 'qed_iov_pf_get_pending_events' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_vf.c:172:5: warning: symbol '_qed_vf_pf_release' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_rdma.c:137:5: warning: symbol 'qed_rdma_get_sb_id' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_rdma.c:709:5: warning: symbol 'qed_rdma_stop' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_ll2.c:161:6: warning: symbol 'qed_ll2b_complete_rx_packet' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_roce.c:160:6: warning: symbol 'qed_roce_free_cid_pair' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iwarp.c:380:12: warning: symbol 'iwarp_state_names' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iwarp.c:946:1: warning: symbol 'qed_iwarp_parse_private_data' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iwarp.c:971:1: warning: symbol 'qed_iwarp_mpa_reply_arrived' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iwarp.c:2504:1: warning: symbol 'qed_iwarp_ll2_slowpath' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iwarp.c:2806:6: warning: symbol 'qed_iwarp_qp_in_error' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iwarp.c:2827:6: warning: symbol 'qed_iwarp_exception_received' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iwarp.c:2958:1: warning: symbol 'qed_iwarp_connect_complete' was not declared. Should it be static?
+drivers/net/ethernet/qlogic/qed/qed_iscsi.c:876:6: warning: symbol 'qed_iscsi_free_connection' was not declared. Should it be static?
+
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Acked-by: Denis Bolotin <Denis.Bolotin@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_cxt.c | 2 +-
+ drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 2 +-
+ drivers/net/ethernet/qlogic/qed/qed_debug.c | 9 +++++----
+ drivers/net/ethernet/qlogic/qed/qed_dev.c | 10 +++++-----
+ drivers/net/ethernet/qlogic/qed/qed_iscsi.c | 4 ++--
+ drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 20 +++++++++++---------
+ drivers/net/ethernet/qlogic/qed/qed_ll2.c | 3 ++-
+ drivers/net/ethernet/qlogic/qed/qed_mcp.c | 15 ++++++++-------
+ drivers/net/ethernet/qlogic/qed/qed_rdma.c | 4 ++--
+ drivers/net/ethernet/qlogic/qed/qed_roce.c | 2 +-
+ drivers/net/ethernet/qlogic/qed/qed_sriov.c | 8 ++++----
+ drivers/net/ethernet/qlogic/qed/qed_vf.c | 2 +-
+ 12 files changed, 43 insertions(+), 38 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+@@ -1531,7 +1531,7 @@ void qed_qm_init_pf(struct qed_hwfn *p_h
+ }
+
+ /* CM PF */
+-void qed_cm_init_pf(struct qed_hwfn *p_hwfn)
++static void qed_cm_init_pf(struct qed_hwfn *p_hwfn)
+ {
+ /* XCM pure-LB queue */
+ STORE_RT_REG(p_hwfn, XCM_REG_CON_PHY_Q3_RT_OFFSET,
+--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+@@ -867,7 +867,7 @@ static int qed_dcbx_read_mib(struct qed_
+ return rc;
+ }
+
+-void qed_dcbx_aen(struct qed_hwfn *hwfn, u32 mib_type)
++static void qed_dcbx_aen(struct qed_hwfn *hwfn, u32 mib_type)
+ {
+ struct qed_common_cb_ops *op = hwfn->cdev->protocol_ops.common;
+ void *cookie = hwfn->cdev->ops_cookie;
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -7837,8 +7837,8 @@ int qed_dbg_igu_fifo_size(struct qed_dev
+ return qed_dbg_feature_size(cdev, DBG_FEATURE_IGU_FIFO);
+ }
+
+-int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn,
+- enum qed_nvm_images image_id, u32 *length)
++static int qed_dbg_nvm_image_length(struct qed_hwfn *p_hwfn,
++ enum qed_nvm_images image_id, u32 *length)
+ {
+ struct qed_nvm_image_att image_att;
+ int rc;
+@@ -7853,8 +7853,9 @@ int qed_dbg_nvm_image_length(struct qed_
+ return rc;
+ }
+
+-int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
+- u32 *num_dumped_bytes, enum qed_nvm_images image_id)
++static int qed_dbg_nvm_image(struct qed_dev *cdev, void *buffer,
++ u32 *num_dumped_bytes,
++ enum qed_nvm_images image_id)
+ {
+ struct qed_hwfn *p_hwfn =
+ &cdev->hwfns[cdev->dbg_params.engine_for_debug];
+--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
+@@ -230,12 +230,12 @@ static u32 qed_get_pq_flags(struct qed_h
+ }
+
+ /* Getters for resource amounts necessary for qm initialization */
+-u8 qed_init_qm_get_num_tcs(struct qed_hwfn *p_hwfn)
++static u8 qed_init_qm_get_num_tcs(struct qed_hwfn *p_hwfn)
+ {
+ return p_hwfn->hw_info.num_hw_tc;
+ }
+
+-u16 qed_init_qm_get_num_vfs(struct qed_hwfn *p_hwfn)
++static u16 qed_init_qm_get_num_vfs(struct qed_hwfn *p_hwfn)
+ {
+ return IS_QED_SRIOV(p_hwfn->cdev) ?
+ p_hwfn->cdev->p_iov_info->total_vfs : 0;
+@@ -243,7 +243,7 @@ u16 qed_init_qm_get_num_vfs(struct qed_h
+
+ #define NUM_DEFAULT_RLS 1
+
+-u16 qed_init_qm_get_num_pf_rls(struct qed_hwfn *p_hwfn)
++static u16 qed_init_qm_get_num_pf_rls(struct qed_hwfn *p_hwfn)
+ {
+ u16 num_pf_rls, num_vfs = qed_init_qm_get_num_vfs(p_hwfn);
+
+@@ -261,7 +261,7 @@ u16 qed_init_qm_get_num_pf_rls(struct qe
+ return num_pf_rls;
+ }
+
+-u16 qed_init_qm_get_num_vports(struct qed_hwfn *p_hwfn)
++static u16 qed_init_qm_get_num_vports(struct qed_hwfn *p_hwfn)
+ {
+ u32 pq_flags = qed_get_pq_flags(p_hwfn);
+
+@@ -273,7 +273,7 @@ u16 qed_init_qm_get_num_vports(struct qe
+ }
+
+ /* calc amount of PQs according to the requested flags */
+-u16 qed_init_qm_get_num_pqs(struct qed_hwfn *p_hwfn)
++static u16 qed_init_qm_get_num_pqs(struct qed_hwfn *p_hwfn)
+ {
+ u32 pq_flags = qed_get_pq_flags(p_hwfn);
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c
+@@ -873,8 +873,8 @@ static void qed_iscsi_release_connection
+ spin_unlock_bh(&p_hwfn->p_iscsi_info->lock);
+ }
+
+-void qed_iscsi_free_connection(struct qed_hwfn *p_hwfn,
+- struct qed_iscsi_conn *p_conn)
++static void qed_iscsi_free_connection(struct qed_hwfn *p_hwfn,
++ struct qed_iscsi_conn *p_conn)
+ {
+ qed_chain_free(p_hwfn->cdev, &p_conn->xhq);
+ qed_chain_free(p_hwfn->cdev, &p_conn->uhq);
+--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+@@ -377,7 +377,7 @@ qed_iwarp2roce_state(enum qed_iwarp_qp_s
+ }
+ }
+
+-const char *iwarp_state_names[] = {
++const static char *iwarp_state_names[] = {
+ "IDLE",
+ "RTS",
+ "TERMINATE",
+@@ -942,7 +942,7 @@ qed_iwarp_return_ep(struct qed_hwfn *p_h
+ spin_unlock_bh(&p_hwfn->p_rdma_info->iwarp.iw_lock);
+ }
+
+-void
++static void
+ qed_iwarp_parse_private_data(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
+ {
+ struct mpa_v2_hdr *mpa_v2_params;
+@@ -967,7 +967,7 @@ qed_iwarp_parse_private_data(struct qed_
+ mpa_data_size;
+ }
+
+-void
++static void
+ qed_iwarp_mpa_reply_arrived(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep *ep)
+ {
+ struct qed_iwarp_cm_event_params params;
+@@ -2500,7 +2500,7 @@ static void qed_iwarp_ll2_rel_tx_pkt(voi
+ /* The only slowpath for iwarp ll2 is unalign flush. When this completion
+ * is received, need to reset the FPDU.
+ */
+-void
++static void
+ qed_iwarp_ll2_slowpath(void *cxt,
+ u8 connection_handle,
+ u32 opaque_data_0, u32 opaque_data_1)
+@@ -2803,8 +2803,9 @@ int qed_iwarp_stop(struct qed_hwfn *p_hw
+ return qed_iwarp_ll2_stop(p_hwfn, p_ptt);
+ }
+
+-void qed_iwarp_qp_in_error(struct qed_hwfn *p_hwfn,
+- struct qed_iwarp_ep *ep, u8 fw_return_code)
++static void qed_iwarp_qp_in_error(struct qed_hwfn *p_hwfn,
++ struct qed_iwarp_ep *ep,
++ u8 fw_return_code)
+ {
+ struct qed_iwarp_cm_event_params params;
+
+@@ -2824,8 +2825,9 @@ void qed_iwarp_qp_in_error(struct qed_hw
+ ep->event_cb(ep->cb_context, &params);
+ }
+
+-void qed_iwarp_exception_received(struct qed_hwfn *p_hwfn,
+- struct qed_iwarp_ep *ep, int fw_ret_code)
++static void qed_iwarp_exception_received(struct qed_hwfn *p_hwfn,
++ struct qed_iwarp_ep *ep,
++ int fw_ret_code)
+ {
+ struct qed_iwarp_cm_event_params params;
+ bool event_cb = false;
+@@ -2954,7 +2956,7 @@ qed_iwarp_tcp_connect_unsuccessful(struc
+ }
+ }
+
+-void
++static void
+ qed_iwarp_connect_complete(struct qed_hwfn *p_hwfn,
+ struct qed_iwarp_ep *ep, u8 fw_return_code)
+ {
+--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+@@ -158,7 +158,8 @@ static void qed_ll2_kill_buffers(struct
+ qed_ll2_dealloc_buffer(cdev, buffer);
+ }
+
+-void qed_ll2b_complete_rx_packet(void *cxt, struct qed_ll2_comp_rx_data *data)
++static void qed_ll2b_complete_rx_packet(void *cxt,
++ struct qed_ll2_comp_rx_data *data)
+ {
+ struct qed_hwfn *p_hwfn = cxt;
+ struct qed_ll2_buffer *buffer = data->cookie;
+--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+@@ -570,12 +570,13 @@ int qed_mcp_cmd(struct qed_hwfn *p_hwfn,
+ return 0;
+ }
+
+-int qed_mcp_nvm_wr_cmd(struct qed_hwfn *p_hwfn,
+- struct qed_ptt *p_ptt,
+- u32 cmd,
+- u32 param,
+- u32 *o_mcp_resp,
+- u32 *o_mcp_param, u32 i_txn_size, u32 *i_buf)
++static int
++qed_mcp_nvm_wr_cmd(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt,
++ u32 cmd,
++ u32 param,
++ u32 *o_mcp_resp,
++ u32 *o_mcp_param, u32 i_txn_size, u32 *i_buf)
+ {
+ struct qed_mcp_mb_params mb_params;
+ int rc;
+@@ -3008,7 +3009,7 @@ static int qed_mcp_resource_cmd(struct q
+ return rc;
+ }
+
+-int
++static int
+ __qed_mcp_resc_lock(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ struct qed_resc_lock_params *p_params)
+--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+@@ -134,7 +134,7 @@ static bool qed_bmap_is_empty(struct qed
+ return bmap->max_count == find_first_bit(bmap->bitmap, bmap->max_count);
+ }
+
+-u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id)
++static u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id)
+ {
+ /* First sb id for RoCE is after all the l2 sb */
+ return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id;
+@@ -706,7 +706,7 @@ static int qed_rdma_setup(struct qed_hwf
+ return qed_rdma_start_fw(p_hwfn, params, p_ptt);
+ }
+
+-int qed_rdma_stop(void *rdma_cxt)
++static int qed_rdma_stop(void *rdma_cxt)
+ {
+ struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
+ struct rdma_close_func_ramrod_data *p_ramrod;
+--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c
+@@ -157,7 +157,7 @@ static enum roce_flavor qed_roce_mode_to
+ return flavor;
+ }
+
+-void qed_roce_free_cid_pair(struct qed_hwfn *p_hwfn, u16 cid)
++static void qed_roce_free_cid_pair(struct qed_hwfn *p_hwfn, u16 cid)
+ {
+ spin_lock_bh(&p_hwfn->p_rdma_info->lock);
+ qed_bmap_release_id(p_hwfn, &p_hwfn->p_rdma_info->cid_map, cid);
+--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+@@ -672,8 +672,8 @@ int qed_iov_hw_info(struct qed_hwfn *p_h
+ return 0;
+ }
+
+-bool _qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn,
+- int vfid, bool b_fail_malicious)
++static bool _qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn,
++ int vfid, bool b_fail_malicious)
+ {
+ /* Check PF supports sriov */
+ if (IS_VF(p_hwfn->cdev) || !IS_QED_SRIOV(p_hwfn->cdev) ||
+@@ -687,7 +687,7 @@ bool _qed_iov_pf_sanity_check(struct qed
+ return true;
+ }
+
+-bool qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn, int vfid)
++static bool qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn, int vfid)
+ {
+ return _qed_iov_pf_sanity_check(p_hwfn, vfid, true);
+ }
+@@ -3979,7 +3979,7 @@ static void qed_iov_process_mbx_req(stru
+ }
+ }
+
+-void qed_iov_pf_get_pending_events(struct qed_hwfn *p_hwfn, u64 *events)
++static void qed_iov_pf_get_pending_events(struct qed_hwfn *p_hwfn, u64 *events)
+ {
+ int i;
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_vf.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c
+@@ -169,7 +169,7 @@ static void qed_vf_pf_add_qid(struct qed
+ p_qid_tlv->qid = p_cid->qid_usage_idx;
+ }
+
+-int _qed_vf_pf_release(struct qed_hwfn *p_hwfn, bool b_final)
++static int _qed_vf_pf_release(struct qed_hwfn *p_hwfn, bool b_final)
+ {
+ struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
+ struct pfvf_def_resp_tlv *resp;
diff --git a/patches.drivers/qed-Utilize-FW-8.37.2.0.patch b/patches.drivers/qed-Utilize-FW-8.37.2.0.patch
new file mode 100644
index 0000000000..8b1807827f
--- /dev/null
+++ b/patches.drivers/qed-Utilize-FW-8.37.2.0.patch
@@ -0,0 +1,2340 @@
+From: Michal Kalderon <Michal.Kalderon@cavium.com>
+Date: Tue, 5 Jun 2018 13:11:16 +0300
+Subject: qed*: Utilize FW 8.37.2.0
+Patch-mainline: v4.18-rc1
+Git-commit: d52c89f120de849575f6b2e5948038f2be12ce6f
+References: bsc#1086314 FATE#324886
+
+This FW contains several fixes and features.
+
+RDMA
+- Several modifications and fixes for Memory Windows
+- drop vlan and tcp timestamp from mss calculation in driver for
+ this FW
+- Fix SQ completion flow when local ack timeout is infinite
+- Modifications in t10dif support
+
+ETH
+- Fix aRFS for tunneled traffic without inner IP.
+- Fix chip configuration which may fail under heavy traffic conditions.
+- Support receiving any-VNI in VXLAN and GENEVE RX classification.
+
+iSCSI / FcoE
+- Fix iSCSI recovery flow
+- Drop vlan and tcp timestamp from mss calc for fw 8.37.2.0
+
+Misc
+- Several registers (split registers) won't read correctly with
+ ethtool -d
+
+Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
+Signed-off-by: Manish Rangankar <manish.rangankar@cavium.com>
+Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/infiniband/hw/qedr/qedr_hsi_rdma.h | 139 ++---
+ drivers/infiniband/hw/qedr/verbs.c | 4
+ drivers/net/ethernet/qlogic/qed/qed_debug.c | 490 +++++++++++---------
+ drivers/net/ethernet/qlogic/qed/qed_dev.c | 2
+ drivers/net/ethernet/qlogic/qed/qed_hsi.h | 460 +++++++++++-------
+ drivers/net/ethernet/qlogic/qed/qed_hw.c | 20
+ drivers/net/ethernet/qlogic/qed/qed_hw.h | 12
+ drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c | 50 ++
+ drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 13
+ drivers/net/ethernet/qlogic/qed/qed_l2.c | 3
+ drivers/net/ethernet/qlogic/qed/qed_l2.h | 1
+ drivers/net/ethernet/qlogic/qed/qed_rdma.c | 8
+ drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 3
+ drivers/net/ethernet/qlogic/qed/qed_roce.c | 31 -
+ drivers/scsi/qedi/qedi_iscsi.c | 6
+ include/linux/qed/common_hsi.h | 4
+ include/linux/qed/iscsi_common.h | 8
+ include/linux/qed/qed_rdma_if.h | 4
+ include/linux/qed/roce_common.h | 1
+ 19 files changed, 725 insertions(+), 534 deletions(-)
+
+--- a/drivers/infiniband/hw/qedr/qedr_hsi_rdma.h
++++ b/drivers/infiniband/hw/qedr/qedr_hsi_rdma.h
+@@ -116,6 +116,7 @@ enum rdma_cqe_requester_status_enum {
+ RDMA_CQE_REQ_STS_TRANSPORT_RETRY_CNT_ERR,
+ RDMA_CQE_REQ_STS_WORK_REQUEST_FLUSHED_ERR,
+ RDMA_CQE_REQ_STS_XRC_VOILATION_ERR,
++ RDMA_CQE_REQ_STS_SIG_ERR,
+ MAX_RDMA_CQE_REQUESTER_STATUS_ENUM
+ };
+
+@@ -152,12 +153,12 @@ struct rdma_rq_sge {
+ struct regpair addr;
+ __le32 length;
+ __le32 flags;
+-#define RDMA_RQ_SGE_L_KEY_MASK 0x3FFFFFF
+-#define RDMA_RQ_SGE_L_KEY_SHIFT 0
++#define RDMA_RQ_SGE_L_KEY_LO_MASK 0x3FFFFFF
++#define RDMA_RQ_SGE_L_KEY_LO_SHIFT 0
+ #define RDMA_RQ_SGE_NUM_SGES_MASK 0x7
+ #define RDMA_RQ_SGE_NUM_SGES_SHIFT 26
+-#define RDMA_RQ_SGE_RESERVED0_MASK 0x7
+-#define RDMA_RQ_SGE_RESERVED0_SHIFT 29
++#define RDMA_RQ_SGE_L_KEY_HI_MASK 0x7
++#define RDMA_RQ_SGE_L_KEY_HI_SHIFT 29
+ };
+
+ struct rdma_srq_sge {
+@@ -241,18 +242,39 @@ enum rdma_dif_io_direction_flg {
+ MAX_RDMA_DIF_IO_DIRECTION_FLG
+ };
+
+-/* RDMA DIF Runt Result Structure */
+-struct rdma_dif_runt_result {
+- __le16 guard_tag;
+- __le16 reserved[3];
++struct rdma_dif_params {
++ __le32 base_ref_tag;
++ __le16 app_tag;
++ __le16 app_tag_mask;
++ __le16 runt_crc_value;
++ __le16 flags;
++#define RDMA_DIF_PARAMS_IO_DIRECTION_FLG_MASK 0x1
++#define RDMA_DIF_PARAMS_IO_DIRECTION_FLG_SHIFT 0
++#define RDMA_DIF_PARAMS_BLOCK_SIZE_MASK 0x1
++#define RDMA_DIF_PARAMS_BLOCK_SIZE_SHIFT 1
++#define RDMA_DIF_PARAMS_RUNT_VALID_FLG_MASK 0x1
++#define RDMA_DIF_PARAMS_RUNT_VALID_FLG_SHIFT 2
++#define RDMA_DIF_PARAMS_VALIDATE_CRC_GUARD_MASK 0x1
++#define RDMA_DIF_PARAMS_VALIDATE_CRC_GUARD_SHIFT 3
++#define RDMA_DIF_PARAMS_VALIDATE_REF_TAG_MASK 0x1
++#define RDMA_DIF_PARAMS_VALIDATE_REF_TAG_SHIFT 4
++#define RDMA_DIF_PARAMS_VALIDATE_APP_TAG_MASK 0x1
++#define RDMA_DIF_PARAMS_VALIDATE_APP_TAG_SHIFT 5
++#define RDMA_DIF_PARAMS_CRC_SEED_MASK 0x1
++#define RDMA_DIF_PARAMS_CRC_SEED_SHIFT 6
++#define RDMA_DIF_PARAMS_RX_REF_TAG_CONST_MASK 0x1
++#define RDMA_DIF_PARAMS_RX_REF_TAG_CONST_SHIFT 7
++#define RDMA_DIF_PARAMS_BLOCK_GUARD_TYPE_MASK 0x1
++#define RDMA_DIF_PARAMS_BLOCK_GUARD_TYPE_SHIFT 8
++#define RDMA_DIF_PARAMS_APP_ESCAPE_MASK 0x1
++#define RDMA_DIF_PARAMS_APP_ESCAPE_SHIFT 9
++#define RDMA_DIF_PARAMS_REF_ESCAPE_MASK 0x1
++#define RDMA_DIF_PARAMS_REF_ESCAPE_SHIFT 10
++#define RDMA_DIF_PARAMS_RESERVED4_MASK 0x1F
++#define RDMA_DIF_PARAMS_RESERVED4_SHIFT 11
++ __le32 reserved5;
+ };
+
+-/* Memory window type enumeration */
+-enum rdma_mw_type {
+- RDMA_MW_TYPE_1,
+- RDMA_MW_TYPE_2A,
+- MAX_RDMA_MW_TYPE
+-};
+
+ struct rdma_sq_atomic_wqe {
+ __le32 reserved1;
+@@ -334,17 +356,17 @@ struct rdma_sq_bind_wqe {
+ #define RDMA_SQ_BIND_WQE_SE_FLG_SHIFT 3
+ #define RDMA_SQ_BIND_WQE_INLINE_FLG_MASK 0x1
+ #define RDMA_SQ_BIND_WQE_INLINE_FLG_SHIFT 4
+-#define RDMA_SQ_BIND_WQE_RESERVED0_MASK 0x7
+-#define RDMA_SQ_BIND_WQE_RESERVED0_SHIFT 5
++#define RDMA_SQ_BIND_WQE_DIF_ON_HOST_FLG_MASK 0x1
++#define RDMA_SQ_BIND_WQE_DIF_ON_HOST_FLG_SHIFT 5
++#define RDMA_SQ_BIND_WQE_RESERVED0_MASK 0x3
++#define RDMA_SQ_BIND_WQE_RESERVED0_SHIFT 6
+ u8 wqe_size;
+ u8 prev_wqe_size;
+ u8 bind_ctrl;
+ #define RDMA_SQ_BIND_WQE_ZERO_BASED_MASK 0x1
+ #define RDMA_SQ_BIND_WQE_ZERO_BASED_SHIFT 0
+-#define RDMA_SQ_BIND_WQE_MW_TYPE_MASK 0x1
+-#define RDMA_SQ_BIND_WQE_MW_TYPE_SHIFT 1
+-#define RDMA_SQ_BIND_WQE_RESERVED1_MASK 0x3F
+-#define RDMA_SQ_BIND_WQE_RESERVED1_SHIFT 2
++#define RDMA_SQ_BIND_WQE_RESERVED1_MASK 0x7F
++#define RDMA_SQ_BIND_WQE_RESERVED1_SHIFT 1
+ u8 access_ctrl;
+ #define RDMA_SQ_BIND_WQE_REMOTE_READ_MASK 0x1
+ #define RDMA_SQ_BIND_WQE_REMOTE_READ_SHIFT 0
+@@ -363,6 +385,7 @@ struct rdma_sq_bind_wqe {
+ __le32 length_lo;
+ __le32 parent_l_key;
+ __le32 reserved4;
++ struct rdma_dif_params dif_params;
+ };
+
+ /* First element (16 bytes) of bind wqe */
+@@ -392,10 +415,8 @@ struct rdma_sq_bind_wqe_2nd {
+ u8 bind_ctrl;
+ #define RDMA_SQ_BIND_WQE_2ND_ZERO_BASED_MASK 0x1
+ #define RDMA_SQ_BIND_WQE_2ND_ZERO_BASED_SHIFT 0
+-#define RDMA_SQ_BIND_WQE_2ND_MW_TYPE_MASK 0x1
+-#define RDMA_SQ_BIND_WQE_2ND_MW_TYPE_SHIFT 1
+-#define RDMA_SQ_BIND_WQE_2ND_RESERVED1_MASK 0x3F
+-#define RDMA_SQ_BIND_WQE_2ND_RESERVED1_SHIFT 2
++#define RDMA_SQ_BIND_WQE_2ND_RESERVED1_MASK 0x7F
++#define RDMA_SQ_BIND_WQE_2ND_RESERVED1_SHIFT 1
+ u8 access_ctrl;
+ #define RDMA_SQ_BIND_WQE_2ND_REMOTE_READ_MASK 0x1
+ #define RDMA_SQ_BIND_WQE_2ND_REMOTE_READ_SHIFT 0
+@@ -416,6 +437,11 @@ struct rdma_sq_bind_wqe_2nd {
+ __le32 reserved4;
+ };
+
++/* Third element (16 bytes) of bind wqe */
++struct rdma_sq_bind_wqe_3rd {
++ struct rdma_dif_params dif_params;
++};
++
+ /* Structure with only the SQ WQE common
+ * fields. Size is of one SQ element (16B)
+ */
+@@ -486,30 +512,6 @@ struct rdma_sq_fmr_wqe {
+ u8 length_hi;
+ __le32 length_lo;
+ struct regpair pbl_addr;
+- __le32 dif_base_ref_tag;
+- __le16 dif_app_tag;
+- __le16 dif_app_tag_mask;
+- __le16 dif_runt_crc_value;
+- __le16 dif_flags;
+-#define RDMA_SQ_FMR_WQE_DIF_IO_DIRECTION_FLG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_IO_DIRECTION_FLG_SHIFT 0
+-#define RDMA_SQ_FMR_WQE_DIF_BLOCK_SIZE_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_BLOCK_SIZE_SHIFT 1
+-#define RDMA_SQ_FMR_WQE_DIF_RUNT_VALID_FLG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_RUNT_VALID_FLG_SHIFT 2
+-#define RDMA_SQ_FMR_WQE_DIF_VALIDATE_CRC_GUARD_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_VALIDATE_CRC_GUARD_SHIFT 3
+-#define RDMA_SQ_FMR_WQE_DIF_VALIDATE_REF_TAG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_VALIDATE_REF_TAG_SHIFT 4
+-#define RDMA_SQ_FMR_WQE_DIF_VALIDATE_APP_TAG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_VALIDATE_APP_TAG_SHIFT 5
+-#define RDMA_SQ_FMR_WQE_DIF_CRC_SEED_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_CRC_SEED_SHIFT 6
+-#define RDMA_SQ_FMR_WQE_DIF_RX_REF_TAG_CONST_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_DIF_RX_REF_TAG_CONST_SHIFT 7
+-#define RDMA_SQ_FMR_WQE_RESERVED4_MASK 0xFF
+-#define RDMA_SQ_FMR_WQE_RESERVED4_SHIFT 8
+- __le32 reserved5;
+ };
+
+ /* First element (16 bytes) of fmr wqe */
+@@ -566,33 +568,6 @@ struct rdma_sq_fmr_wqe_2nd {
+ struct regpair pbl_addr;
+ };
+
+-/* Third element (16 bytes) of fmr wqe */
+-struct rdma_sq_fmr_wqe_3rd {
+- __le32 dif_base_ref_tag;
+- __le16 dif_app_tag;
+- __le16 dif_app_tag_mask;
+- __le16 dif_runt_crc_value;
+- __le16 dif_flags;
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_IO_DIRECTION_FLG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_IO_DIRECTION_FLG_SHIFT 0
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_BLOCK_SIZE_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_BLOCK_SIZE_SHIFT 1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_RUNT_VALID_FLG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_RUNT_VALID_FLG_SHIFT 2
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_VALIDATE_CRC_GUARD_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_VALIDATE_CRC_GUARD_SHIFT 3
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_VALIDATE_REF_TAG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_VALIDATE_REF_TAG_SHIFT 4
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_VALIDATE_APP_TAG_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_VALIDATE_APP_TAG_SHIFT 5
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_CRC_SEED_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_CRC_SEED_SHIFT 6
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_RX_REF_TAG_CONST_MASK 0x1
+-#define RDMA_SQ_FMR_WQE_3RD_DIF_RX_REF_TAG_CONST_SHIFT 7
+-#define RDMA_SQ_FMR_WQE_3RD_RESERVED4_MASK 0xFF
+-#define RDMA_SQ_FMR_WQE_RESERVED4_SHIFT 8
+- __le32 reserved5;
+-};
+
+ struct rdma_sq_local_inv_wqe {
+ struct regpair reserved;
+@@ -637,8 +612,8 @@ struct rdma_sq_rdma_wqe {
+ #define RDMA_SQ_RDMA_WQE_DIF_ON_HOST_FLG_SHIFT 5
+ #define RDMA_SQ_RDMA_WQE_READ_INV_FLG_MASK 0x1
+ #define RDMA_SQ_RDMA_WQE_READ_INV_FLG_SHIFT 6
+-#define RDMA_SQ_RDMA_WQE_RESERVED0_MASK 0x1
+-#define RDMA_SQ_RDMA_WQE_RESERVED0_SHIFT 7
++#define RDMA_SQ_RDMA_WQE_RESERVED1_MASK 0x1
++#define RDMA_SQ_RDMA_WQE_RESERVED1_SHIFT 7
+ u8 wqe_size;
+ u8 prev_wqe_size;
+ struct regpair remote_va;
+@@ -646,13 +621,9 @@ struct rdma_sq_rdma_wqe {
+ u8 dif_flags;
+ #define RDMA_SQ_RDMA_WQE_DIF_BLOCK_SIZE_MASK 0x1
+ #define RDMA_SQ_RDMA_WQE_DIF_BLOCK_SIZE_SHIFT 0
+-#define RDMA_SQ_RDMA_WQE_DIF_FIRST_RDMA_IN_IO_FLG_MASK 0x1
+-#define RDMA_SQ_RDMA_WQE_DIF_FIRST_RDMA_IN_IO_FLG_SHIFT 1
+-#define RDMA_SQ_RDMA_WQE_DIF_LAST_RDMA_IN_IO_FLG_MASK 0x1
+-#define RDMA_SQ_RDMA_WQE_DIF_LAST_RDMA_IN_IO_FLG_SHIFT 2
+-#define RDMA_SQ_RDMA_WQE_RESERVED1_MASK 0x1F
+-#define RDMA_SQ_RDMA_WQE_RESERVED1_SHIFT 3
+- u8 reserved2[3];
++#define RDMA_SQ_RDMA_WQE_RESERVED2_MASK 0x7F
++#define RDMA_SQ_RDMA_WQE_RESERVED2_SHIFT 1
++ u8 reserved3[3];
+ };
+
+ /* First element (16 bytes) of rdma wqe */
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -3302,7 +3302,7 @@ int qedr_post_recv(struct ib_qp *ibqp, s
+ SET_FIELD(flags, RDMA_RQ_SGE_NUM_SGES,
+ wr->num_sge);
+
+- SET_FIELD(flags, RDMA_RQ_SGE_L_KEY,
++ SET_FIELD(flags, RDMA_RQ_SGE_L_KEY_LO,
+ wr->sg_list[i].lkey);
+
+ RQ_SGE_SET(rqe, wr->sg_list[i].addr,
+@@ -3321,7 +3321,7 @@ int qedr_post_recv(struct ib_qp *ibqp, s
+ /* First one must include the number
+ * of SGE in the list
+ */
+- SET_FIELD(flags, RDMA_RQ_SGE_L_KEY, 0);
++ SET_FIELD(flags, RDMA_RQ_SGE_L_KEY_LO, 0);
+ SET_FIELD(flags, RDMA_RQ_SGE_NUM_SGES, 1);
+
+ RQ_SGE_SET(rqe, 0, 0, flags);
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -183,16 +183,9 @@ enum platform_ids {
+ MAX_PLATFORM_IDS
+ };
+
+-struct chip_platform_defs {
+- u8 num_ports;
+- u8 num_pfs;
+- u8 num_vfs;
+-};
+-
+ /* Chip constant definitions */
+ struct chip_defs {
+ const char *name;
+- struct chip_platform_defs per_platform[MAX_PLATFORM_IDS];
+ };
+
+ /* Platform constant definitions */
+@@ -317,6 +310,11 @@ struct phy_defs {
+ u32 tbus_data_hi_addr;
+ };
+
++/* Split type definitions */
++struct split_type_defs {
++ const char *name;
++};
++
+ /******************************** Constants **********************************/
+
+ #define MAX_LCIDS 320
+@@ -469,21 +467,9 @@ static struct dbg_array s_dbg_arrays[MAX
+
+ /* Chip constant definitions array */
+ static struct chip_defs s_chip_defs[MAX_CHIP_IDS] = {
+- { "bb",
+- {{MAX_NUM_PORTS_BB, MAX_NUM_PFS_BB, MAX_NUM_VFS_BB},
+- {0, 0, 0},
+- {0, 0, 0},
+- {0, 0, 0} } },
+- { "ah",
+- {{MAX_NUM_PORTS_K2, MAX_NUM_PFS_K2, MAX_NUM_VFS_K2},
+- {0, 0, 0},
+- {0, 0, 0},
+- {0, 0, 0} } },
+- { "reserved",
+- {{0, 0, 0},
+- {0, 0, 0},
+- {0, 0, 0},
+- {0, 0, 0} } }
++ {"bb"},
++ {"ah"},
++ {"reserved"},
+ };
+
+ /* Storm constant definitions array */
+@@ -1588,7 +1574,7 @@ static struct grc_param_defs s_grc_param
+ {{0, 0, 0}, 0, 1, false, false, 0, 1},
+
+ /* DBG_GRC_PARAM_DUMP_BMB */
+- {{0, 0, 0}, 0, 1, false, false, 0, 1},
++ {{0, 0, 0}, 0, 1, false, false, 0, 0},
+
+ /* DBG_GRC_PARAM_DUMP_NIG */
+ {{1, 1, 1}, 0, 1, false, false, 0, 1},
+@@ -1745,6 +1731,23 @@ static struct phy_defs s_phy_defs[] = {
+ PHY_PCIE_IP_REG_AHB_CMU_CSR_0_X131_K2_E5},
+ };
+
++static struct split_type_defs s_split_type_defs[] = {
++ /* SPLIT_TYPE_NONE */
++ {"eng"},
++
++ /* SPLIT_TYPE_PORT */
++ {"port"},
++
++ /* SPLIT_TYPE_PF */
++ {"pf"},
++
++ /* SPLIT_TYPE_PORT_PF */
++ {"port"},
++
++ /* SPLIT_TYPE_VF */
++ {"vf"}
++};
++
+ /**************************** Private Functions ******************************/
+
+ /* Reads and returns a single dword from the specified unaligned buffer */
+@@ -1781,28 +1784,68 @@ static enum dbg_status qed_dbg_dev_init(
+ struct qed_ptt *p_ptt)
+ {
+ struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
++ u8 num_pfs = 0, max_pfs_per_port = 0;
+
+ if (dev_data->initialized)
+ return DBG_STATUS_OK;
+
++ /* Set chip */
+ if (QED_IS_K2(p_hwfn->cdev)) {
+ dev_data->chip_id = CHIP_K2;
+ dev_data->mode_enable[MODE_K2] = 1;
++ dev_data->num_vfs = MAX_NUM_VFS_K2;
++ num_pfs = MAX_NUM_PFS_K2;
++ max_pfs_per_port = MAX_NUM_PFS_K2 / 2;
+ } else if (QED_IS_BB_B0(p_hwfn->cdev)) {
+ dev_data->chip_id = CHIP_BB;
+ dev_data->mode_enable[MODE_BB] = 1;
++ dev_data->num_vfs = MAX_NUM_VFS_BB;
++ num_pfs = MAX_NUM_PFS_BB;
++ max_pfs_per_port = MAX_NUM_PFS_BB;
+ } else {
+ return DBG_STATUS_UNKNOWN_CHIP;
+ }
+
++ /* Set platofrm */
+ dev_data->platform_id = PLATFORM_ASIC;
+ dev_data->mode_enable[MODE_ASIC] = 1;
+
++ /* Set port mode */
++ switch (qed_rd(p_hwfn, p_ptt, MISC_REG_PORT_MODE)) {
++ case 0:
++ dev_data->mode_enable[MODE_PORTS_PER_ENG_1] = 1;
++ break;
++ case 1:
++ dev_data->mode_enable[MODE_PORTS_PER_ENG_2] = 1;
++ break;
++ case 2:
++ dev_data->mode_enable[MODE_PORTS_PER_ENG_4] = 1;
++ break;
++ }
++
++ /* Set 100G mode */
++ if (dev_data->chip_id == CHIP_BB &&
++ qed_rd(p_hwfn, p_ptt, CNIG_REG_NW_PORT_MODE_BB) == 2)
++ dev_data->mode_enable[MODE_100G] = 1;
++
++ /* Set number of ports */
++ if (dev_data->mode_enable[MODE_PORTS_PER_ENG_1] ||
++ dev_data->mode_enable[MODE_100G])
++ dev_data->num_ports = 1;
++ else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_2])
++ dev_data->num_ports = 2;
++ else if (dev_data->mode_enable[MODE_PORTS_PER_ENG_4])
++ dev_data->num_ports = 4;
++
++ /* Set number of PFs per port */
++ dev_data->num_pfs_per_port = min_t(u32,
++ num_pfs / dev_data->num_ports,
++ max_pfs_per_port);
++
+ /* Initializes the GRC parameters */
+ qed_dbg_grc_init_params(p_hwfn);
+
+ dev_data->use_dmae = true;
+- dev_data->num_regs_read = 0;
+ dev_data->initialized = 1;
+
+ return DBG_STATUS_OK;
+@@ -1821,9 +1864,9 @@ static struct dbg_bus_block *get_dbg_bus
+ /* Reads the FW info structure for the specified Storm from the chip,
+ * and writes it to the specified fw_info pointer.
+ */
+-static void qed_read_fw_info(struct qed_hwfn *p_hwfn,
+- struct qed_ptt *p_ptt,
+- u8 storm_id, struct fw_info *fw_info)
++static void qed_read_storm_fw_info(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt,
++ u8 storm_id, struct fw_info *fw_info)
+ {
+ struct storm_defs *storm = &s_storm_defs[storm_id];
+ struct fw_info_location fw_info_location;
+@@ -1945,45 +1988,29 @@ static u32 qed_dump_fw_ver_param(struct
+ struct qed_ptt *p_ptt,
+ u32 *dump_buf, bool dump)
+ {
+- struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
+ char fw_ver_str[16] = EMPTY_FW_VERSION_STR;
+ char fw_img_str[16] = EMPTY_FW_IMAGE_STR;
+ struct fw_info fw_info = { {0}, {0} };
+ u32 offset = 0;
+
+ if (dump && !qed_grc_get_param(p_hwfn, DBG_GRC_PARAM_NO_FW_VER)) {
+- /* Read FW image/version from PRAM in a non-reset SEMI */
+- bool found = false;
+- u8 storm_id;
+-
+- for (storm_id = 0; storm_id < MAX_DBG_STORMS && !found;
+- storm_id++) {
+- struct storm_defs *storm = &s_storm_defs[storm_id];
++ /* Read FW info from chip */
++ qed_read_fw_info(p_hwfn, p_ptt, &fw_info);
+
+- /* Read FW version/image */
+- if (dev_data->block_in_reset[storm->block_id])
+- continue;
+-
+- /* Read FW info for the current Storm */
+- qed_read_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
+-
+- /* Create FW version/image strings */
+- if (snprintf(fw_ver_str, sizeof(fw_ver_str),
+- "%d_%d_%d_%d", fw_info.ver.num.major,
+- fw_info.ver.num.minor, fw_info.ver.num.rev,
+- fw_info.ver.num.eng) < 0)
+- DP_NOTICE(p_hwfn,
+- "Unexpected debug error: invalid FW version string\n");
+- switch (fw_info.ver.image_id) {
+- case FW_IMG_MAIN:
+- strcpy(fw_img_str, "main");
+- break;
+- default:
+- strcpy(fw_img_str, "unknown");
+- break;
+- }
+-
+- found = true;
++ /* Create FW version/image strings */
++ if (snprintf(fw_ver_str, sizeof(fw_ver_str),
++ "%d_%d_%d_%d", fw_info.ver.num.major,
++ fw_info.ver.num.minor, fw_info.ver.num.rev,
++ fw_info.ver.num.eng) < 0)
++ DP_NOTICE(p_hwfn,
++ "Unexpected debug error: invalid FW version string\n");
++ switch (fw_info.ver.image_id) {
++ case FW_IMG_MAIN:
++ strcpy(fw_img_str, "main");
++ break;
++ default:
++ strcpy(fw_img_str, "unknown");
++ break;
+ }
+ }
+
+@@ -2412,20 +2439,21 @@ static void qed_grc_clear_all_prty(struc
+
+ /* Dumps GRC registers section header. Returns the dumped size in dwords.
+ * The following parameters are dumped:
+- * - count: no. of dumped entries
+- * - split: split type
+- * - id: split ID (dumped only if split_id >= 0)
++ * - count: no. of dumped entries
++ * - split_type: split type
++ * - split_id: split ID (dumped only if split_id != SPLIT_TYPE_NONE)
+ * - param_name: user parameter value (dumped only if param_name != NULL
+ * and param_val != NULL).
+ */
+ static u32 qed_grc_dump_regs_hdr(u32 *dump_buf,
+ bool dump,
+ u32 num_reg_entries,
+- const char *split_type,
+- int split_id,
++ enum init_split_types split_type,
++ u8 split_id,
+ const char *param_name, const char *param_val)
+ {
+- u8 num_params = 2 + (split_id >= 0 ? 1 : 0) + (param_name ? 1 : 0);
++ u8 num_params = 2 +
++ (split_type != SPLIT_TYPE_NONE ? 1 : 0) + (param_name ? 1 : 0);
+ u32 offset = 0;
+
+ offset += qed_dump_section_hdr(dump_buf + offset,
+@@ -2433,8 +2461,9 @@ static u32 qed_grc_dump_regs_hdr(u32 *du
+ offset += qed_dump_num_param(dump_buf + offset,
+ dump, "count", num_reg_entries);
+ offset += qed_dump_str_param(dump_buf + offset,
+- dump, "split", split_type);
+- if (split_id >= 0)
++ dump, "split",
++ s_split_type_defs[split_type].name);
++ if (split_type != SPLIT_TYPE_NONE)
+ offset += qed_dump_num_param(dump_buf + offset,
+ dump, "id", split_id);
+ if (param_name && param_val)
+@@ -2463,9 +2492,12 @@ void qed_read_regs(struct qed_hwfn *p_hw
+ static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u32 *dump_buf,
+- bool dump, u32 addr, u32 len, bool wide_bus)
++ bool dump, u32 addr, u32 len, bool wide_bus,
++ enum init_split_types split_type,
++ u8 split_id)
+ {
+ struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
++ u8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;
+
+ if (!dump)
+ return len;
+@@ -2481,8 +2513,27 @@ static u32 qed_grc_dump_addr_range(struc
+ dev_data->num_regs_read = 0;
+ }
+
++ switch (split_type) {
++ case SPLIT_TYPE_PORT:
++ port_id = split_id;
++ break;
++ case SPLIT_TYPE_PF:
++ pf_id = split_id;
++ break;
++ case SPLIT_TYPE_PORT_PF:
++ port_id = split_id / dev_data->num_pfs_per_port;
++ pf_id = port_id + dev_data->num_ports *
++ (split_id % dev_data->num_pfs_per_port);
++ break;
++ case SPLIT_TYPE_VF:
++ vf_id = split_id;
++ break;
++ default:
++ break;
++ }
++
+ /* Try reading using DMAE */
+- if (dev_data->use_dmae &&
++ if (dev_data->use_dmae && split_type == SPLIT_TYPE_NONE &&
+ (len >= s_platform_defs[dev_data->platform_id].dmae_thresh ||
+ wide_bus)) {
+ if (!qed_dmae_grc2host(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr),
+@@ -2494,7 +2545,37 @@ static u32 qed_grc_dump_addr_range(struc
+ "Failed reading from chip using DMAE, using GRC instead\n");
+ }
+
+- /* Read registers */
++ /* If not read using DMAE, read using GRC */
++
++ /* Set pretend */
++ if (split_type != dev_data->pretend.split_type || split_id !=
++ dev_data->pretend.split_id) {
++ switch (split_type) {
++ case SPLIT_TYPE_PORT:
++ qed_port_pretend(p_hwfn, p_ptt, port_id);
++ break;
++ case SPLIT_TYPE_PF:
++ fid = pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
++ qed_fid_pretend(p_hwfn, p_ptt, fid);
++ break;
++ case SPLIT_TYPE_PORT_PF:
++ fid = pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
++ qed_port_fid_pretend(p_hwfn, p_ptt, port_id, fid);
++ break;
++ case SPLIT_TYPE_VF:
++ fid = BIT(PXP_PRETEND_CONCRETE_FID_VFVALID_SHIFT) |
++ (vf_id << PXP_PRETEND_CONCRETE_FID_VFID_SHIFT);
++ qed_fid_pretend(p_hwfn, p_ptt, fid);
++ break;
++ default:
++ break;
++ }
++
++ dev_data->pretend.split_type = (u8)split_type;
++ dev_data->pretend.split_id = split_id;
++ }
++
++ /* Read registers using GRC */
+ qed_read_regs(p_hwfn, p_ptt, dump_buf, addr, len);
+
+ return len;
+@@ -2518,7 +2599,8 @@ static u32 qed_grc_dump_reg_entry_hdr(u3
+ static u32 qed_grc_dump_reg_entry(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u32 *dump_buf,
+- bool dump, u32 addr, u32 len, bool wide_bus)
++ bool dump, u32 addr, u32 len, bool wide_bus,
++ enum init_split_types split_type, u8 split_id)
+ {
+ u32 offset = 0;
+
+@@ -2526,7 +2608,8 @@ static u32 qed_grc_dump_reg_entry(struct
+ offset += qed_grc_dump_addr_range(p_hwfn,
+ p_ptt,
+ dump_buf + offset,
+- dump, addr, len, wide_bus);
++ dump, addr, len, wide_bus,
++ split_type, split_id);
+
+ return offset;
+ }
+@@ -2559,7 +2642,8 @@ static u32 qed_grc_dump_reg_entry_skip(s
+ offset += qed_grc_dump_addr_range(p_hwfn,
+ p_ptt,
+ dump_buf + offset,
+- dump, addr, curr_len, false);
++ dump, addr, curr_len, false,
++ SPLIT_TYPE_NONE, 0);
+ reg_offset += curr_len;
+ addr += curr_len;
+
+@@ -2581,6 +2665,8 @@ static u32 qed_grc_dump_regs_entries(str
+ struct dbg_array input_regs_arr,
+ u32 *dump_buf,
+ bool dump,
++ enum init_split_types split_type,
++ u8 split_id,
+ bool block_enable[MAX_BLOCK_ID],
+ u32 *num_dumped_reg_entries)
+ {
+@@ -2628,7 +2714,8 @@ static u32 qed_grc_dump_regs_entries(str
+ dump,
+ addr,
+ len,
+- wide_bus);
++ wide_bus,
++ split_type, split_id);
+ (*num_dumped_reg_entries)++;
+ }
+ }
+@@ -2643,19 +2730,28 @@ static u32 qed_grc_dump_split_data(struc
+ u32 *dump_buf,
+ bool dump,
+ bool block_enable[MAX_BLOCK_ID],
+- const char *split_type_name,
+- u32 split_id,
++ enum init_split_types split_type,
++ u8 split_id,
+ const char *param_name,
+ const char *param_val)
+ {
++ struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
++ enum init_split_types hdr_split_type = split_type;
+ u32 num_dumped_reg_entries, offset;
++ u8 hdr_split_id = split_id;
++
++ /* In PORT_PF split type, print a port split header */
++ if (split_type == SPLIT_TYPE_PORT_PF) {
++ hdr_split_type = SPLIT_TYPE_PORT;
++ hdr_split_id = split_id / dev_data->num_pfs_per_port;
++ }
+
+ /* Calculate register dump header size (and skip it for now) */
+ offset = qed_grc_dump_regs_hdr(dump_buf,
+ false,
+ 0,
+- split_type_name,
+- split_id, param_name, param_val);
++ hdr_split_type,
++ hdr_split_id, param_name, param_val);
+
+ /* Dump registers */
+ offset += qed_grc_dump_regs_entries(p_hwfn,
+@@ -2663,6 +2759,8 @@ static u32 qed_grc_dump_split_data(struc
+ input_regs_arr,
+ dump_buf + offset,
+ dump,
++ split_type,
++ split_id,
+ block_enable,
+ &num_dumped_reg_entries);
+
+@@ -2671,8 +2769,8 @@ static u32 qed_grc_dump_split_data(struc
+ qed_grc_dump_regs_hdr(dump_buf,
+ dump,
+ num_dumped_reg_entries,
+- split_type_name,
+- split_id, param_name, param_val);
++ hdr_split_type,
++ hdr_split_id, param_name, param_val);
+
+ return num_dumped_reg_entries > 0 ? offset : 0;
+ }
+@@ -2688,26 +2786,21 @@ static u32 qed_grc_dump_registers(struct
+ const char *param_name, const char *param_val)
+ {
+ struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
+- struct chip_platform_defs *chip_platform;
+ u32 offset = 0, input_offset = 0;
+- struct chip_defs *chip;
+- u8 port_id, pf_id, vf_id;
+ u16 fid;
+-
+- chip = &s_chip_defs[dev_data->chip_id];
+- chip_platform = &chip->per_platform[dev_data->platform_id];
+-
+ while (input_offset <
+ s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].size_in_dwords) {
+ const struct dbg_dump_split_hdr *split_hdr;
+ struct dbg_array curr_input_regs_arr;
++ enum init_split_types split_type;
++ u16 split_count = 0;
+ u32 split_data_size;
+- u8 split_type_id;
++ u8 split_id;
+
+ split_hdr =
+ (const struct dbg_dump_split_hdr *)
+ &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset++];
+- split_type_id =
++ split_type =
+ GET_FIELD(split_hdr->hdr,
+ DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
+ split_data_size =
+@@ -2717,99 +2810,44 @@ static u32 qed_grc_dump_registers(struct
+ &s_dbg_arrays[BIN_BUF_DBG_DUMP_REG].ptr[input_offset];
+ curr_input_regs_arr.size_in_dwords = split_data_size;
+
+- switch (split_type_id) {
++ switch (split_type) {
+ case SPLIT_TYPE_NONE:
+- offset += qed_grc_dump_split_data(p_hwfn,
+- p_ptt,
+- curr_input_regs_arr,
+- dump_buf + offset,
+- dump,
+- block_enable,
+- "eng",
+- (u32)(-1),
+- param_name,
+- param_val);
++ split_count = 1;
+ break;
+-
+ case SPLIT_TYPE_PORT:
+- for (port_id = 0; port_id < chip_platform->num_ports;
+- port_id++) {
+- if (dump)
+- qed_port_pretend(p_hwfn, p_ptt,
+- port_id);
+- offset +=
+- qed_grc_dump_split_data(p_hwfn, p_ptt,
+- curr_input_regs_arr,
+- dump_buf + offset,
+- dump, block_enable,
+- "port", port_id,
+- param_name,
+- param_val);
+- }
++ split_count = dev_data->num_ports;
+ break;
+-
+ case SPLIT_TYPE_PF:
+ case SPLIT_TYPE_PORT_PF:
+- for (pf_id = 0; pf_id < chip_platform->num_pfs;
+- pf_id++) {
+- u8 pfid_shift =
+- PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
+-
+- if (dump) {
+- fid = pf_id << pfid_shift;
+- qed_fid_pretend(p_hwfn, p_ptt, fid);
+- }
+-
+- offset +=
+- qed_grc_dump_split_data(p_hwfn,
+- p_ptt,
+- curr_input_regs_arr,
+- dump_buf + offset,
+- dump,
+- block_enable,
+- "pf",
+- pf_id,
+- param_name,
+- param_val);
+- }
++ split_count = dev_data->num_ports *
++ dev_data->num_pfs_per_port;
+ break;
+-
+ case SPLIT_TYPE_VF:
+- for (vf_id = 0; vf_id < chip_platform->num_vfs;
+- vf_id++) {
+- u8 vfvalid_shift =
+- PXP_PRETEND_CONCRETE_FID_VFVALID_SHIFT;
+- u8 vfid_shift =
+- PXP_PRETEND_CONCRETE_FID_VFID_SHIFT;
+-
+- if (dump) {
+- fid = BIT(vfvalid_shift) |
+- (vf_id << vfid_shift);
+- qed_fid_pretend(p_hwfn, p_ptt, fid);
+- }
+-
+- offset +=
+- qed_grc_dump_split_data(p_hwfn, p_ptt,
+- curr_input_regs_arr,
+- dump_buf + offset,
+- dump, block_enable,
+- "vf", vf_id,
+- param_name,
+- param_val);
+- }
++ split_count = dev_data->num_vfs;
+ break;
+-
+ default:
+- break;
++ return 0;
+ }
+
++ for (split_id = 0; split_id < split_count; split_id++)
++ offset += qed_grc_dump_split_data(p_hwfn, p_ptt,
++ curr_input_regs_arr,
++ dump_buf + offset,
++ dump, block_enable,
++ split_type,
++ split_id,
++ param_name,
++ param_val);
++
+ input_offset += split_data_size;
+ }
+
+- /* Pretend to original PF */
++ /* Cancel pretends (pretend to original PF) */
+ if (dump) {
+ fid = p_hwfn->rel_pf_id << PXP_PRETEND_CONCRETE_FID_PFID_SHIFT;
+ qed_fid_pretend(p_hwfn, p_ptt, fid);
++ dev_data->pretend.split_type = SPLIT_TYPE_NONE;
++ dev_data->pretend.split_id = 0;
+ }
+
+ return offset;
+@@ -2825,7 +2863,8 @@ static u32 qed_grc_dump_reset_regs(struc
+
+ /* Calculate header size */
+ offset += qed_grc_dump_regs_hdr(dump_buf,
+- false, 0, "eng", -1, NULL, NULL);
++ false, 0,
++ SPLIT_TYPE_NONE, 0, NULL, NULL);
+
+ /* Write reset registers */
+ for (i = 0; i < MAX_DBG_RESET_REGS; i++) {
+@@ -2838,14 +2877,15 @@ static u32 qed_grc_dump_reset_regs(struc
+ dump,
+ BYTES_TO_DWORDS
+ (s_reset_regs_defs[i].addr), 1,
+- false);
++ false, SPLIT_TYPE_NONE, 0);
+ num_regs++;
+ }
+
+ /* Write header */
+ if (dump)
+ qed_grc_dump_regs_hdr(dump_buf,
+- true, num_regs, "eng", -1, NULL, NULL);
++ true, num_regs, SPLIT_TYPE_NONE,
++ 0, NULL, NULL);
+
+ return offset;
+ }
+@@ -2864,7 +2904,8 @@ static u32 qed_grc_dump_modified_regs(st
+
+ /* Calculate header size */
+ offset += qed_grc_dump_regs_hdr(dump_buf,
+- false, 0, "eng", -1, NULL, NULL);
++ false, 0, SPLIT_TYPE_NONE,
++ 0, NULL, NULL);
+
+ /* Write parity registers */
+ for (block_id = 0; block_id < MAX_BLOCK_ID; block_id++) {
+@@ -2899,7 +2940,8 @@ static u32 qed_grc_dump_modified_regs(st
+ dump_buf + offset,
+ dump,
+ addr,
+- 1, false);
++ 1, false,
++ SPLIT_TYPE_NONE, 0);
+ addr = GET_FIELD(reg_data->data,
+ DBG_ATTN_REG_STS_ADDRESS);
+ offset += qed_grc_dump_reg_entry(p_hwfn,
+@@ -2907,7 +2949,8 @@ static u32 qed_grc_dump_modified_regs(st
+ dump_buf + offset,
+ dump,
+ addr,
+- 1, false);
++ 1, false,
++ SPLIT_TYPE_NONE, 0);
+ num_reg_entries += 2;
+ }
+ }
+@@ -2929,7 +2972,7 @@ static u32 qed_grc_dump_modified_regs(st
+ dump,
+ addr,
+ 1,
+- false);
++ false, SPLIT_TYPE_NONE, 0);
+ num_reg_entries++;
+ }
+
+@@ -2937,7 +2980,8 @@ static u32 qed_grc_dump_modified_regs(st
+ if (dump)
+ qed_grc_dump_regs_hdr(dump_buf,
+ true,
+- num_reg_entries, "eng", -1, NULL, NULL);
++ num_reg_entries, SPLIT_TYPE_NONE,
++ 0, NULL, NULL);
+
+ return offset;
+ }
+@@ -2950,7 +2994,8 @@ static u32 qed_grc_dump_special_regs(str
+ u32 offset = 0, addr;
+
+ offset += qed_grc_dump_regs_hdr(dump_buf,
+- dump, 2, "eng", -1, NULL, NULL);
++ dump, 2, SPLIT_TYPE_NONE, 0,
++ NULL, NULL);
+
+ /* Dump R/TDIF_REG_DEBUG_ERROR_INFO_SIZE (every 8'th register should be
+ * skipped).
+@@ -3096,7 +3141,8 @@ static u32 qed_grc_dump_mem(struct qed_h
+ offset += qed_grc_dump_addr_range(p_hwfn,
+ p_ptt,
+ dump_buf + offset,
+- dump, addr, len, wide_bus);
++ dump, addr, len, wide_bus,
++ SPLIT_TYPE_NONE, 0);
+
+ return offset;
+ }
+@@ -3235,12 +3281,12 @@ static u32 qed_grc_dump_memories(struct
+ s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].size_in_dwords) {
+ const struct dbg_dump_split_hdr *split_hdr;
+ struct dbg_array curr_input_mems_arr;
++ enum init_split_types split_type;
+ u32 split_data_size;
+- u8 split_type_id;
+
+ split_hdr = (const struct dbg_dump_split_hdr *)
+ &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset++];
+- split_type_id =
++ split_type =
+ GET_FIELD(split_hdr->hdr,
+ DBG_DUMP_SPLIT_HDR_SPLIT_TYPE_ID);
+ split_data_size =
+@@ -3250,20 +3296,15 @@ static u32 qed_grc_dump_memories(struct
+ &s_dbg_arrays[BIN_BUF_DBG_DUMP_MEM].ptr[input_offset];
+ curr_input_mems_arr.size_in_dwords = split_data_size;
+
+- switch (split_type_id) {
+- case SPLIT_TYPE_NONE:
++ if (split_type == SPLIT_TYPE_NONE)
+ offset += qed_grc_dump_mem_entries(p_hwfn,
+ p_ptt,
+ curr_input_mems_arr,
+ dump_buf + offset,
+ dump);
+- break;
+-
+- default:
++ else
+ DP_NOTICE(p_hwfn,
+ "Dumping split memories is currently not supported\n");
+- break;
+- }
+
+ input_offset += split_data_size;
+ }
+@@ -3623,7 +3664,8 @@ static u32 qed_grc_dump_rss(struct qed_h
+ dump,
+ addr,
+ num_dwords_to_read,
+- false);
++ false,
++ SPLIT_TYPE_NONE, 0);
+ total_dwords -= num_dwords_to_read;
+ rss_addr++;
+ }
+@@ -3682,7 +3724,7 @@ static u32 qed_grc_dump_big_ram(struct q
+ dump,
+ addr,
+ len,
+- false);
++ false, SPLIT_TYPE_NONE, 0);
+ }
+
+ return offset;
+@@ -3731,7 +3773,8 @@ static u32 qed_grc_dump_mcp(struct qed_h
+
+ /* Dump required non-MCP registers */
+ offset += qed_grc_dump_regs_hdr(dump_buf + offset,
+- dump, 1, "eng", -1, "block", "MCP");
++ dump, 1, SPLIT_TYPE_NONE, 0,
++ "block", "MCP");
+ addr = BYTES_TO_DWORDS(MISC_REG_SHARED_MEM_ADDR);
+ offset += qed_grc_dump_reg_entry(p_hwfn,
+ p_ptt,
+@@ -3739,7 +3782,7 @@ static u32 qed_grc_dump_mcp(struct qed_h
+ dump,
+ addr,
+ 1,
+- false);
++ false, SPLIT_TYPE_NONE, 0);
+
+ /* Release MCP */
+ if (halted && qed_mcp_resume(p_hwfn, p_ptt))
+@@ -3923,7 +3966,8 @@ static u32 qed_grc_dump_static_debug(str
+ dump,
+ addr,
+ len,
+- true);
++ true, SPLIT_TYPE_NONE,
++ 0);
+ }
+
+ /* Disable block's client and debug output */
+@@ -3949,28 +3993,15 @@ static enum dbg_status qed_grc_dump(stru
+ {
+ struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
+ bool parities_masked = false;
+- u8 i, port_mode = 0;
+ u32 offset = 0;
++ u8 i;
+
+ *num_dumped_dwords = 0;
++ dev_data->num_regs_read = 0;
+
+- if (dump) {
+- /* Find port mode */
+- switch (qed_rd(p_hwfn, p_ptt, MISC_REG_PORT_MODE)) {
+- case 0:
+- port_mode = 1;
+- break;
+- case 1:
+- port_mode = 2;
+- break;
+- case 2:
+- port_mode = 4;
+- break;
+- }
+-
+- /* Update reset state */
++ /* Update reset state */
++ if (dump)
+ qed_update_blocks_reset_state(p_hwfn, p_ptt);
+- }
+
+ /* Dump global params */
+ offset += qed_dump_common_global_params(p_hwfn,
+@@ -3989,7 +4020,7 @@ static enum dbg_status qed_grc_dump(stru
+ qed_grc_get_param(p_hwfn,
+ DBG_GRC_PARAM_NUM_LTIDS));
+ offset += qed_dump_num_param(dump_buf + offset,
+- dump, "num-ports", port_mode);
++ dump, "num-ports", dev_data->num_ports);
+
+ /* Dump reset registers (dumped before taking blocks out of reset ) */
+ if (qed_grc_is_included(p_hwfn, DBG_GRC_PARAM_DUMP_REGS))
+@@ -4093,10 +4124,10 @@ static enum dbg_status qed_grc_dump(stru
+ offset += qed_grc_dump_phy(p_hwfn,
+ p_ptt, dump_buf + offset, dump);
+
+- /* Dump static debug data */
++ /* Dump static debug data (only if not during debug bus recording) */
+ if (qed_grc_is_included(p_hwfn,
+ DBG_GRC_PARAM_DUMP_STATIC) &&
+- dev_data->bus.state == DBG_BUS_STATE_IDLE)
++ (!dump || dev_data->bus.state == DBG_BUS_STATE_IDLE))
+ offset += qed_grc_dump_static_debug(p_hwfn,
+ p_ptt,
+ dump_buf + offset, dump);
+@@ -4250,7 +4281,8 @@ static u32 qed_idle_chk_dump_failure(str
+ dump_buf + offset,
+ dump,
+ addr,
+- reg->size, wide_bus);
++ reg->size, wide_bus,
++ SPLIT_TYPE_NONE, 0);
+ }
+ }
+
+@@ -4373,7 +4405,8 @@ qed_idle_chk_dump_rule_entries(struct qe
+ next_reg_offset,
+ dump, addr,
+ reg->entry_size,
+- wide_bus);
++ wide_bus,
++ SPLIT_TYPE_NONE, 0);
+ }
+
+ /* Call rule condition function.
+@@ -4723,7 +4756,8 @@ static enum dbg_status qed_mcp_trace_dum
+ dump_buf + offset,
+ dump,
+ BYTES_TO_DWORDS(trace_data_grc_addr),
+- trace_data_size_dwords, false);
++ trace_data_size_dwords, false,
++ SPLIT_TYPE_NONE, 0);
+
+ /* Resume MCP (only if halt succeeded) */
+ if (halted && qed_mcp_resume(p_hwfn, p_ptt))
+@@ -4829,7 +4863,8 @@ static enum dbg_status qed_reg_fifo_dump
+ true,
+ addr,
+ len,
+- true);
++ true, SPLIT_TYPE_NONE,
++ 0);
+ fifo_has_data = qed_rd(p_hwfn, p_ptt,
+ GRC_REG_TRACE_FIFO_VALID_DATA) > 0;
+ }
+@@ -4898,7 +4933,8 @@ static enum dbg_status qed_igu_fifo_dump
+ true,
+ addr,
+ len,
+- true);
++ true, SPLIT_TYPE_NONE,
++ 0);
+ fifo_has_data = qed_rd(p_hwfn, p_ptt,
+ IGU_REG_ERROR_HANDLING_DATA_VALID) > 0;
+ }
+@@ -4956,7 +4992,7 @@ static enum dbg_status qed_protection_ov
+ true,
+ addr,
+ override_window_dwords,
+- true);
++ true, SPLIT_TYPE_NONE, 0);
+ qed_dump_num_param(dump_buf + size_param_offset, dump, "size",
+ override_window_dwords);
+ out:
+@@ -4998,7 +5034,7 @@ static u32 qed_fw_asserts_dump(struct qe
+ continue;
+
+ /* Read FW info for the current Storm */
+- qed_read_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
++ qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, &fw_info);
+
+ asserts = &fw_info.fw_asserts_section;
+
+@@ -5036,7 +5072,7 @@ static u32 qed_fw_asserts_dump(struct qe
+ dump_buf + offset,
+ dump, addr,
+ asserts->list_element_dword_size,
+- false);
++ false, SPLIT_TYPE_NONE, 0);
+ }
+
+ /* Dump last section */
+@@ -5063,6 +5099,28 @@ enum dbg_status qed_dbg_set_bin_ptr(cons
+ return DBG_STATUS_OK;
+ }
+
++bool qed_read_fw_info(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt, struct fw_info *fw_info)
++{
++ struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
++ u8 storm_id;
++
++ for (storm_id = 0; storm_id < MAX_DBG_STORMS; storm_id++) {
++ struct storm_defs *storm = &s_storm_defs[storm_id];
++
++ /* Skip Storm if it's in reset */
++ if (dev_data->block_in_reset[storm->block_id])
++ continue;
++
++ /* Read FW info for the current Storm */
++ qed_read_storm_fw_info(p_hwfn, p_ptt, storm_id, fw_info);
++
++ return true;
++ }
++
++ return false;
++}
++
+ /* Assign default GRC param values */
+ void qed_dbg_grc_set_params_default(struct qed_hwfn *p_hwfn)
+ {
+--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
+@@ -2792,7 +2792,7 @@ static void qed_hw_info_port_num_bb(stru
+ {
+ u32 port_mode;
+
+- port_mode = qed_rd(p_hwfn, p_ptt, CNIG_REG_NW_PORT_MODE_BB_B0);
++ port_mode = qed_rd(p_hwfn, p_ptt, CNIG_REG_NW_PORT_MODE_BB);
+
+ if (port_mode < 3) {
+ p_hwfn->cdev->num_ports_in_engine = 1;
+--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+@@ -1095,14 +1095,16 @@ enum personality_type {
+ struct pf_start_tunnel_config {
+ u8 set_vxlan_udp_port_flg;
+ u8 set_geneve_udp_port_flg;
++ u8 set_no_inner_l2_vxlan_udp_port_flg;
+ u8 tunnel_clss_vxlan;
+ u8 tunnel_clss_l2geneve;
+ u8 tunnel_clss_ipgeneve;
+ u8 tunnel_clss_l2gre;
+ u8 tunnel_clss_ipgre;
+- u8 reserved;
+ __le16 vxlan_udp_port;
+ __le16 geneve_udp_port;
++ __le16 no_inner_l2_vxlan_udp_port;
++ __le16 reserved[3];
+ };
+
+ /* Ramrod data for PF start ramrod */
+@@ -1145,14 +1147,17 @@ struct pf_update_tunnel_config {
+ u8 update_rx_def_non_ucast_clss;
+ u8 set_vxlan_udp_port_flg;
+ u8 set_geneve_udp_port_flg;
++ u8 set_no_inner_l2_vxlan_udp_port_flg;
+ u8 tunnel_clss_vxlan;
+ u8 tunnel_clss_l2geneve;
+ u8 tunnel_clss_ipgeneve;
+ u8 tunnel_clss_l2gre;
+ u8 tunnel_clss_ipgre;
++ u8 reserved;
+ __le16 vxlan_udp_port;
+ __le16 geneve_udp_port;
+- __le16 reserved;
++ __le16 no_inner_l2_vxlan_udp_port;
++ __le16 reserved1[3];
+ };
+
+ /* Data for port update ramrod */
+@@ -2535,7 +2540,14 @@ struct idle_chk_data {
+ u16 reserved2;
+ };
+
+-/* Debug Tools data (per HW function) */
++struct pretend_params {
++ u8 split_type;
++ u8 reserved;
++ u16 split_id;
++};
++
++/* Debug Tools data (per HW function)
++ */
+ struct dbg_tools_data {
+ struct dbg_grc_data grc;
+ struct dbg_bus_data bus;
+@@ -2544,8 +2556,13 @@ struct dbg_tools_data {
+ u8 block_in_reset[88];
+ u8 chip_id;
+ u8 platform_id;
++ u8 num_ports;
++ u8 num_pfs_per_port;
++ u8 num_vfs;
+ u8 initialized;
+ u8 use_dmae;
++ u8 reserved;
++ struct pretend_params pretend;
+ u32 num_regs_read;
+ };
+
+@@ -2975,6 +2992,24 @@ void qed_read_regs(struct qed_hwfn *p_hw
+ struct qed_ptt *p_ptt, u32 *buf, u32 addr, u32 len);
+
+ /**
++ * @brief qed_read_fw_info - Reads FW info from the chip.
++ *
++ * The FW info contains FW-related information, such as the FW version,
++ * FW image (main/L2B/kuku), FW timestamp, etc.
++ * The FW info is read from the internal RAM of the first Storm that is not in
++ * reset.
++ *
++ * @param p_hwfn - HW device data
++ * @param p_ptt - Ptt window used for writing the registers.
++ * @param fw_info - Out: a pointer to write the FW info into.
++ *
++ * @return true if the FW info was read successfully from one of the Storms,
++ * or false if all Storms are in reset.
++ */
++bool qed_read_fw_info(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt, struct fw_info *fw_info);
++
++/**
+ * @brief qed_dbg_grc_set_params_default - Reverts all GRC parameters to their
+ * default value.
+ *
+@@ -4110,6 +4145,21 @@ void qed_memset_session_ctx(void *p_ctx_
+ */
+ void qed_memset_task_ctx(void *p_ctx_mem, u32 ctx_size, u8 ctx_type);
+
++#define NUM_STORMS 6
++
++/**
++ * @brief qed_set_rdma_error_level - Sets the RDMA assert level.
++ * If the severity of the error will be
++ * above the level, the FW will assert.
++ * @param p_hwfn - HW device data
++ * @param p_ptt - ptt window used for writing the registers
++ * @param assert_level - An array of assert levels for each storm.
++ *
++ */
++void qed_set_rdma_error_level(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt,
++ u8 assert_level[NUM_STORMS]);
++
+ /* Ystorm flow control mode. Use enum fw_flow_ctrl_mode */
+ #define YSTORM_FLOW_CONTROL_MODE_OFFSET (IRO[0].base)
+ #define YSTORM_FLOW_CONTROL_MODE_SIZE (IRO[0].size)
+@@ -4340,27 +4390,67 @@ void qed_memset_task_ctx(void *p_ctx_mem
+ (IRO[46].base + ((rdma_stat_counter_id) * IRO[46].m1))
+ #define TSTORM_RDMA_QUEUE_STAT_SIZE (IRO[46].size)
+
++/* Xstorm error level for assert */
++#define XSTORM_RDMA_ASSERT_LEVEL_OFFSET(pf_id) \
++ (IRO[47].base + ((pf_id) * IRO[47].m1))
++#define XSTORM_RDMA_ASSERT_LEVEL_SIZE (IRO[47].size)
++
++/* Ystorm error level for assert */
++#define YSTORM_RDMA_ASSERT_LEVEL_OFFSET(pf_id) \
++ (IRO[48].base + ((pf_id) * IRO[48].m1))
++#define YSTORM_RDMA_ASSERT_LEVEL_SIZE (IRO[48].size)
++
++/* Pstorm error level for assert */
++#define PSTORM_RDMA_ASSERT_LEVEL_OFFSET(pf_id) \
++ (IRO[49].base + ((pf_id) * IRO[49].m1))
++#define PSTORM_RDMA_ASSERT_LEVEL_SIZE (IRO[49].size)
++
++/* Tstorm error level for assert */
++#define TSTORM_RDMA_ASSERT_LEVEL_OFFSET(pf_id) \
++ (IRO[50].base + ((pf_id) * IRO[50].m1))
++#define TSTORM_RDMA_ASSERT_LEVEL_SIZE (IRO[50].size)
++
++/* Mstorm error level for assert */
++#define MSTORM_RDMA_ASSERT_LEVEL_OFFSET(pf_id) \
++ (IRO[51].base + ((pf_id) * IRO[51].m1))
++#define MSTORM_RDMA_ASSERT_LEVEL_SIZE (IRO[51].size)
++
++/* Ustorm error level for assert */
++#define USTORM_RDMA_ASSERT_LEVEL_OFFSET(pf_id) \
++ (IRO[52].base + ((pf_id) * IRO[52].m1))
++#define USTORM_RDMA_ASSERT_LEVEL_SIZE (IRO[52].size)
++
+ /* Xstorm iWARP rxmit stats */
+ #define XSTORM_IWARP_RXMIT_STATS_OFFSET(pf_id) \
+- (IRO[47].base + ((pf_id) * IRO[47].m1))
+-#define XSTORM_IWARP_RXMIT_STATS_SIZE (IRO[47].size)
++ (IRO[53].base + ((pf_id) * IRO[53].m1))
++#define XSTORM_IWARP_RXMIT_STATS_SIZE (IRO[53].size)
+
+ /* Tstorm RoCE Event Statistics */
+ #define TSTORM_ROCE_EVENTS_STAT_OFFSET(roce_pf_id) \
+- (IRO[48].base + ((roce_pf_id) * IRO[48].m1))
+-#define TSTORM_ROCE_EVENTS_STAT_SIZE (IRO[48].size)
++ (IRO[54].base + ((roce_pf_id) * IRO[54].m1))
++#define TSTORM_ROCE_EVENTS_STAT_SIZE (IRO[54].size)
+
+ /* DCQCN Received Statistics */
+ #define YSTORM_ROCE_DCQCN_RECEIVED_STATS_OFFSET(roce_pf_id) \
+- (IRO[49].base + ((roce_pf_id) * IRO[49].m1))
+-#define YSTORM_ROCE_DCQCN_RECEIVED_STATS_SIZE (IRO[49].size)
++ (IRO[55].base + ((roce_pf_id) * IRO[55].m1))
++#define YSTORM_ROCE_DCQCN_RECEIVED_STATS_SIZE (IRO[55].size)
++
++/* RoCE Error Statistics */
++#define YSTORM_ROCE_ERROR_STATS_OFFSET(roce_pf_id) \
++ (IRO[56].base + ((roce_pf_id) * IRO[56].m1))
++#define YSTORM_ROCE_ERROR_STATS_SIZE (IRO[56].size)
+
+ /* DCQCN Sent Statistics */
+ #define PSTORM_ROCE_DCQCN_SENT_STATS_OFFSET(roce_pf_id) \
+- (IRO[50].base + ((roce_pf_id) * IRO[50].m1))
+-#define PSTORM_ROCE_DCQCN_SENT_STATS_SIZE (IRO[50].size)
++ (IRO[57].base + ((roce_pf_id) * IRO[57].m1))
++#define PSTORM_ROCE_DCQCN_SENT_STATS_SIZE (IRO[57].size)
++
++/* RoCE CQEs Statistics */
++#define USTORM_ROCE_CQE_STATS_OFFSET(roce_pf_id) \
++ (IRO[58].base + ((roce_pf_id) * IRO[58].m1))
++#define USTORM_ROCE_CQE_STATS_SIZE (IRO[58].size)
+
+-static const struct iro iro_arr[51] = {
++static const struct iro iro_arr[59] = {
+ {0x0, 0x0, 0x0, 0x0, 0x8},
+ {0x4cb8, 0x88, 0x0, 0x0, 0x88},
+ {0x6530, 0x20, 0x0, 0x0, 0x20},
+@@ -4408,10 +4498,18 @@ static const struct iro iro_arr[51] = {
+ {0x10768, 0x20, 0x0, 0x0, 0x20},
+ {0x2d48, 0x80, 0x0, 0x0, 0x10},
+ {0x5048, 0x10, 0x0, 0x0, 0x10},
++ {0xc748, 0x8, 0x0, 0x0, 0x1},
++ {0xa128, 0x8, 0x0, 0x0, 0x1},
++ {0x10f00, 0x8, 0x0, 0x0, 0x1},
++ {0xf030, 0x8, 0x0, 0x0, 0x1},
++ {0x13028, 0x8, 0x0, 0x0, 0x1},
++ {0x12c58, 0x8, 0x0, 0x0, 0x1},
+ {0xc9b8, 0x30, 0x0, 0x0, 0x10},
+- {0xed90, 0x10, 0x0, 0x0, 0x10},
+- {0xa3a0, 0x10, 0x0, 0x0, 0x10},
++ {0xed90, 0x28, 0x0, 0x0, 0x28},
++ {0xa520, 0x18, 0x0, 0x0, 0x18},
++ {0xa6a0, 0x8, 0x0, 0x0, 0x8},
+ {0x13108, 0x8, 0x0, 0x0, 0x8},
++ {0x13c50, 0x18, 0x0, 0x0, 0x18},
+ };
+
+ /* Runtime array offsets */
+@@ -4797,147 +4895,147 @@ static const struct iro iro_arr[51] = {
+ #define NIG_REG_LLH_FUNC_FILTER_HDR_SEL_RT_OFFSET 39769
+ #define NIG_REG_LLH_FUNC_FILTER_HDR_SEL_RT_SIZE 16
+ #define NIG_REG_TX_EDPM_CTRL_RT_OFFSET 39785
+-#define NIG_REG_ROCE_DUPLICATE_TO_HOST_RT_OFFSET 39786
+-#define NIG_REG_PPF_TO_ENGINE_SEL_RT_OFFSET 39787
+-#define NIG_REG_PPF_TO_ENGINE_SEL_RT_SIZE 8
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_VALUE_RT_OFFSET 39795
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_VALUE_RT_SIZE 1024
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_EN_RT_OFFSET 40819
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_EN_RT_SIZE 512
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_MODE_RT_OFFSET 41331
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_MODE_RT_SIZE 512
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_PROTOCOL_TYPE_RT_OFFSET 41843
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_PROTOCOL_TYPE_RT_SIZE 512
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_HDR_SEL_RT_OFFSET 42355
+-#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_HDR_SEL_RT_SIZE 512
+-#define NIG_REG_LLH_PF_CLS_FILTERS_MAP_RT_OFFSET 42867
+-#define NIG_REG_LLH_PF_CLS_FILTERS_MAP_RT_SIZE 32
+-#define CDU_REG_CID_ADDR_PARAMS_RT_OFFSET 42899
+-#define CDU_REG_SEGMENT0_PARAMS_RT_OFFSET 42900
+-#define CDU_REG_SEGMENT1_PARAMS_RT_OFFSET 42901
+-#define CDU_REG_PF_SEG0_TYPE_OFFSET_RT_OFFSET 42902
+-#define CDU_REG_PF_SEG1_TYPE_OFFSET_RT_OFFSET 42903
+-#define CDU_REG_PF_SEG2_TYPE_OFFSET_RT_OFFSET 42904
+-#define CDU_REG_PF_SEG3_TYPE_OFFSET_RT_OFFSET 42905
+-#define CDU_REG_PF_FL_SEG0_TYPE_OFFSET_RT_OFFSET 42906
+-#define CDU_REG_PF_FL_SEG1_TYPE_OFFSET_RT_OFFSET 42907
+-#define CDU_REG_PF_FL_SEG2_TYPE_OFFSET_RT_OFFSET 42908
+-#define CDU_REG_PF_FL_SEG3_TYPE_OFFSET_RT_OFFSET 42909
+-#define CDU_REG_VF_SEG_TYPE_OFFSET_RT_OFFSET 42910
+-#define CDU_REG_VF_FL_SEG_TYPE_OFFSET_RT_OFFSET 42911
+-#define PBF_REG_TAG_ETHERTYPE_0_RT_OFFSET 42912
+-#define PBF_REG_BTB_SHARED_AREA_SIZE_RT_OFFSET 42913
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET 42914
+-#define PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET 42915
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ0_RT_OFFSET 42916
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET 42917
+-#define PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET 42918
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ1_RT_OFFSET 42919
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ2_RT_OFFSET 42920
+-#define PBF_REG_BTB_GUARANTEED_VOQ2_RT_OFFSET 42921
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ2_RT_OFFSET 42922
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ3_RT_OFFSET 42923
+-#define PBF_REG_BTB_GUARANTEED_VOQ3_RT_OFFSET 42924
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ3_RT_OFFSET 42925
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ4_RT_OFFSET 42926
+-#define PBF_REG_BTB_GUARANTEED_VOQ4_RT_OFFSET 42927
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ4_RT_OFFSET 42928
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ5_RT_OFFSET 42929
+-#define PBF_REG_BTB_GUARANTEED_VOQ5_RT_OFFSET 42930
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ5_RT_OFFSET 42931
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ6_RT_OFFSET 42932
+-#define PBF_REG_BTB_GUARANTEED_VOQ6_RT_OFFSET 42933
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ6_RT_OFFSET 42934
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ7_RT_OFFSET 42935
+-#define PBF_REG_BTB_GUARANTEED_VOQ7_RT_OFFSET 42936
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ7_RT_OFFSET 42937
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ8_RT_OFFSET 42938
+-#define PBF_REG_BTB_GUARANTEED_VOQ8_RT_OFFSET 42939
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ8_RT_OFFSET 42940
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ9_RT_OFFSET 42941
+-#define PBF_REG_BTB_GUARANTEED_VOQ9_RT_OFFSET 42942
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ9_RT_OFFSET 42943
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ10_RT_OFFSET 42944
+-#define PBF_REG_BTB_GUARANTEED_VOQ10_RT_OFFSET 42945
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ10_RT_OFFSET 42946
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ11_RT_OFFSET 42947
+-#define PBF_REG_BTB_GUARANTEED_VOQ11_RT_OFFSET 42948
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ11_RT_OFFSET 42949
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ12_RT_OFFSET 42950
+-#define PBF_REG_BTB_GUARANTEED_VOQ12_RT_OFFSET 42951
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ12_RT_OFFSET 42952
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ13_RT_OFFSET 42953
+-#define PBF_REG_BTB_GUARANTEED_VOQ13_RT_OFFSET 42954
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ13_RT_OFFSET 42955
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ14_RT_OFFSET 42956
+-#define PBF_REG_BTB_GUARANTEED_VOQ14_RT_OFFSET 42957
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ14_RT_OFFSET 42958
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ15_RT_OFFSET 42959
+-#define PBF_REG_BTB_GUARANTEED_VOQ15_RT_OFFSET 42960
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ15_RT_OFFSET 42961
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ16_RT_OFFSET 42962
+-#define PBF_REG_BTB_GUARANTEED_VOQ16_RT_OFFSET 42963
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ16_RT_OFFSET 42964
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ17_RT_OFFSET 42965
+-#define PBF_REG_BTB_GUARANTEED_VOQ17_RT_OFFSET 42966
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ17_RT_OFFSET 42967
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ18_RT_OFFSET 42968
+-#define PBF_REG_BTB_GUARANTEED_VOQ18_RT_OFFSET 42969
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ18_RT_OFFSET 42970
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ19_RT_OFFSET 42971
+-#define PBF_REG_BTB_GUARANTEED_VOQ19_RT_OFFSET 42972
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ19_RT_OFFSET 42973
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ20_RT_OFFSET 42974
+-#define PBF_REG_BTB_GUARANTEED_VOQ20_RT_OFFSET 42975
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ20_RT_OFFSET 42976
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ21_RT_OFFSET 42977
+-#define PBF_REG_BTB_GUARANTEED_VOQ21_RT_OFFSET 42978
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ21_RT_OFFSET 42979
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ22_RT_OFFSET 42980
+-#define PBF_REG_BTB_GUARANTEED_VOQ22_RT_OFFSET 42981
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ22_RT_OFFSET 42982
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ23_RT_OFFSET 42983
+-#define PBF_REG_BTB_GUARANTEED_VOQ23_RT_OFFSET 42984
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ23_RT_OFFSET 42985
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ24_RT_OFFSET 42986
+-#define PBF_REG_BTB_GUARANTEED_VOQ24_RT_OFFSET 42987
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ24_RT_OFFSET 42988
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ25_RT_OFFSET 42989
+-#define PBF_REG_BTB_GUARANTEED_VOQ25_RT_OFFSET 42990
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ25_RT_OFFSET 42991
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ26_RT_OFFSET 42992
+-#define PBF_REG_BTB_GUARANTEED_VOQ26_RT_OFFSET 42993
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ26_RT_OFFSET 42994
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ27_RT_OFFSET 42995
+-#define PBF_REG_BTB_GUARANTEED_VOQ27_RT_OFFSET 42996
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ27_RT_OFFSET 42997
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ28_RT_OFFSET 42998
+-#define PBF_REG_BTB_GUARANTEED_VOQ28_RT_OFFSET 42999
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ28_RT_OFFSET 43000
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ29_RT_OFFSET 43001
+-#define PBF_REG_BTB_GUARANTEED_VOQ29_RT_OFFSET 43002
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ29_RT_OFFSET 43003
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ30_RT_OFFSET 43004
+-#define PBF_REG_BTB_GUARANTEED_VOQ30_RT_OFFSET 43005
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ30_RT_OFFSET 43006
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ31_RT_OFFSET 43007
+-#define PBF_REG_BTB_GUARANTEED_VOQ31_RT_OFFSET 43008
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ31_RT_OFFSET 43009
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ32_RT_OFFSET 43010
+-#define PBF_REG_BTB_GUARANTEED_VOQ32_RT_OFFSET 43011
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ32_RT_OFFSET 43012
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ33_RT_OFFSET 43013
+-#define PBF_REG_BTB_GUARANTEED_VOQ33_RT_OFFSET 43014
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ33_RT_OFFSET 43015
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ34_RT_OFFSET 43016
+-#define PBF_REG_BTB_GUARANTEED_VOQ34_RT_OFFSET 43017
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ34_RT_OFFSET 43018
+-#define PBF_REG_YCMD_QS_NUM_LINES_VOQ35_RT_OFFSET 43019
+-#define PBF_REG_BTB_GUARANTEED_VOQ35_RT_OFFSET 43020
+-#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ35_RT_OFFSET 43021
+-#define XCM_REG_CON_PHY_Q3_RT_OFFSET 43022
++#define NIG_REG_PPF_TO_ENGINE_SEL_RT_OFFSET 39786
++#define NIG_REG_PPF_TO_ENGINE_SEL_RT_SIZE 8
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_VALUE_RT_OFFSET 39794
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_VALUE_RT_SIZE 1024
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_EN_RT_OFFSET 40818
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_EN_RT_SIZE 512
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_MODE_RT_OFFSET 41330
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_MODE_RT_SIZE 512
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_PROTOCOL_TYPE_RT_OFFSET 41842
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_PROTOCOL_TYPE_RT_SIZE 512
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_HDR_SEL_RT_OFFSET 42354
++#define NIG_REG_LLH_PF_CLS_FUNC_FILTER_HDR_SEL_RT_SIZE 512
++#define NIG_REG_LLH_PF_CLS_FILTERS_MAP_RT_OFFSET 42866
++#define NIG_REG_LLH_PF_CLS_FILTERS_MAP_RT_SIZE 32
++#define CDU_REG_CID_ADDR_PARAMS_RT_OFFSET 42898
++#define CDU_REG_SEGMENT0_PARAMS_RT_OFFSET 42899
++#define CDU_REG_SEGMENT1_PARAMS_RT_OFFSET 42900
++#define CDU_REG_PF_SEG0_TYPE_OFFSET_RT_OFFSET 42901
++#define CDU_REG_PF_SEG1_TYPE_OFFSET_RT_OFFSET 42902
++#define CDU_REG_PF_SEG2_TYPE_OFFSET_RT_OFFSET 42903
++#define CDU_REG_PF_SEG3_TYPE_OFFSET_RT_OFFSET 42904
++#define CDU_REG_PF_FL_SEG0_TYPE_OFFSET_RT_OFFSET 42905
++#define CDU_REG_PF_FL_SEG1_TYPE_OFFSET_RT_OFFSET 42906
++#define CDU_REG_PF_FL_SEG2_TYPE_OFFSET_RT_OFFSET 42907
++#define CDU_REG_PF_FL_SEG3_TYPE_OFFSET_RT_OFFSET 42908
++#define CDU_REG_VF_SEG_TYPE_OFFSET_RT_OFFSET 42909
++#define CDU_REG_VF_FL_SEG_TYPE_OFFSET_RT_OFFSET 42910
++#define PBF_REG_TAG_ETHERTYPE_0_RT_OFFSET 42911
++#define PBF_REG_BTB_SHARED_AREA_SIZE_RT_OFFSET 42912
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET 42913
++#define PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET 42914
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ0_RT_OFFSET 42915
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET 42916
++#define PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET 42917
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ1_RT_OFFSET 42918
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ2_RT_OFFSET 42919
++#define PBF_REG_BTB_GUARANTEED_VOQ2_RT_OFFSET 42920
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ2_RT_OFFSET 42921
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ3_RT_OFFSET 42922
++#define PBF_REG_BTB_GUARANTEED_VOQ3_RT_OFFSET 42923
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ3_RT_OFFSET 42924
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ4_RT_OFFSET 42925
++#define PBF_REG_BTB_GUARANTEED_VOQ4_RT_OFFSET 42926
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ4_RT_OFFSET 42927
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ5_RT_OFFSET 42928
++#define PBF_REG_BTB_GUARANTEED_VOQ5_RT_OFFSET 42929
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ5_RT_OFFSET 42930
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ6_RT_OFFSET 42931
++#define PBF_REG_BTB_GUARANTEED_VOQ6_RT_OFFSET 42932
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ6_RT_OFFSET 42933
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ7_RT_OFFSET 42934
++#define PBF_REG_BTB_GUARANTEED_VOQ7_RT_OFFSET 42935
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ7_RT_OFFSET 42936
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ8_RT_OFFSET 42937
++#define PBF_REG_BTB_GUARANTEED_VOQ8_RT_OFFSET 42938
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ8_RT_OFFSET 42939
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ9_RT_OFFSET 42940
++#define PBF_REG_BTB_GUARANTEED_VOQ9_RT_OFFSET 42941
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ9_RT_OFFSET 42942
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ10_RT_OFFSET 42943
++#define PBF_REG_BTB_GUARANTEED_VOQ10_RT_OFFSET 42944
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ10_RT_OFFSET 42945
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ11_RT_OFFSET 42946
++#define PBF_REG_BTB_GUARANTEED_VOQ11_RT_OFFSET 42947
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ11_RT_OFFSET 42948
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ12_RT_OFFSET 42949
++#define PBF_REG_BTB_GUARANTEED_VOQ12_RT_OFFSET 42950
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ12_RT_OFFSET 42951
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ13_RT_OFFSET 42952
++#define PBF_REG_BTB_GUARANTEED_VOQ13_RT_OFFSET 42953
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ13_RT_OFFSET 42954
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ14_RT_OFFSET 42955
++#define PBF_REG_BTB_GUARANTEED_VOQ14_RT_OFFSET 42956
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ14_RT_OFFSET 42957
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ15_RT_OFFSET 42958
++#define PBF_REG_BTB_GUARANTEED_VOQ15_RT_OFFSET 42959
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ15_RT_OFFSET 42960
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ16_RT_OFFSET 42961
++#define PBF_REG_BTB_GUARANTEED_VOQ16_RT_OFFSET 42962
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ16_RT_OFFSET 42963
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ17_RT_OFFSET 42964
++#define PBF_REG_BTB_GUARANTEED_VOQ17_RT_OFFSET 42965
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ17_RT_OFFSET 42966
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ18_RT_OFFSET 42967
++#define PBF_REG_BTB_GUARANTEED_VOQ18_RT_OFFSET 42968
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ18_RT_OFFSET 42969
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ19_RT_OFFSET 42970
++#define PBF_REG_BTB_GUARANTEED_VOQ19_RT_OFFSET 42971
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ19_RT_OFFSET 42972
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ20_RT_OFFSET 42973
++#define PBF_REG_BTB_GUARANTEED_VOQ20_RT_OFFSET 42974
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ20_RT_OFFSET 42975
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ21_RT_OFFSET 42976
++#define PBF_REG_BTB_GUARANTEED_VOQ21_RT_OFFSET 42977
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ21_RT_OFFSET 42978
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ22_RT_OFFSET 42979
++#define PBF_REG_BTB_GUARANTEED_VOQ22_RT_OFFSET 42980
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ22_RT_OFFSET 42981
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ23_RT_OFFSET 42982
++#define PBF_REG_BTB_GUARANTEED_VOQ23_RT_OFFSET 42983
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ23_RT_OFFSET 42984
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ24_RT_OFFSET 42985
++#define PBF_REG_BTB_GUARANTEED_VOQ24_RT_OFFSET 42986
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ24_RT_OFFSET 42987
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ25_RT_OFFSET 42988
++#define PBF_REG_BTB_GUARANTEED_VOQ25_RT_OFFSET 42989
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ25_RT_OFFSET 42990
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ26_RT_OFFSET 42991
++#define PBF_REG_BTB_GUARANTEED_VOQ26_RT_OFFSET 42992
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ26_RT_OFFSET 42993
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ27_RT_OFFSET 42994
++#define PBF_REG_BTB_GUARANTEED_VOQ27_RT_OFFSET 42995
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ27_RT_OFFSET 42996
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ28_RT_OFFSET 42997
++#define PBF_REG_BTB_GUARANTEED_VOQ28_RT_OFFSET 42998
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ28_RT_OFFSET 42999
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ29_RT_OFFSET 43000
++#define PBF_REG_BTB_GUARANTEED_VOQ29_RT_OFFSET 43001
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ29_RT_OFFSET 43002
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ30_RT_OFFSET 43003
++#define PBF_REG_BTB_GUARANTEED_VOQ30_RT_OFFSET 43004
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ30_RT_OFFSET 43005
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ31_RT_OFFSET 43006
++#define PBF_REG_BTB_GUARANTEED_VOQ31_RT_OFFSET 43007
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ31_RT_OFFSET 43008
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ32_RT_OFFSET 43009
++#define PBF_REG_BTB_GUARANTEED_VOQ32_RT_OFFSET 43010
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ32_RT_OFFSET 43011
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ33_RT_OFFSET 43012
++#define PBF_REG_BTB_GUARANTEED_VOQ33_RT_OFFSET 43013
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ33_RT_OFFSET 43014
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ34_RT_OFFSET 43015
++#define PBF_REG_BTB_GUARANTEED_VOQ34_RT_OFFSET 43016
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ34_RT_OFFSET 43017
++#define PBF_REG_YCMD_QS_NUM_LINES_VOQ35_RT_OFFSET 43018
++#define PBF_REG_BTB_GUARANTEED_VOQ35_RT_OFFSET 43019
++#define PBF_REG_BTB_SHARED_AREA_SETUP_VOQ35_RT_OFFSET 43020
++#define XCM_REG_CON_PHY_Q3_RT_OFFSET 43021
++
++#define RUNTIME_ARRAY_SIZE 43022
+
+-#define RUNTIME_ARRAY_SIZE 43023
+
+ /* Init Callbacks */
+ #define DMAE_READY_CB 0
+@@ -5694,8 +5792,10 @@ struct eth_vport_rx_mode {
+ #define ETH_VPORT_RX_MODE_MCAST_ACCEPT_ALL_SHIFT 4
+ #define ETH_VPORT_RX_MODE_BCAST_ACCEPT_ALL_MASK 0x1
+ #define ETH_VPORT_RX_MODE_BCAST_ACCEPT_ALL_SHIFT 5
+-#define ETH_VPORT_RX_MODE_RESERVED1_MASK 0x3FF
+-#define ETH_VPORT_RX_MODE_RESERVED1_SHIFT 6
++#define ETH_VPORT_RX_MODE_ACCEPT_ANY_VNI_MASK 0x1
++#define ETH_VPORT_RX_MODE_ACCEPT_ANY_VNI_SHIFT 6
++#define ETH_VPORT_RX_MODE_RESERVED1_MASK 0x1FF
++#define ETH_VPORT_RX_MODE_RESERVED1_SHIFT 7
+ };
+
+ /* Command for setting tpa parameters */
+@@ -6756,7 +6856,7 @@ struct e4_ystorm_rdma_task_ag_ctx {
+ #define E4_YSTORM_RDMA_TASK_AG_CTX_RULE6EN_MASK 0x1
+ #define E4_YSTORM_RDMA_TASK_AG_CTX_RULE6EN_SHIFT 7
+ u8 key;
+- __le32 mw_cnt;
++ __le32 mw_cnt_or_qp_id;
+ u8 ref_cnt_seq;
+ u8 ctx_upd_seq;
+ __le16 dif_flags;
+@@ -6812,7 +6912,7 @@ struct e4_mstorm_rdma_task_ag_ctx {
+ #define E4_MSTORM_RDMA_TASK_AG_CTX_RULE6EN_MASK 0x1
+ #define E4_MSTORM_RDMA_TASK_AG_CTX_RULE6EN_SHIFT 7
+ u8 key;
+- __le32 mw_cnt;
++ __le32 mw_cnt_or_qp_id;
+ u8 ref_cnt_seq;
+ u8 ctx_upd_seq;
+ __le16 dif_flags;
+@@ -7075,8 +7175,7 @@ struct rdma_register_tid_ramrod_data {
+ struct regpair va;
+ struct regpair pbl_base;
+ struct regpair dif_error_addr;
+- struct regpair dif_runt_addr;
+- __le32 reserved4[2];
++ __le32 reserved4[4];
+ };
+
+ /* rdma resize cq output params */
+@@ -7144,8 +7243,7 @@ struct rdma_srq_modify_ramrod_data {
+ enum rdma_tid_type {
+ RDMA_TID_REGISTERED_MR,
+ RDMA_TID_FMR,
+- RDMA_TID_MW_TYPE1,
+- RDMA_TID_MW_TYPE2A,
++ RDMA_TID_MW,
+ MAX_RDMA_TID_TYPE
+ };
+
+@@ -7681,6 +7779,16 @@ struct e4_roce_conn_context {
+ struct ustorm_roce_conn_st_ctx ustorm_st_context;
+ };
+
++/* roce cqes statistics */
++struct roce_cqe_stats {
++ __le32 req_cqe_error;
++ __le32 req_remote_access_errors;
++ __le32 req_remote_invalid_request;
++ __le32 resp_cqe_error;
++ __le32 resp_local_length_error;
++ __le32 reserved;
++};
++
+ /* roce create qp requester ramrod data */
+ struct roce_create_qp_req_ramrod_data {
+ __le16 flags;
+@@ -7798,8 +7906,8 @@ struct roce_dcqcn_sent_stats {
+
+ /* RoCE destroy qp requester output params */
+ struct roce_destroy_qp_req_output_params {
+- __le32 num_bound_mw;
+ __le32 cq_prod;
++ __le32 reserved;
+ };
+
+ /* RoCE destroy qp requester ramrod data */
+@@ -7809,8 +7917,8 @@ struct roce_destroy_qp_req_ramrod_data {
+
+ /* RoCE destroy qp responder output params */
+ struct roce_destroy_qp_resp_output_params {
+- __le32 num_invalidated_mw;
+ __le32 cq_prod;
++ __le32 reserved;
+ };
+
+ /* RoCE destroy qp responder ramrod data */
+@@ -7818,16 +7926,27 @@ struct roce_destroy_qp_resp_ramrod_data
+ struct regpair output_params_addr;
+ };
+
++/* roce error statistics */
++struct roce_error_stats {
++ __le32 resp_remote_access_errors;
++ __le32 reserved;
++};
++
+ /* roce special events statistics */
+ struct roce_events_stats {
+- __le16 silent_drops;
+- __le16 rnr_naks_sent;
++ __le32 silent_drops;
++ __le32 rnr_naks_sent;
+ __le32 retransmit_count;
+ __le32 icrc_error_count;
+- __le32 reserved;
++ __le32 implied_nak_seq_err;
++ __le32 duplicate_request;
++ __le32 local_ack_timeout_err;
++ __le32 out_of_sequence;
++ __le32 packet_seq_err;
++ __le32 rnr_nak_retry_err;
+ };
+
+-/* ROCE slow path EQ cmd IDs */
++/* roce slow path EQ cmd IDs */
+ enum roce_event_opcode {
+ ROCE_EVENT_CREATE_QP = 11,
+ ROCE_EVENT_MODIFY_QP,
+@@ -7845,6 +7964,9 @@ struct roce_init_func_params {
+ u8 cnp_dscp;
+ u8 reserved;
+ __le32 cnp_send_timeout;
++ __le16 rl_offset;
++ u8 rl_count_log;
++ u8 reserved1[5];
+ };
+
+ /* roce func init ramrod data */
+@@ -8532,7 +8654,7 @@ struct e4_tstorm_roce_resp_conn_ag_ctx {
+ __le16 rq_prod;
+ __le16 conn_dpi;
+ __le16 irq_cons;
+- __le32 num_invlidated_mw;
++ __le32 reg9;
+ __le32 reg10;
+ };
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_hw.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c
+@@ -360,6 +360,26 @@ void qed_port_unpretend(struct qed_hwfn
+ *(u32 *)&p_ptt->pxp.pretend);
+ }
+
++void qed_port_fid_pretend(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt, u8 port_id, u16 fid)
++{
++ u16 control = 0;
++
++ SET_FIELD(control, PXP_PRETEND_CMD_PORT, port_id);
++ SET_FIELD(control, PXP_PRETEND_CMD_USE_PORT, 1);
++ SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_PORT, 1);
++ SET_FIELD(control, PXP_PRETEND_CMD_IS_CONCRETE, 1);
++ SET_FIELD(control, PXP_PRETEND_CMD_PRETEND_FUNCTION, 1);
++ if (!GET_FIELD(fid, PXP_CONCRETE_FID_VFVALID))
++ fid = GET_FIELD(fid, PXP_CONCRETE_FID_PFID);
++ p_ptt->pxp.pretend.control = cpu_to_le16(control);
++ p_ptt->pxp.pretend.fid.concrete_fid.fid = cpu_to_le16(fid);
++ REG_WR(p_hwfn,
++ qed_ptt_config_addr(p_ptt) +
++ offsetof(struct pxp_ptt_entry, pretend),
++ *(u32 *)&p_ptt->pxp.pretend);
++}
++
+ u32 qed_vfid_to_concrete(struct qed_hwfn *p_hwfn, u8 vfid)
+ {
+ u32 concrete_fid = 0;
+--- a/drivers/net/ethernet/qlogic/qed/qed_hw.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_hw.h
+@@ -245,6 +245,18 @@ void qed_port_unpretend(struct qed_hwfn
+ struct qed_ptt *p_ptt);
+
+ /**
++ * @brief qed_port_fid_pretend - pretend to another port and another function
++ * when accessing the ptt window
++ *
++ * @param p_hwfn
++ * @param p_ptt
++ * @param port_id - the port to pretend to
++ * @param fid - fid field of pxp_pretend structure. Can contain either pf / vf.
++ */
++void qed_port_fid_pretend(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt, u8 port_id, u16 fid);
++
++/**
+ * @brief qed_vfid_to_concrete - build a concrete FID for a
+ * given VF ID
+ *
+--- a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
+@@ -1245,7 +1245,7 @@ void qed_gft_config(struct qed_hwfn *p_h
+ bool udp,
+ bool ipv4, bool ipv6, enum gft_profile_type profile_type)
+ {
+- u32 reg_val, cam_line, ram_line_lo, ram_line_hi;
++ u32 reg_val, cam_line, ram_line_lo, ram_line_hi, search_non_ip_as_gft;
+
+ if (!ipv6 && !ipv4)
+ DP_NOTICE(p_hwfn,
+@@ -1314,6 +1314,9 @@ void qed_gft_config(struct qed_hwfn *p_h
+ ram_line_lo = 0;
+ ram_line_hi = 0;
+
++ /* Search no IP as GFT */
++ search_non_ip_as_gft = 0;
++
+ /* Tunnel type */
+ SET_FIELD(ram_line_lo, GFT_RAM_LINE_TUNNEL_DST_PORT, 1);
+ SET_FIELD(ram_line_lo, GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL, 1);
+@@ -1337,9 +1340,14 @@ void qed_gft_config(struct qed_hwfn *p_h
+ SET_FIELD(ram_line_lo, GFT_RAM_LINE_ETHERTYPE, 1);
+ } else if (profile_type == GFT_PROFILE_TYPE_TUNNEL_TYPE) {
+ SET_FIELD(ram_line_lo, GFT_RAM_LINE_TUNNEL_ETHERTYPE, 1);
++
++ /* Allow tunneled traffic without inner IP */
++ search_non_ip_as_gft = 1;
+ }
+
+ qed_wr(p_hwfn,
++ p_ptt, PRS_REG_SEARCH_NON_IP_AS_GFT, search_non_ip_as_gft);
++ qed_wr(p_hwfn,
+ p_ptt,
+ PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
+ ram_line_lo);
+@@ -1509,3 +1517,43 @@ void qed_enable_context_validation(struc
+ ctx_validation = CDU_VALIDATION_DEFAULT_CFG << 8;
+ qed_wr(p_hwfn, p_ptt, CDU_REG_TCFC_CTX_VALID0, ctx_validation);
+ }
++
++static u32 qed_get_rdma_assert_ram_addr(struct qed_hwfn *p_hwfn, u8 storm_id)
++{
++ switch (storm_id) {
++ case 0:
++ return TSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
++ TSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
++ case 1:
++ return MSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
++ MSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
++ case 2:
++ return USEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
++ USTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
++ case 3:
++ return XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
++ XSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
++ case 4:
++ return YSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
++ YSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
++ case 5:
++ return PSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
++ PSTORM_RDMA_ASSERT_LEVEL_OFFSET(p_hwfn->rel_pf_id);
++
++ default:
++ return 0;
++ }
++}
++
++void qed_set_rdma_error_level(struct qed_hwfn *p_hwfn,
++ struct qed_ptt *p_ptt,
++ u8 assert_level[NUM_STORMS])
++{
++ u8 storm_id;
++
++ for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
++ u32 ram_addr = qed_get_rdma_assert_ram_addr(p_hwfn, storm_id);
++
++ qed_wr(p_hwfn, p_ptt, ram_addr, assert_level[storm_id]);
++ }
++}
+--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+@@ -1159,7 +1159,6 @@ int qed_iwarp_connect(void *rdma_cxt,
+ struct qed_iwarp_info *iwarp_info;
+ struct qed_iwarp_ep *ep;
+ u8 mpa_data_size = 0;
+- u8 ts_hdr_size = 0;
+ u32 cid;
+ int rc;
+
+@@ -1218,10 +1217,7 @@ int qed_iwarp_connect(void *rdma_cxt,
+ iparams->cm_info.private_data,
+ iparams->cm_info.private_data_len);
+
+- if (p_hwfn->p_rdma_info->iwarp.tcp_flags & QED_IWARP_TS_EN)
+- ts_hdr_size = TIMESTAMP_HEADER_SIZE;
+-
+- ep->mss = iparams->mss - ts_hdr_size;
++ ep->mss = iparams->mss;
+ ep->mss = min_t(u16, QED_IWARP_MAX_FW_MSS, ep->mss);
+
+ ep->event_cb = iparams->event_cb;
+@@ -2337,7 +2333,6 @@ qed_iwarp_ll2_comp_syn_pkt(void *cxt, st
+ u8 local_mac_addr[ETH_ALEN];
+ struct qed_iwarp_ep *ep;
+ int tcp_start_offset;
+- u8 ts_hdr_size = 0;
+ u8 ll2_syn_handle;
+ int payload_len;
+ u32 hdr_size;
+@@ -2415,11 +2410,7 @@ qed_iwarp_ll2_comp_syn_pkt(void *cxt, st
+
+ memcpy(&ep->cm_info, &cm_info, sizeof(ep->cm_info));
+
+- if (p_hwfn->p_rdma_info->iwarp.tcp_flags & QED_IWARP_TS_EN)
+- ts_hdr_size = TIMESTAMP_HEADER_SIZE;
+-
+- hdr_size = ((cm_info.ip_version == QED_TCP_IPV4) ? 40 : 60) +
+- ts_hdr_size;
++ hdr_size = ((cm_info.ip_version == QED_TCP_IPV4) ? 40 : 60);
+ ep->mss = p_hwfn->p_rdma_info->iwarp.max_mtu - hdr_size;
+ ep->mss = min_t(u16, QED_IWARP_MAX_FW_MSS, ep->mss);
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c
+@@ -586,6 +586,9 @@ qed_sp_update_accept_mode(struct qed_hwf
+ SET_FIELD(state, ETH_VPORT_RX_MODE_BCAST_ACCEPT_ALL,
+ !!(accept_filter & QED_ACCEPT_BCAST));
+
++ SET_FIELD(state, ETH_VPORT_RX_MODE_ACCEPT_ANY_VNI,
++ !!(accept_filter & QED_ACCEPT_ANY_VNI));
++
+ p_ramrod->rx_mode.state = cpu_to_le16(state);
+ DP_VERBOSE(p_hwfn, QED_MSG_SP,
+ "p_ramrod->rx_mode.state = 0x%x\n", state);
+--- a/drivers/net/ethernet/qlogic/qed/qed_l2.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_l2.h
+@@ -183,6 +183,7 @@ struct qed_filter_accept_flags {
+ #define QED_ACCEPT_MCAST_MATCHED 0x08
+ #define QED_ACCEPT_MCAST_UNMATCHED 0x10
+ #define QED_ACCEPT_BCAST 0x20
++#define QED_ACCEPT_ANY_VNI 0x40
+ };
+
+ struct qed_arfs_config_params {
+--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+@@ -1508,11 +1508,8 @@ qed_rdma_register_tid(void *rdma_cxt,
+ case QED_RDMA_TID_FMR:
+ tid_type = RDMA_TID_FMR;
+ break;
+- case QED_RDMA_TID_MW_TYPE1:
+- tid_type = RDMA_TID_MW_TYPE1;
+- break;
+- case QED_RDMA_TID_MW_TYPE2A:
+- tid_type = RDMA_TID_MW_TYPE2A;
++ case QED_RDMA_TID_MW:
++ tid_type = RDMA_TID_MW;
+ break;
+ default:
+ rc = -EINVAL;
+@@ -1544,7 +1541,6 @@ qed_rdma_register_tid(void *rdma_cxt,
+ RDMA_REGISTER_TID_RAMROD_DATA_DIF_ON_HOST_FLG, 1);
+ DMA_REGPAIR_LE(p_ramrod->dif_error_addr,
+ params->dif_error_addr);
+- DMA_REGPAIR_LE(p_ramrod->dif_runt_addr, params->dif_runt_addr);
+ }
+
+ rc = qed_spq_post(p_hwfn, p_ent, &fw_return_code);
+--- a/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
++++ b/drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
+@@ -178,7 +178,7 @@
+ 0x008c80UL
+ #define MCP_REG_SCRATCH \
+ 0xe20000UL
+-#define CNIG_REG_NW_PORT_MODE_BB_B0 \
++#define CNIG_REG_NW_PORT_MODE_BB \
+ 0x218200UL
+ #define MISCS_REG_CHIP_NUM \
+ 0x00976cUL
+@@ -1621,6 +1621,7 @@
+ #define NIG_REG_TX_EDPM_CTRL_TX_EDPM_TC_EN_SHIFT 1
+
+ #define PRS_REG_SEARCH_GFT 0x1f11bcUL
++#define PRS_REG_SEARCH_NON_IP_AS_GFT 0x1f11c0UL
+ #define PRS_REG_CM_HDR_GFT 0x1f11c8UL
+ #define PRS_REG_GFT_CAM 0x1f1100UL
+ #define PRS_REG_GFT_PROFILE_MASK_RAM 0x1f1000UL
+--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c
+@@ -681,7 +681,6 @@ static int qed_roce_sp_modify_requester(
+
+ static int qed_roce_sp_destroy_qp_responder(struct qed_hwfn *p_hwfn,
+ struct qed_rdma_qp *qp,
+- u32 *num_invalidated_mw,
+ u32 *cq_prod)
+ {
+ struct roce_destroy_qp_resp_output_params *p_ramrod_res;
+@@ -692,8 +691,6 @@ static int qed_roce_sp_destroy_qp_respon
+ int rc;
+
+ DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "icid = %08x\n", qp->icid);
+-
+- *num_invalidated_mw = 0;
+ *cq_prod = qp->cq_prod;
+
+ if (!qp->resp_offloaded) {
+@@ -742,7 +739,6 @@ static int qed_roce_sp_destroy_qp_respon
+ if (rc)
+ goto err;
+
+- *num_invalidated_mw = le32_to_cpu(p_ramrod_res->num_invalidated_mw);
+ *cq_prod = le32_to_cpu(p_ramrod_res->cq_prod);
+ qp->cq_prod = *cq_prod;
+
+@@ -764,8 +760,7 @@ err:
+ }
+
+ static int qed_roce_sp_destroy_qp_requester(struct qed_hwfn *p_hwfn,
+- struct qed_rdma_qp *qp,
+- u32 *num_bound_mw)
++ struct qed_rdma_qp *qp)
+ {
+ struct roce_destroy_qp_req_output_params *p_ramrod_res;
+ struct roce_destroy_qp_req_ramrod_data *p_ramrod;
+@@ -807,7 +802,6 @@ static int qed_roce_sp_destroy_qp_reques
+ if (rc)
+ goto err;
+
+- *num_bound_mw = le32_to_cpu(p_ramrod_res->num_bound_mw);
+
+ /* Free ORQ - only if ramrod succeeded, in case FW is still using it */
+ dma_free_coherent(&p_hwfn->cdev->pdev->dev,
+@@ -968,8 +962,6 @@ err_resp:
+
+ int qed_roce_destroy_qp(struct qed_hwfn *p_hwfn, struct qed_rdma_qp *qp)
+ {
+- u32 num_invalidated_mw = 0;
+- u32 num_bound_mw = 0;
+ u32 cq_prod;
+ int rc;
+
+@@ -984,22 +976,14 @@ int qed_roce_destroy_qp(struct qed_hwfn
+
+ if (qp->cur_state != QED_ROCE_QP_STATE_RESET) {
+ rc = qed_roce_sp_destroy_qp_responder(p_hwfn, qp,
+- &num_invalidated_mw,
+ &cq_prod);
+ if (rc)
+ return rc;
+
+ /* Send destroy requester ramrod */
+- rc = qed_roce_sp_destroy_qp_requester(p_hwfn, qp,
+- &num_bound_mw);
++ rc = qed_roce_sp_destroy_qp_requester(p_hwfn, qp);
+ if (rc)
+ return rc;
+-
+- if (num_invalidated_mw != num_bound_mw) {
+- DP_NOTICE(p_hwfn,
+- "number of invalidate memory windows is different from bounded ones\n");
+- return -EINVAL;
+- }
+ }
+
+ return 0;
+@@ -1010,7 +994,6 @@ int qed_roce_modify_qp(struct qed_hwfn *
+ enum qed_roce_qp_state prev_state,
+ struct qed_rdma_modify_qp_in_params *params)
+ {
+- u32 num_invalidated_mw = 0, num_bound_mw = 0;
+ int rc = 0;
+
+ /* Perform additional operations according to the current state and the
+@@ -1090,7 +1073,6 @@ int qed_roce_modify_qp(struct qed_hwfn *
+ /* Send destroy responder ramrod */
+ rc = qed_roce_sp_destroy_qp_responder(p_hwfn,
+ qp,
+- &num_invalidated_mw,
+ &cq_prod);
+
+ if (rc)
+@@ -1098,14 +1080,7 @@ int qed_roce_modify_qp(struct qed_hwfn *
+
+ qp->cq_prod = cq_prod;
+
+- rc = qed_roce_sp_destroy_qp_requester(p_hwfn, qp,
+- &num_bound_mw);
+-
+- if (num_invalidated_mw != num_bound_mw) {
+- DP_NOTICE(p_hwfn,
+- "number of invalidate memory windows is different from bounded ones\n");
+- return -EINVAL;
+- }
++ rc = qed_roce_sp_destroy_qp_requester(p_hwfn, qp);
+ } else {
+ DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "0\n");
+ }
+--- a/drivers/scsi/qedi/qedi_iscsi.c
++++ b/drivers/scsi/qedi/qedi_iscsi.c
+@@ -471,14 +471,8 @@ static u16 qedi_calc_mss(u16 pmtu, u8 is
+ else
+ hdrs += IPV4_HDR_LEN;
+
+- if (vlan_en)
+- hdrs += VLAN_LEN;
+-
+ mss = pmtu - hdrs;
+
+- if (tcp_ts_en)
+- mss -= TCP_OPTION_LEN;
+-
+ if (!mss)
+ mss = DEF_MSS;
+
+--- a/include/linux/qed/common_hsi.h
++++ b/include/linux/qed/common_hsi.h
+@@ -109,8 +109,8 @@
+ #define MAX_NUM_LL2_TX_STATS_COUNTERS 48
+
+ #define FW_MAJOR_VERSION 8
+-#define FW_MINOR_VERSION 33
+-#define FW_REVISION_VERSION 11
++#define FW_MINOR_VERSION 37
++#define FW_REVISION_VERSION 2
+ #define FW_ENGINEERING_VERSION 0
+
+ /***********************/
+--- a/include/linux/qed/iscsi_common.h
++++ b/include/linux/qed/iscsi_common.h
+@@ -799,8 +799,8 @@ struct e4_mstorm_iscsi_task_ag_ctx {
+ #define E4_MSTORM_ISCSI_TASK_AG_CTX_CONNECTION_TYPE_SHIFT 0
+ #define E4_MSTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_MASK 0x1
+ #define E4_MSTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_SHIFT 4
+-#define E4_MSTORM_ISCSI_TASK_AG_CTX_BIT1_MASK 0x1
+-#define E4_MSTORM_ISCSI_TASK_AG_CTX_BIT1_SHIFT 5
++#define E4_MSTORM_ISCSI_TASK_AG_CTX_CONN_CLEAR_SQ_FLAG_MASK 0x1
++#define E4_MSTORM_ISCSI_TASK_AG_CTX_CONN_CLEAR_SQ_FLAG_SHIFT 5
+ #define E4_MSTORM_ISCSI_TASK_AG_CTX_VALID_MASK 0x1
+ #define E4_MSTORM_ISCSI_TASK_AG_CTX_VALID_SHIFT 6
+ #define E4_MSTORM_ISCSI_TASK_AG_CTX_TASK_CLEANUP_FLAG_MASK 0x1
+@@ -849,8 +849,8 @@ struct e4_ustorm_iscsi_task_ag_ctx {
+ #define E4_USTORM_ISCSI_TASK_AG_CTX_CONNECTION_TYPE_SHIFT 0
+ #define E4_USTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_MASK 0x1
+ #define E4_USTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_SHIFT 4
+-#define E4_USTORM_ISCSI_TASK_AG_CTX_BIT1_MASK 0x1
+-#define E4_USTORM_ISCSI_TASK_AG_CTX_BIT1_SHIFT 5
++#define E4_USTORM_ISCSI_TASK_AG_CTX_CONN_CLEAR_SQ_FLAG_MASK 0x1
++#define E4_USTORM_ISCSI_TASK_AG_CTX_CONN_CLEAR_SQ_FLAG_SHIFT 5
+ #define E4_USTORM_ISCSI_TASK_AG_CTX_HQ_SCANNED_CF_MASK 0x3
+ #define E4_USTORM_ISCSI_TASK_AG_CTX_HQ_SCANNED_CF_SHIFT 6
+ u8 flags1;
+--- a/include/linux/qed/qed_rdma_if.h
++++ b/include/linux/qed/qed_rdma_if.h
+@@ -65,8 +65,7 @@ enum qed_roce_qp_state {
+ enum qed_rdma_tid_type {
+ QED_RDMA_TID_REGISTERED_MR,
+ QED_RDMA_TID_FMR,
+- QED_RDMA_TID_MW_TYPE1,
+- QED_RDMA_TID_MW_TYPE2A
++ QED_RDMA_TID_MW
+ };
+
+ struct qed_rdma_events {
+@@ -280,7 +279,6 @@ struct qed_rdma_register_tid_in_params {
+
+ bool dif_enabled;
+ u64 dif_error_addr;
+- u64 dif_runt_addr;
+ };
+
+ struct qed_rdma_create_cq_in_params {
+--- a/include/linux/qed/roce_common.h
++++ b/include/linux/qed/roce_common.h
+@@ -43,6 +43,7 @@
+ #define ROCE_MAX_QPS (32 * 1024)
+ #define ROCE_DCQCN_NP_MAX_QPS (64)
+ #define ROCE_DCQCN_RP_MAX_QPS (64)
++#define ROCE_LKEY_MW_DIF_EN_BIT (28)
+
+ /* Affiliated asynchronous events / errors enumeration */
+ enum roce_async_events_type {
diff --git a/patches.drivers/qed-fix-spelling-mistake-successffuly-successfully.patch b/patches.drivers/qed-fix-spelling-mistake-successffuly-successfully.patch
new file mode 100644
index 0000000000..eb3a512658
--- /dev/null
+++ b/patches.drivers/qed-fix-spelling-mistake-successffuly-successfully.patch
@@ -0,0 +1,27 @@
+From: "Ewan D. Milne" <emilne@redhat.com>
+Date: Tue, 10 Jul 2018 10:27:24 -0400
+Subject: qed: fix spelling mistake "successffuly" -> "successfully"
+Patch-mainline: v4.18-rc6
+Git-commit: 20c4515a1af770f4fb0dc6b044ffc9a6031e5767
+References: bsc#1086314 FATE#324886
+
+Trivial fix to spelling mistake in qed_probe message.
+
+Signed-off-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
+@@ -371,7 +371,7 @@ static struct qed_dev *qed_probe(struct
+ goto err2;
+ }
+
+- DP_INFO(cdev, "qed_probe completed successffuly\n");
++ DP_INFO(cdev, "qed_probe completed successfully\n");
+
+ return cdev;
+
diff --git a/patches.drivers/qed-remove-redundant-functions-qed_get_cm_pq_idx_rl.patch b/patches.drivers/qed-remove-redundant-functions-qed_get_cm_pq_idx_rl.patch
new file mode 100644
index 0000000000..8719d25abe
--- /dev/null
+++ b/patches.drivers/qed-remove-redundant-functions-qed_get_cm_pq_idx_rl.patch
@@ -0,0 +1,37 @@
+From: YueHaibing <yuehaibing@huawei.com>
+Date: Sat, 28 Jul 2018 18:23:36 +0800
+Subject: qed: remove redundant functions qed_get_cm_pq_idx_rl
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: b23641fe731f035a6071a654fd64309fa2f12208
+References: bsc#1086314 FATE#324886
+
+There are no in-tree callers of qed_get_cm_pq_idx_rl since it be there,
+so it can be removed.
+
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_dev.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
+@@ -507,16 +507,6 @@ u16 qed_get_cm_pq_idx_vf(struct qed_hwfn
+ return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + vf;
+ }
+
+-u16 qed_get_cm_pq_idx_rl(struct qed_hwfn *p_hwfn, u8 rl)
+-{
+- u16 max_rl = qed_init_qm_get_num_pf_rls(p_hwfn);
+-
+- if (rl > max_rl)
+- DP_ERR(p_hwfn, "rl %d must be smaller than %d\n", rl, max_rl);
+-
+- return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_RLS) + rl;
+-}
+-
+ /* Functions for creating specific types of pqs */
+ static void qed_init_qm_lb_pq(struct qed_hwfn *p_hwfn)
+ {
diff --git a/patches.drivers/qed-remove-redundant-functions-qed_set_gft_event_id_.patch b/patches.drivers/qed-remove-redundant-functions-qed_set_gft_event_id_.patch
new file mode 100644
index 0000000000..aa9044f27f
--- /dev/null
+++ b/patches.drivers/qed-remove-redundant-functions-qed_set_gft_event_id_.patch
@@ -0,0 +1,39 @@
+From: YueHaibing <yuehaibing@huawei.com>
+Date: Fri, 27 Jul 2018 21:24:27 +0800
+Subject: qed: remove redundant functions qed_set_gft_event_id_cm_hdr
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: 4be90c79d6de941216fdaeb0e76647c48877ffd5
+References: bsc#1086314 FATE#324886
+
+There are no in-tree callers of qed_set_gft_event_id_cm_hdr.
+
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
+@@ -1225,19 +1225,6 @@ void qed_gft_disable(struct qed_hwfn *p_
+ 0);
+ }
+
+-void qed_set_gft_event_id_cm_hdr(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
+-{
+- u32 rfs_cm_hdr_event_id;
+-
+- /* Set RFS event ID to be awakened i Tstorm By Prs */
+- rfs_cm_hdr_event_id = qed_rd(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT);
+- rfs_cm_hdr_event_id |= T_ETH_PACKET_ACTION_GFT_EVENTID <<
+- PRS_REG_CM_HDR_GFT_EVENT_ID_SHIFT;
+- rfs_cm_hdr_event_id |= PARSER_ETH_CONN_GFT_ACTION_CM_HDR <<
+- PRS_REG_CM_HDR_GFT_CM_HDR_SHIFT;
+- qed_wr(p_hwfn, p_ptt, PRS_REG_CM_HDR_GFT, rfs_cm_hdr_event_id);
+-}
+-
+ void qed_gft_config(struct qed_hwfn *p_hwfn,
+ struct qed_ptt *p_ptt,
+ u16 pf_id,
diff --git a/patches.drivers/qed-remove-redundant-pointer-name.patch b/patches.drivers/qed-remove-redundant-pointer-name.patch
new file mode 100644
index 0000000000..b466bfccb5
--- /dev/null
+++ b/patches.drivers/qed-remove-redundant-pointer-name.patch
@@ -0,0 +1,39 @@
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 4 Jul 2018 13:06:26 +0100
+Subject: qed: remove redundant pointer 'name'
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: 9b0bb10a84ffbbbb9f589122e34ceee0194ea5ca
+References: bsc#1086314 FATE#324886
+
+Pointer 'name' is being assigned but is never used hence it is
+redundant and can be removed.
+
+Cleans up clang warning:
+warning: variable 'name' set but not used [-Wunused-but-set-variable]
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+@@ -221,7 +221,6 @@ qed_dcbx_update_app_info(struct qed_dcbx
+ struct qed_hw_info *p_info = &p_hwfn->hw_info;
+ enum qed_pci_personality personality;
+ enum dcbx_protocol_type id;
+- char *name;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) {
+@@ -231,7 +230,6 @@ qed_dcbx_update_app_info(struct qed_dcbx
+ continue;
+
+ personality = qed_dcbx_app_update[i].personality;
+- name = qed_dcbx_app_update[i].name;
+
+ qed_dcbx_set_params(p_data, p_info, enable,
+ prio, tc, type, personality);
diff --git a/patches.drivers/qed-use-dma_zalloc_coherent-instead-of-allocator-mem.patch b/patches.drivers/qed-use-dma_zalloc_coherent-instead-of-allocator-mem.patch
new file mode 100644
index 0000000000..2e93fdd7a5
--- /dev/null
+++ b/patches.drivers/qed-use-dma_zalloc_coherent-instead-of-allocator-mem.patch
@@ -0,0 +1,38 @@
+From: YueHaibing <yuehaibing@huawei.com>
+Date: Mon, 4 Jun 2018 21:10:31 +0800
+Subject: qed: use dma_zalloc_coherent instead of allocator/memset
+Patch-mainline: v4.18-rc1
+Git-commit: ff2e351e1928b5b81a23d78e3e4effc24db007b9
+References: bsc#1086314 FATE#324886
+
+Use dma_zalloc_coherent instead of dma_alloc_coherent
+followed by memset 0.
+
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Acked-by: Tomer Tayar <Tomer.Tayar@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qed/qed_cxt.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+@@ -937,14 +937,13 @@ static int qed_cxt_src_t2_alloc(struct q
+ u32 size = min_t(u32, total_size, psz);
+ void **p_virt = &p_mngr->t2[i].p_virt;
+
+- *p_virt = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
+- size,
+- &p_mngr->t2[i].p_phys, GFP_KERNEL);
++ *p_virt = dma_zalloc_coherent(&p_hwfn->cdev->pdev->dev,
++ size, &p_mngr->t2[i].p_phys,
++ GFP_KERNEL);
+ if (!p_mngr->t2[i].p_virt) {
+ rc = -ENOMEM;
+ goto t2_fail;
+ }
+- memset(*p_virt, 0, size);
+ p_mngr->t2[i].size = size;
+ total_size -= size;
+ }
diff --git a/patches.drivers/qede-Add-driver-callbacks-for-eeprom-module-query.patch b/patches.drivers/qede-Add-driver-callbacks-for-eeprom-module-query.patch
new file mode 100644
index 0000000000..31159eda54
--- /dev/null
+++ b/patches.drivers/qede-Add-driver-callbacks-for-eeprom-module-query.patch
@@ -0,0 +1,122 @@
+From: Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>
+Date: Wed, 18 Jul 2018 06:27:23 -0700
+Subject: qede: Add driver callbacks for eeprom module query.
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+Git-commit: 97df0d65623b1a6e090df0a8298b8349d538c67e
+References: bsc#1086314 FATE#324886
+
+This patch implements the ethtool callbacks for querying sfp/eeprom module.
+
+Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
+Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+---
+ drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 88 ++++++++++++++++++++++++
+ 1 file changed, 88 insertions(+)
+
+--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
++++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+@@ -1780,6 +1780,92 @@ static int qede_set_eee(struct net_devic
+ return 0;
+ }
+
++static int qede_get_module_info(struct net_device *dev,
++ struct ethtool_modinfo *modinfo)
++{
++ struct qede_dev *edev = netdev_priv(dev);
++ u8 buf[4];
++ int rc;
++
++ /* Read first 4 bytes to find the sfp type */
++ rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
++ QED_I2C_DEV_ADDR_A0, 0, 4);
++ if (rc) {
++ DP_ERR(edev, "Failed reading EEPROM data %d\n", rc);
++ return rc;
++ }
++
++ switch (buf[0]) {
++ case 0x3: /* SFP, SFP+, SFP-28 */
++ modinfo->type = ETH_MODULE_SFF_8472;
++ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
++ break;
++ case 0xc: /* QSFP */
++ case 0xd: /* QSFP+ */
++ modinfo->type = ETH_MODULE_SFF_8436;
++ modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
++ break;
++ case 0x11: /* QSFP-28 */
++ modinfo->type = ETH_MODULE_SFF_8636;
++ modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
++ break;
++ default:
++ DP_ERR(edev, "Unknown transceiver type 0x%x\n", buf[0]);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int qede_get_module_eeprom(struct net_device *dev,
++ struct ethtool_eeprom *ee, u8 *data)
++{
++ struct qede_dev *edev = netdev_priv(dev);
++ u32 start_addr = ee->offset, size = 0;
++ u8 *buf = data;
++ int rc = 0;
++
++ /* Read A0 section */
++ if (ee->offset < ETH_MODULE_SFF_8079_LEN) {
++ /* Limit transfer size to the A0 section boundary */
++ if (ee->offset + ee->len > ETH_MODULE_SFF_8079_LEN)
++ size = ETH_MODULE_SFF_8079_LEN - ee->offset;
++ else
++ size = ee->len;
++
++ rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
++ QED_I2C_DEV_ADDR_A0,
++ start_addr, size);
++ if (rc) {
++ DP_ERR(edev, "Failed reading A0 section %d\n", rc);
++ return rc;
++ }
++
++ buf += size;
++ start_addr += size;
++ }
++
++ /* Read A2 section */
++ if (start_addr >= ETH_MODULE_SFF_8079_LEN &&
++ start_addr < ETH_MODULE_SFF_8472_LEN) {
++ size = ee->len - size;
++ /* Limit transfer size to the A2 section boundary */
++ if (start_addr + size > ETH_MODULE_SFF_8472_LEN)
++ size = ETH_MODULE_SFF_8472_LEN - start_addr;
++ start_addr -= ETH_MODULE_SFF_8079_LEN;
++ rc = edev->ops->common->read_module_eeprom(edev->cdev, buf,
++ QED_I2C_DEV_ADDR_A2,
++ start_addr, size);
++ if (rc) {
++ DP_VERBOSE(edev, QED_MSG_DEBUG,
++ "Failed reading A2 section %d\n", rc);
++ return 0;
++ }
++ }
++
++ return rc;
++}
++
+ static const struct ethtool_ops qede_ethtool_ops = {
+ .get_link_ksettings = qede_get_link_ksettings,
+ .set_link_ksettings = qede_set_link_ksettings,
+@@ -1813,6 +1899,8 @@ static const struct ethtool_ops qede_eth
+ .get_channels = qede_get_channels,
+ .set_channels = qede_set_channels,
+ .self_test = qede_self_test,
++ .get_module_info = qede_get_module_info,
++ .get_module_eeprom = qede_get_module_eeprom,
+ .get_eee = qede_get_eee,
+ .set_eee = qede_set_eee,
+
diff --git a/patches.drivers/scsi-ata-enhance-the-definition-of-set-max-feature-field-value.patch b/patches.drivers/scsi-ata-enhance-the-definition-of-set-max-feature-field-value.patch
new file mode 100644
index 0000000000..7b58fc0a5a
--- /dev/null
+++ b/patches.drivers/scsi-ata-enhance-the-definition-of-set-max-feature-field-value.patch
@@ -0,0 +1,33 @@
+From: chenxiang <chenxiang66@hisilicon.com>
+Date: Thu, 28 Dec 2017 18:20:46 +0800
+Subject: scsi: ata: enhance the definition of SET MAX feature field value
+Git-commit: d5c15c2c22a8d4e0e82ca95eac5a6ccd175c0762
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+There are two other values for SET MAX feature field according to ata
+protocol. So definite them.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ include/linux/ata.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/ata.h b/include/linux/ata.h
+index c7a353825450..40d150ad7e07 100644
+--- a/include/linux/ata.h
++++ b/include/linux/ata.h
+@@ -448,6 +448,8 @@ enum {
+ ATA_SET_MAX_LOCK = 0x02,
+ ATA_SET_MAX_UNLOCK = 0x03,
+ ATA_SET_MAX_FREEZE_LOCK = 0x04,
++ ATA_SET_MAX_PASSWD_DMA = 0x05,
++ ATA_SET_MAX_UNLOCK_DMA = 0x06,
+
+ /* feature values for DEVICE CONFIGURATION OVERLAY */
+ ATA_DCO_RESTORE = 0xC0,
+
diff --git a/patches.drivers/scsi-hisi_sas-add-an-mechanism-to-do-reset-work-synchronously.patch b/patches.drivers/scsi-hisi_sas-add-an-mechanism-to-do-reset-work-synchronously.patch
new file mode 100644
index 0000000000..82614d20b0
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-an-mechanism-to-do-reset-work-synchronously.patch
@@ -0,0 +1,110 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:38 +0800
+Subject: scsi: hisi_sas: add an mechanism to do reset work synchronously
+Git-commit: e402acdb664134f948b62d13b7db866295689f38
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Sometimes it is required to know when the controller reset has completed and
+also if it has completed successfully. For such places, we call
+hisi_sas_controller_reset() directly before. That may lead to multiple calls
+to this function.
+
+This patch create a per-reset structure which contains a completion structure
+and status flag to know when the reset completes and also the status. It is
+also in hisi_hba.wq to do reset work.
+
+As all host reset works are done in hisi_hba.wq, we don't worry multiple calls
+to hisi_sas_controller_reset().
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 26 ++++++++++++++++++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 19 ++++++++++++++++++-
+ 2 files changed, 44 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index b2534caed45a..71bc8eaac99e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -99,6 +99,31 @@ struct hisi_sas_hw_error {
+ const struct hisi_sas_hw_error *sub;
+ };
+
++struct hisi_sas_rst {
++ struct hisi_hba *hisi_hba;
++ struct completion *completion;
++ struct work_struct work;
++ bool done;
++};
++
++#define HISI_SAS_RST_WORK_INIT(r, c) \
++ { .hisi_hba = hisi_hba, \
++ .completion = &c, \
++ .work = __WORK_INITIALIZER(r.work, \
++ hisi_sas_sync_rst_work_handler), \
++ .done = false, \
++ }
++
++#define HISI_SAS_DECLARE_RST_WORK_ON_STACK(r) \
++ DECLARE_COMPLETION_ONSTACK(c); \
++ DECLARE_WORK(w, hisi_sas_sync_rst_work_handler); \
++ struct hisi_sas_rst r = HISI_SAS_RST_WORK_INIT(r, c)
++
++enum hisi_sas_bit_err_type {
++ HISI_SAS_ERR_SINGLE_BIT_ECC = 0x0,
++ HISI_SAS_ERR_MULTI_BIT_ECC = 0x1,
++};
++
+ struct hisi_sas_phy {
+ struct hisi_hba *hisi_hba;
+ struct hisi_sas_port *port;
+@@ -426,5 +451,6 @@ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot);
+ extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba);
+ extern void hisi_sas_rst_work_handler(struct work_struct *work);
++extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);
+ extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba);
+ #endif
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index e4b30922a75d..fb162c06ac83 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1299,8 +1299,14 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun)
+ static int hisi_sas_clear_nexus_ha(struct sas_ha_struct *sas_ha)
+ {
+ struct hisi_hba *hisi_hba = sas_ha->lldd_ha;
++ HISI_SAS_DECLARE_RST_WORK_ON_STACK(r);
+
+- return hisi_sas_controller_reset(hisi_hba);
++ queue_work(hisi_hba->wq, &r.work);
++ wait_for_completion(r.completion);
++ if (r.done)
++ return TMF_RESP_FUNC_COMPLETE;
++
++ return TMF_RESP_FUNC_FAILED;
+ }
+
+ static int hisi_sas_query_task(struct sas_task *task)
+@@ -1820,6 +1826,17 @@ void hisi_sas_rst_work_handler(struct work_struct *work)
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_rst_work_handler);
+
++void hisi_sas_sync_rst_work_handler(struct work_struct *work)
++{
++ struct hisi_sas_rst *rst =
++ container_of(work, struct hisi_sas_rst, work);
++
++ if (!hisi_sas_controller_reset(rst->hisi_hba))
++ rst->done = true;
++ complete(rst->completion);
++}
++EXPORT_SYMBOL_GPL(hisi_sas_sync_rst_work_handler);
++
+ int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba)
+ {
+ struct device *dev = hisi_hba->dev;
+
diff --git a/patches.drivers/scsi-hisi_sas-add-check-of-device-in-hisi_sas_task_exec.patch b/patches.drivers/scsi-hisi_sas-add-check-of-device-in-hisi_sas_task_exec.patch
new file mode 100644
index 0000000000..06615292dd
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-check-of-device-in-hisi_sas_task_exec.patch
@@ -0,0 +1,95 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 9 May 2018 23:10:50 +0800
+Subject: scsi: hisi_sas: add check of device in hisi_sas_task_exec()
+Git-commit: 2f6bca202b78e2b63a62b46ff5dc26f300785e23
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Currently we don't check that device is not gone before dereferencing
+its elements in the function hisi_sas_task_exec() (specifically, the DQ
+pointer).
+
+This patch fixes this issue by filling in the DQ pointer in
+hisi_sas_task_prep() after we check that the device pointer is still
+safe to reference.
+
+[mkp: typo]
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index a451625b8253..39f694eb7b00 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -310,12 +310,13 @@ static void hisi_sas_slot_abort(struct work_struct *work)
+ task->task_done(task);
+ }
+
+-static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq *dq,
++static int hisi_sas_task_prep(struct sas_task *task,
++ struct hisi_sas_dq **dq_pointer,
+ int is_tmf, struct hisi_sas_tmf_task *tmf,
+ int *pass)
+ {
+- struct hisi_hba *hisi_hba = dq->hisi_hba;
+ struct domain_device *device = task->dev;
++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_sas_port *port;
+ struct hisi_sas_slot *slot;
+@@ -323,8 +324,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq *dq,
+ struct asd_sas_port *sas_port = device->port;
+ struct device *dev = hisi_hba->dev;
+ int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
+- int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
++ int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
+ unsigned long flags, flags_dq;
++ struct hisi_sas_dq *dq;
+ int wr_q_index;
+
+ if (!sas_port) {
+@@ -352,6 +354,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq *dq,
+ return -ECOMM;
+ }
+
++ *dq_pointer = dq = sas_dev->dq;
++
+ port = to_hisi_sas_port(sas_port);
+ if (port && !port->port_attached) {
+ dev_info(dev, "task prep: %s port%d not attach device\n",
+@@ -520,22 +524,21 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
+ unsigned long flags;
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev);
+ struct device *dev = hisi_hba->dev;
+- struct domain_device *device = task->dev;
+- struct hisi_sas_device *sas_dev = device->lldd_dev;
+- struct hisi_sas_dq *dq = sas_dev->dq;
++ struct hisi_sas_dq *dq = NULL;
+
+ if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags)))
+ return -EINVAL;
+
+ /* protect task_prep and start_delivery sequence */
+- rc = hisi_sas_task_prep(task, dq, is_tmf, tmf, &pass);
++ rc = hisi_sas_task_prep(task, &dq, is_tmf, tmf, &pass);
+ if (rc)
+ dev_err(dev, "task exec: failed[%d]!\n", rc);
+
+- spin_lock_irqsave(&dq->lock, flags);
+- if (likely(pass))
++ if (likely(pass)) {
++ spin_lock_irqsave(&dq->lock, flags);
+ hisi_hba->hw->start_delivery(dq);
+- spin_unlock_irqrestore(&dq->lock, flags);
++ spin_unlock_irqrestore(&dq->lock, flags);
++ }
+
+ return rc;
+ }
+
diff --git a/patches.drivers/scsi-hisi_sas-add-internal-abort-dev-in-some-places.patch b/patches.drivers/scsi-hisi_sas-add-internal-abort-dev-in-some-places.patch
new file mode 100644
index 0000000000..dd9e47990b
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-internal-abort-dev-in-some-places.patch
@@ -0,0 +1,73 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:47 +0800
+Subject: scsi: hisi_sas: add internal abort dev in some places
+Git-commit: 2a03813123c4beb0b60be6b3b65a6b30f7124579
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+We should do internal abort dev before TMF_ABORT_TASK_SET and TMF_LU_RESET.
+Because we may only have done internal abort for single IO in the earlier part
+of SCSI EH process. Even the internal abort to the single IO, we also don't
+know whether it is successful.
+
+Besides, we should release slots of the device in hisi_sas_abort_task_set() if
+the abort is successful.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 1b9c48c99968..302da84bf9ef 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1238,12 +1238,29 @@ static int hisi_sas_abort_task(struct sas_task *task)
+
+ static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun)
+ {
++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
++ struct device *dev = hisi_hba->dev;
+ struct hisi_sas_tmf_task tmf_task;
+ int rc = TMF_RESP_FUNC_FAILED;
++ unsigned long flags;
++
++ rc = hisi_sas_internal_task_abort(hisi_hba, device,
++ HISI_SAS_INT_ABT_DEV, 0);
++ if (rc < 0) {
++ dev_err(dev, "abort task set: internal abort rc=%d\n", rc);
++ return TMF_RESP_FUNC_FAILED;
++ }
++ hisi_sas_dereg_device(hisi_hba, device);
+
+ tmf_task.tmf = TMF_ABORT_TASK_SET;
+ rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task);
+
++ if (rc == TMF_RESP_FUNC_COMPLETE) {
++ spin_lock_irqsave(&hisi_hba->lock, flags);
++ hisi_sas_release_task(hisi_hba, device);
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ }
++
+ return rc;
+ }
+
+@@ -1333,6 +1350,14 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun)
+ } else {
+ struct hisi_sas_tmf_task tmf_task = { .tmf = TMF_LU_RESET };
+
++ rc = hisi_sas_internal_task_abort(hisi_hba, device,
++ HISI_SAS_INT_ABT_DEV, 0);
++ if (rc < 0) {
++ dev_err(dev, "lu_reset: internal abort failed\n");
++ goto out;
++ }
++ hisi_sas_dereg_device(hisi_hba, device);
++
+ rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task);
+ if (rc == TMF_RESP_FUNC_COMPLETE) {
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+
diff --git a/patches.drivers/scsi-hisi_sas-add-led-feature-for-v3-hw.patch b/patches.drivers/scsi-hisi_sas-add-led-feature-for-v3-hw.patch
new file mode 100644
index 0000000000..0afd673947
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-led-feature-for-v3-hw.patch
@@ -0,0 +1,95 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Mon, 21 May 2018 18:09:16 +0800
+Subject: scsi: hisi_sas: Add LED feature for v3 hw
+Git-commit: 428f1b3424f4fe750943d8cdd1b0dafad99b0b75
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+This patch implements LED feature of directly attached disk for v3 hw.
+
+In fact, this hw has created an SGPIO component for LED feature, and we can
+control LEDs just by internal registers.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 42 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 0a80a39eccdd..a043d9cdbf48 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -107,6 +107,10 @@
+ #define AWQOS_AWCACHE_CFG 0xc84
+ #define ARQOS_ARCACHE_CFG 0xc88
+ #define HILINK_ERR_DFX 0xe04
++#define SAS_GPIO_CFG_0 0x1000
++#define SAS_GPIO_CFG_1 0x1004
++#define SAS_GPIO_TX_0_1 0x1040
++#define SAS_CFG_DRIVE_VLD 0x1070
+
+ /* phy registers requiring init */
+ #define PORT_BASE (0x2000)
+@@ -549,6 +553,14 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_write32(hisi_hba, SAS_RAS_INTR1_MASK, 0x0);
+ hisi_sas_write32(hisi_hba, SAS_RAS_INTR2_MASK, 0x0);
+ hisi_sas_write32(hisi_hba, CFG_SAS_RAS_INTR_MASK, 0x0);
++
++ /* LED registers init */
++ hisi_sas_write32(hisi_hba, SAS_CFG_DRIVE_VLD, 0x80000ff);
++ hisi_sas_write32(hisi_hba, SAS_GPIO_TX_0_1, 0x80808080);
++ hisi_sas_write32(hisi_hba, SAS_GPIO_TX_0_1 + 0x4, 0x80808080);
++ /* Configure blink generator rate A to 1Hz and B to 4Hz */
++ hisi_sas_write32(hisi_hba, SAS_GPIO_CFG_1, 0x121700);
++ hisi_sas_write32(hisi_hba, SAS_GPIO_CFG_0, 0x800000);
+ }
+
+ static void config_phy_opt_mode_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+@@ -1974,6 +1986,35 @@ static int soft_reset_v3_hw(struct hisi_hba *hisi_hba)
+ return hw_init_v3_hw(hisi_hba);
+ }
+
++static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type,
++ u8 reg_index, u8 reg_count, u8 *write_data)
++{
++ struct device *dev = hisi_hba->dev;
++ u32 *data = (u32 *)write_data;
++ int i;
++
++ switch (reg_type) {
++ case SAS_GPIO_REG_TX:
++ if ((reg_index + reg_count) > ((hisi_hba->n_phy + 3) / 4)) {
++ dev_err(dev, "write gpio: invalid reg range[%d, %d]\n",
++ reg_index, reg_index + reg_count - 1);
++ return -EINVAL;
++ }
++
++ for (i = 0; i < reg_count; i++)
++ hisi_sas_write32(hisi_hba,
++ SAS_GPIO_TX_0_1 + (reg_index + i) * 4,
++ data[i]);
++ break;
++ default:
++ dev_err(dev, "write gpio: unsupported or bad reg type %d\n",
++ reg_type);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
+ static const struct hisi_sas_hw hisi_sas_v3_hw = {
+ .hw_init = hisi_sas_v3_init,
+ .setup_itct = setup_itct_v3_hw,
+@@ -1999,6 +2040,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
+ .soft_reset = soft_reset_v3_hw,
+ .get_phys_state = get_phys_state_v3_hw,
+ .get_events = phy_get_events_v3_hw,
++ .write_gpio = write_gpio_v3_hw,
+ };
+
+ static struct Scsi_Host *
+
diff --git a/patches.drivers/scsi-hisi_sas-add-ras-feature-for-v3-hw.patch b/patches.drivers/scsi-hisi_sas-add-ras-feature-for-v3-hw.patch
new file mode 100644
index 0000000000..f148241156
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-ras-feature-for-v3-hw.patch
@@ -0,0 +1,200 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:40 +0800
+Subject: scsi: hisi_sas: add RAS feature for v3 hw
+Git-commit: 1aaf81e0e34988ff56b317b568f92fe6ca447da2
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+We use PCIe AER to support RAS feature for v3 hw. This driver should do
+following two things to support this:
+
+1. Enable RAS interrupts, so that errors can be reported to RAS module.
+
+2. Realize err_handler for sas_v3_pci_driver. Then if non-fatal error is
+ detected, print error source and try to recover SAS controller.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 139 +++++++++++++++++++++++++++++++++
+ 1 file changed, 139 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 69aa7bc15783..d356e12d7b98 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -204,6 +204,13 @@
+ #define AM_ROB_ECC_MULBIT_ERR_ADDR_OFF 8
+ #define AM_ROB_ECC_MULBIT_ERR_ADDR_MSK (0xff << AM_ROB_ECC_MULBIT_ERR_ADDR_OFF)
+
++/* RAS registers need init */
++#define RAS_BASE (0x6000)
++#define SAS_RAS_INTR0 (RAS_BASE)
++#define SAS_RAS_INTR1 (RAS_BASE + 0x04)
++#define SAS_RAS_INTR0_MASK (RAS_BASE + 0x08)
++#define SAS_RAS_INTR1_MASK (RAS_BASE + 0x0c)
++
+ /* HW dma structures */
+ /* Delivery queue header */
+ /* dw0 */
+@@ -496,6 +503,10 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+
+ hisi_sas_write32(hisi_hba, SATA_INITI_D2H_STORE_ADDR_HI,
+ upper_32_bits(hisi_hba->initial_fis_dma));
++
++ /* RAS registers init */
++ hisi_sas_write32(hisi_hba, SAS_RAS_INTR0_MASK, 0x0);
++ hisi_sas_write32(hisi_hba, SAS_RAS_INTR1_MASK, 0x0);
+ }
+
+ static void config_phy_opt_mode_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+@@ -2129,6 +2140,127 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
+ scsi_host_put(shost);
+ }
+
++static const struct hisi_sas_hw_error sas_ras_intr0_nfe[] = {
++ { .irq_msk = BIT(19), .msg = "HILINK_INT" },
++ { .irq_msk = BIT(20), .msg = "HILINK_PLL0_OUT_OF_LOCK" },
++ { .irq_msk = BIT(21), .msg = "HILINK_PLL1_OUT_OF_LOCK" },
++ { .irq_msk = BIT(22), .msg = "HILINK_LOSS_OF_REFCLK0" },
++ { .irq_msk = BIT(23), .msg = "HILINK_LOSS_OF_REFCLK1" },
++ { .irq_msk = BIT(24), .msg = "DMAC0_TX_POISON" },
++ { .irq_msk = BIT(25), .msg = "DMAC1_TX_POISON" },
++ { .irq_msk = BIT(26), .msg = "DMAC2_TX_POISON" },
++ { .irq_msk = BIT(27), .msg = "DMAC3_TX_POISON" },
++ { .irq_msk = BIT(28), .msg = "DMAC4_TX_POISON" },
++ { .irq_msk = BIT(29), .msg = "DMAC5_TX_POISON" },
++ { .irq_msk = BIT(30), .msg = "DMAC6_TX_POISON" },
++ { .irq_msk = BIT(31), .msg = "DMAC7_TX_POISON" },
++};
++
++static const struct hisi_sas_hw_error sas_ras_intr1_nfe[] = {
++ { .irq_msk = BIT(0), .msg = "RXM_CFG_MEM3_ECC2B_INTR" },
++ { .irq_msk = BIT(1), .msg = "RXM_CFG_MEM2_ECC2B_INTR" },
++ { .irq_msk = BIT(2), .msg = "RXM_CFG_MEM1_ECC2B_INTR" },
++ { .irq_msk = BIT(3), .msg = "RXM_CFG_MEM0_ECC2B_INTR" },
++ { .irq_msk = BIT(4), .msg = "HGC_CQE_ECC2B_INTR" },
++ { .irq_msk = BIT(5), .msg = "LM_CFG_IOSTL_ECC2B_INTR" },
++ { .irq_msk = BIT(6), .msg = "LM_CFG_ITCTL_ECC2B_INTR" },
++ { .irq_msk = BIT(7), .msg = "HGC_ITCT_ECC2B_INTR" },
++ { .irq_msk = BIT(8), .msg = "HGC_IOST_ECC2B_INTR" },
++ { .irq_msk = BIT(9), .msg = "HGC_DQE_ECC2B_INTR" },
++ { .irq_msk = BIT(10), .msg = "DMAC0_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(11), .msg = "DMAC1_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(12), .msg = "DMAC2_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(13), .msg = "DMAC3_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(14), .msg = "DMAC4_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(15), .msg = "DMAC5_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(16), .msg = "DMAC6_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(17), .msg = "DMAC7_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(18), .msg = "OOO_RAM_ECC2B_INTR" },
++ { .irq_msk = BIT(20), .msg = "HGC_DQE_POISON_INTR" },
++ { .irq_msk = BIT(21), .msg = "HGC_IOST_POISON_INTR" },
++ { .irq_msk = BIT(22), .msg = "HGC_ITCT_POISON_INTR" },
++ { .irq_msk = BIT(23), .msg = "HGC_ITCT_NCQ_POISON_INTR" },
++ { .irq_msk = BIT(24), .msg = "DMAC0_RX_POISON" },
++ { .irq_msk = BIT(25), .msg = "DMAC1_RX_POISON" },
++ { .irq_msk = BIT(26), .msg = "DMAC2_RX_POISON" },
++ { .irq_msk = BIT(27), .msg = "DMAC3_RX_POISON" },
++ { .irq_msk = BIT(28), .msg = "DMAC4_RX_POISON" },
++ { .irq_msk = BIT(29), .msg = "DMAC5_RX_POISON" },
++ { .irq_msk = BIT(30), .msg = "DMAC6_RX_POISON" },
++ { .irq_msk = BIT(31), .msg = "DMAC7_RX_POISON" },
++};
++
++static bool process_non_fatal_error_v3_hw(struct hisi_hba *hisi_hba)
++{
++ struct device *dev = hisi_hba->dev;
++ const struct hisi_sas_hw_error *ras_error;
++ bool need_reset = false;
++ u32 irq_value;
++ int i;
++
++ irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR0);
++ for (i = 0; i < ARRAY_SIZE(sas_ras_intr0_nfe); i++) {
++ ras_error = &sas_ras_intr0_nfe[i];
++ if (ras_error->irq_msk & irq_value) {
++ dev_warn(dev, "SAS_RAS_INTR0: %s(irq_value=0x%x) found.\n",
++ ras_error->msg, irq_value);
++ need_reset = true;
++ }
++ }
++ hisi_sas_write32(hisi_hba, SAS_RAS_INTR0, irq_value);
++
++ irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR1);
++ for (i = 0; i < ARRAY_SIZE(sas_ras_intr1_nfe); i++) {
++ ras_error = &sas_ras_intr1_nfe[i];
++ if (ras_error->irq_msk & irq_value) {
++ dev_warn(dev, "SAS_RAS_INTR1: %s(irq_value=0x%x) found.\n",
++ ras_error->msg, irq_value);
++ need_reset = true;
++ }
++ }
++ hisi_sas_write32(hisi_hba, SAS_RAS_INTR1, irq_value);
++
++ return need_reset;
++}
++
++static pci_ers_result_t hisi_sas_error_detected_v3_hw(struct pci_dev *pdev,
++ pci_channel_state_t state)
++{
++ struct sas_ha_struct *sha = pci_get_drvdata(pdev);
++ struct hisi_hba *hisi_hba = sha->lldd_ha;
++ struct device *dev = hisi_hba->dev;
++
++ dev_info(dev, "PCI error: detected callback, state(%d)!!\n", state);
++ if (state == pci_channel_io_perm_failure)
++ return PCI_ERS_RESULT_DISCONNECT;
++
++ if (process_non_fatal_error_v3_hw(hisi_hba))
++ return PCI_ERS_RESULT_NEED_RESET;
++
++ return PCI_ERS_RESULT_CAN_RECOVER;
++}
++
++static pci_ers_result_t hisi_sas_mmio_enabled_v3_hw(struct pci_dev *pdev)
++{
++ return PCI_ERS_RESULT_RECOVERED;
++}
++
++static pci_ers_result_t hisi_sas_slot_reset_v3_hw(struct pci_dev *pdev)
++{
++ struct sas_ha_struct *sha = pci_get_drvdata(pdev);
++ struct hisi_hba *hisi_hba = sha->lldd_ha;
++ struct device *dev = hisi_hba->dev;
++ HISI_SAS_DECLARE_RST_WORK_ON_STACK(r);
++
++ dev_info(dev, "PCI error: slot reset callback!!\n");
++ queue_work(hisi_hba->wq, &r.work);
++ wait_for_completion(r.completion);
++ if (r.done)
++ return PCI_ERS_RESULT_RECOVERED;
++
++ return PCI_ERS_RESULT_DISCONNECT;
++}
++
+ enum {
+ /* instances of the controller */
+ hip08,
+@@ -2139,11 +2271,18 @@ static const struct pci_device_id sas_v3_pci_table[] = {
+ {}
+ };
+
++static const struct pci_error_handlers hisi_sas_err_handler = {
++ .error_detected = hisi_sas_error_detected_v3_hw,
++ .mmio_enabled = hisi_sas_mmio_enabled_v3_hw,
++ .slot_reset = hisi_sas_slot_reset_v3_hw,
++};
++
+ static struct pci_driver sas_v3_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = sas_v3_pci_table,
+ .probe = hisi_sas_v3_probe,
+ .remove = hisi_sas_v3_remove,
++ .err_handler = &hisi_sas_err_handler,
+ };
+
+ module_pci_driver(sas_v3_pci_driver);
+
diff --git a/patches.drivers/scsi-hisi_sas-add-readl-poll-timeout-helper-wrappers.patch b/patches.drivers/scsi-hisi_sas-add-readl-poll-timeout-helper-wrappers.patch
new file mode 100644
index 0000000000..c5e2d92e2f
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-readl-poll-timeout-helper-wrappers.patch
@@ -0,0 +1,78 @@
+From: John Garry <john.garry@huawei.com>
+Date: Wed, 2 May 2018 23:56:33 +0800
+Subject: scsi: hisi_sas: add readl poll timeout helper wrappers
+Git-commit: 9b8addf3024eb57a215d0af2e1c95cd44b94ccab
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+It is common to use readl poll timeout helpers in the driver, so create
+custom wrappers.
+
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index d6e705ff9dad..28bb71e3b093 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -394,6 +394,20 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
+ return readl(regs);
+ }
+
++#define hisi_sas_read32_poll_timeout(off, val, cond, delay_us, \
++ timeout_us) \
++({ \
++ void __iomem *regs = hisi_hba->regs + off; \
++ readl_poll_timeout(regs, val, cond, delay_us, timeout_us); \
++})
++
++#define hisi_sas_read32_poll_timeout_atomic(off, val, cond, delay_us, \
++ timeout_us) \
++({ \
++ void __iomem *regs = hisi_hba->regs + off; \
++ readl_poll_timeout_atomic(regs, val, cond, delay_us, timeout_us);\
++})
++
+ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ {
+ struct pci_dev *pdev = hisi_hba->pci_dev;
+@@ -684,8 +698,8 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba)
+ udelay(50);
+
+ /* Ensure axi bus idle */
+- ret = readl_poll_timeout(hisi_hba->regs + AXI_CFG, val, !val,
+- 20000, 1000000);
++ ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val,
++ 20000, 1000000);
+ if (ret) {
+ dev_err(dev, "axi bus is not idle, ret = %d!\n", ret);
+ return -EIO;
+@@ -1977,8 +1991,9 @@ static int soft_reset_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE + AM_CTRL_GLOBAL, 0x1);
+
+ /* wait until bus idle */
+- rc = readl_poll_timeout(hisi_hba->regs + AXI_MASTER_CFG_BASE +
+- AM_CURR_TRANS_RETURN, status, status == 0x3, 10, 100);
++ rc = hisi_sas_read32_poll_timeout(AXI_MASTER_CFG_BASE +
++ AM_CURR_TRANS_RETURN, status,
++ status == 0x3, 10, 100);
+ if (rc) {
+ dev_err(dev, "axi bus is not idle, rc = %d\n", rc);
+ return rc;
+@@ -2396,8 +2411,9 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
+ AM_CTRL_GLOBAL, reg_val);
+
+ /* wait until bus idle */
+- rc = readl_poll_timeout(hisi_hba->regs + AXI_MASTER_CFG_BASE +
+- AM_CURR_TRANS_RETURN, status, status == 0x3, 10, 100);
++ rc = hisi_sas_read32_poll_timeout(AXI_MASTER_CFG_BASE +
++ AM_CURR_TRANS_RETURN, status,
++ status == 0x3, 10, 100);
+ if (rc) {
+ dev_err(dev, "axi bus is not idle, rc = %d\n", rc);
+ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+
diff --git a/patches.drivers/scsi-hisi_sas-add-some-checks-to-avoid-free-ing-a-sas_task-twice.patch b/patches.drivers/scsi-hisi_sas-add-some-checks-to-avoid-free-ing-a-sas_task-twice.patch
new file mode 100644
index 0000000000..5cd9fdfcae
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-some-checks-to-avoid-free-ing-a-sas_task-twice.patch
@@ -0,0 +1,161 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 2 May 2018 23:56:25 +0800
+Subject: scsi: hisi_sas: Add some checks to avoid free'ing a sas_task twice
+Git-commit: b81b6cce58b7912e0d35f0b5bf526cb798f8e7aa
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+If the SCSI host enters EH, any pending IO will be processed by SCSI
+EH. However it is possible that SCSI EH will try to abort the IO and
+also at the same time the IO completes in the driver. In this situation
+there is a small chance of freeing the sas_task twice.
+
+Then if another IO re-uses freed sas_task before the second time of
+free'ing sas_task, it is possible to free incorrect sas_task.
+
+To avoid this situation, add some checks to increase reliability. The
+sas_task task state flag SAS_TASK_STATE_ABORTED is used to mutually
+protect the LLDD and libsas freeing the task.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 4 ++++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 22 +++++++---------------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 21 +++++++--------------
+ 3 files changed, 18 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index d1a61b1e591b..52746e2e7f6f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1174,10 +1174,14 @@ static int hisi_sas_abort_task(struct sas_task *task)
+ return TMF_RESP_FUNC_FAILED;
+ }
+
++ spin_lock_irqsave(&task->task_state_lock, flags);
+ if (task->task_state_flags & SAS_TASK_STATE_DONE) {
++ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ rc = TMF_RESP_FUNC_COMPLETE;
+ goto out;
+ }
++ task->task_state_flags |= SAS_TASK_STATE_ABORTED;
++ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+ sas_dev->dev_status = HISI_SAS_DEV_EH;
+ if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 384e4ef50b24..8ca0044e09be 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2386,7 +2386,6 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ struct hisi_sas_complete_v2_hdr *complete_hdr =
+ &complete_queue[slot->cmplt_queue_slot];
+ unsigned long flags;
+- int aborted;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+ return -EINVAL;
+@@ -2396,7 +2395,6 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ sas_dev = device->lldd_dev;
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+- aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED;
+ task->task_state_flags &=
+ ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR);
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+@@ -2404,15 +2402,6 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ memset(ts, 0, sizeof(*ts));
+ ts->resp = SAS_TASK_COMPLETE;
+
+- if (unlikely(aborted)) {
+- dev_dbg(dev, "slot_complete: task(%p) aborted\n", task);
+- ts->stat = SAS_ABORTED_TASK;
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- return ts->stat;
+- }
+-
+ if (unlikely(!sas_dev)) {
+ dev_dbg(dev, "slot complete: port has no device\n");
+ ts->stat = SAS_PHY_DOWN;
+@@ -2523,13 +2512,16 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ }
+
+ out:
++ hisi_sas_slot_task_free(hisi_hba, task, slot);
++ sts = ts->stat;
+ spin_lock_irqsave(&task->task_state_lock, flags);
++ if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
++ spin_unlock_irqrestore(&task->task_state_lock, flags);
++ dev_info(dev, "slot complete: task(%p) aborted\n", task);
++ return SAS_ABORTED_TASK;
++ }
+ task->task_state_flags |= SAS_TASK_STATE_DONE;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- sts = ts->stat;
+
+ if (task->task_done)
+ task->task_done(task);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index afc1242abdcf..734611046d3e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1576,7 +1576,6 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ hisi_hba->complete_hdr[slot->cmplt_queue];
+ struct hisi_sas_complete_v3_hdr *complete_hdr =
+ &complete_queue[slot->cmplt_queue_slot];
+- int aborted;
+ unsigned long flags;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+@@ -1587,21 +1586,12 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ sas_dev = device->lldd_dev;
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+- aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED;
+ task->task_state_flags &=
+ ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR);
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+ memset(ts, 0, sizeof(*ts));
+ ts->resp = SAS_TASK_COMPLETE;
+- if (unlikely(aborted)) {
+- dev_dbg(dev, "slot complete: task(%p) aborted\n", task);
+- ts->stat = SAS_ABORTED_TASK;
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- return ts->stat;
+- }
+
+ if (unlikely(!sas_dev)) {
+ dev_dbg(dev, "slot complete: port has not device\n");
+@@ -1699,13 +1689,16 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ }
+
+ out:
++ hisi_sas_slot_task_free(hisi_hba, task, slot);
++ sts = ts->stat;
+ spin_lock_irqsave(&task->task_state_lock, flags);
++ if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
++ spin_unlock_irqrestore(&task->task_state_lock, flags);
++ dev_info(dev, "slot complete: task(%p) aborted\n", task);
++ return SAS_ABORTED_TASK;
++ }
+ task->task_state_flags |= SAS_TASK_STATE_DONE;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+- hisi_sas_slot_task_free(hisi_hba, task, slot);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- sts = ts->stat;
+
+ if (task->task_done)
+ task->task_done(task);
+
diff --git a/patches.drivers/scsi-hisi_sas-add-some-print-to-enhance-debugging.patch b/patches.drivers/scsi-hisi_sas-add-some-print-to-enhance-debugging.patch
new file mode 100644
index 0000000000..c9e3755c7f
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-some-print-to-enhance-debugging.patch
@@ -0,0 +1,240 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:41 +0800
+Subject: scsi: hisi_sas: add some print to enhance debugging
+Git-commit: f1c88211454ff8063b358f9ebe250f0fe429319c
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Add some print at some places such as error info and cq of exception IO,
+device found etc, and also adjust some log levels.
+
+All this to assist debugging ability.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 15 ++++++++++-----
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 24 +++++++++++++++++++-----
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 22 +++++++++++++++++-----
+ 3 files changed, 46 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index fb162c06ac83..1f6f06321c5a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -580,6 +580,9 @@ static int hisi_sas_dev_found(struct domain_device *device)
+ }
+ }
+
++ dev_info(dev, "dev[%d:%x] found\n",
++ sas_dev->device_id, sas_dev->dev_type);
++
+ return 0;
+ }
+
+@@ -735,7 +738,7 @@ static void hisi_sas_dev_gone(struct domain_device *device)
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct device *dev = hisi_hba->dev;
+
+- dev_info(dev, "found dev[%d:%x] is gone\n",
++ dev_info(dev, "dev[%d:%x] is gone\n",
+ sas_dev->device_id, sas_dev->dev_type);
+
+ if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) {
+@@ -866,12 +869,13 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device,
+ if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
+ struct hisi_sas_slot *slot = task->lldd_task;
+
+- dev_err(dev, "abort tmf: TMF task timeout\n");
++ dev_err(dev, "abort tmf: TMF task timeout and not done\n");
+ if (slot)
+ slot->task = NULL;
+
+ goto ex_err;
+- }
++ } else
++ dev_err(dev, "abort tmf: TMF task timeout\n");
+ }
+
+ if (task->task_status.resp == SAS_TASK_COMPLETE &&
+@@ -1495,9 +1499,10 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
+
+ if (slot)
+ slot->task = NULL;
+- dev_err(dev, "internal task abort: timeout.\n");
++ dev_err(dev, "internal task abort: timeout and not done.\n");
+ goto exit;
+- }
++ } else
++ dev_err(dev, "internal task abort: timeout.\n");
+ }
+
+ if (task->task_status.resp == SAS_TASK_COMPLETE &&
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index cd9cd8468829..8d6886a452ef 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2361,6 +2361,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ ts->resp = SAS_TASK_COMPLETE;
+
+ if (unlikely(aborted)) {
++ dev_dbg(dev, "slot_complete: task(%p) aborted\n", task);
+ ts->stat = SAS_ABORTED_TASK;
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_task_free(hisi_hba, task, slot);
+@@ -2405,6 +2406,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {
+ u32 err_phase = (complete_hdr->dw0 & CMPLT_HDR_ERR_PHASE_MSK)
+ >> CMPLT_HDR_ERR_PHASE_OFF;
++ u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
+
+ /* Analyse error happens on which phase TX or RX */
+ if (ERR_ON_TX_PHASE(err_phase))
+@@ -2412,6 +2414,16 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ else if (ERR_ON_RX_PHASE(err_phase))
+ slot_err_v2_hw(hisi_hba, task, slot, 2);
+
++ if (ts->stat != SAS_DATA_UNDERRUN)
++ dev_info(dev, "erroneous completion iptt=%d task=%p "
++ "CQ hdr: 0x%x 0x%x 0x%x 0x%x "
++ "Error info: 0x%x 0x%x 0x%x 0x%x\n",
++ slot->idx, task,
++ complete_hdr->dw0, complete_hdr->dw1,
++ complete_hdr->act, complete_hdr->dw3,
++ error_info[0], error_info[1],
++ error_info[2], error_info[3]);
++
+ if (unlikely(slot->abort))
+ return ts->stat;
+ goto out;
+@@ -2461,7 +2473,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ }
+
+ if (!slot->port->port_attached) {
+- dev_err(dev, "slot complete: port %d has removed\n",
++ dev_warn(dev, "slot complete: port %d has removed\n",
+ slot->port->sas_port.id);
+ ts->stat = SAS_PHY_DOWN;
+ }
+@@ -2718,10 +2730,12 @@ static int phy_down_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
+ u32 phy_state, sl_ctrl, txid_auto;
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct hisi_sas_port *port = phy->port;
++ struct device *dev = hisi_hba->dev;
+
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1);
+
+ phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
++ dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, phy_state);
+ hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0);
+
+ sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
+@@ -2911,7 +2925,7 @@ static void multi_bit_ecc_error_process_v2_hw(struct hisi_hba *hisi_hba,
+ val = hisi_sas_read32(hisi_hba, ecc_error->reg);
+ val &= ecc_error->msk;
+ val >>= ecc_error->shift;
+- dev_warn(dev, ecc_error->msg, irq_value, val);
++ dev_err(dev, ecc_error->msg, irq_value, val);
+ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
+ }
+ }
+@@ -3020,12 +3034,12 @@ static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p)
+ for (; sub->msk || sub->msg; sub++) {
+ if (!(err_value & sub->msk))
+ continue;
+- dev_warn(dev, "%s (0x%x) found!\n",
++ dev_err(dev, "%s (0x%x) found!\n",
+ sub->msg, irq_value);
+ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
+ }
+ } else {
+- dev_warn(dev, "%s (0x%x) found!\n",
++ dev_err(dev, "%s (0x%x) found!\n",
+ axi_error->msg, irq_value);
+ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
+ }
+@@ -3397,7 +3411,7 @@ static int soft_reset_v2_hw(struct hisi_hba *hisi_hba)
+
+ udelay(10);
+ if (cnt++ > 10) {
+- dev_info(dev, "wait axi bus state to idle timeout!\n");
++ dev_err(dev, "wait axi bus state to idle timeout!\n");
+ return -1;
+ }
+ }
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index d356e12d7b98..67020bdf19c1 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1149,7 +1149,7 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ struct dev_to_host_fis *fis;
+ u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};
+
+- dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
++ dev_info(dev, "phyup: phy%d link_rate=%d(sata)\n", phy_no, link_rate);
+ initial_fis = &hisi_hba->initial_fis[phy_no];
+ fis = &initial_fis->fis;
+ sas_phy->oob_mode = SATA_OOB_MODE;
+@@ -1333,7 +1333,7 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+ if (!(irq_value1 & error->irq_msk))
+ continue;
+
+- dev_warn(dev, "%s error (phy%d 0x%x) found!\n",
++ dev_err(dev, "%s error (phy%d 0x%x) found!\n",
+ error->msg, phy_no, irq_value1);
+ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
+ }
+@@ -1443,12 +1443,12 @@ static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p)
+ if (!(err_value & sub->msk))
+ continue;
+
+- dev_warn(dev, "%s error (0x%x) found!\n",
++ dev_err(dev, "%s error (0x%x) found!\n",
+ sub->msg, irq_value);
+ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
+ }
+ } else {
+- dev_warn(dev, "%s error (0x%x) found!\n",
++ dev_err(dev, "%s error (0x%x) found!\n",
+ error->msg, irq_value);
+ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
+ }
+@@ -1553,6 +1553,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ memset(ts, 0, sizeof(*ts));
+ ts->resp = SAS_TASK_COMPLETE;
+ if (unlikely(aborted)) {
++ dev_dbg(dev, "slot complete: task(%p) aborted\n", task);
+ ts->stat = SAS_ABORTED_TASK;
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_task_free(hisi_hba, task, slot);
+@@ -1594,7 +1595,18 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+
+ /* check for erroneous completion */
+ if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
++ u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
++
+ slot_err_v3_hw(hisi_hba, task, slot);
++ if (ts->stat != SAS_DATA_UNDERRUN)
++ dev_info(dev, "erroneous completion iptt=%d task=%p "
++ "CQ hdr: 0x%x 0x%x 0x%x 0x%x "
++ "Error info: 0x%x 0x%x 0x%x 0x%x\n",
++ slot->idx, task,
++ complete_hdr->dw0, complete_hdr->dw1,
++ complete_hdr->act, complete_hdr->dw3,
++ error_info[0], error_info[1],
++ error_info[2], error_info[3]);
+ if (unlikely(slot->abort))
+ return ts->stat;
+ goto out;
+@@ -1639,7 +1651,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ }
+
+ if (!slot->port->port_attached) {
+- dev_err(dev, "slot complete: port %d has removed\n",
++ dev_warn(dev, "slot complete: port %d has removed\n",
+ slot->port->sas_port.id);
+ ts->stat = SAS_PHY_DOWN;
+ }
+
diff --git a/patches.drivers/scsi-hisi_sas-add-v2-hw-force-phy-function-for-internal-ata-command.patch b/patches.drivers/scsi-hisi_sas-add-v2-hw-force-phy-function-for-internal-ata-command.patch
new file mode 100644
index 0000000000..56b3042041
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-v2-hw-force-phy-function-for-internal-ata-command.patch
@@ -0,0 +1,73 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Mon, 21 May 2018 18:09:22 +0800
+Subject: scsi: hisi_sas: Add v2 hw force PHY function for internal ATA command
+Git-commit: b09fcd09e9767f81187aa4036fb16d14e2f2fc79
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+This patch adds a force PHY function for internal ATA command for v2 hw.
+
+Because there is an SoC bug in v2 hw, and need send an IO through each PHY
+of a port to work around a bug which occurs after a controller reset.
+
+This force PHY function will be used in the later patch.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 2 ++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 11 +++++++++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 60bd652534fe..9400824f23ad 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -180,6 +180,8 @@ struct hisi_sas_device {
+ };
+
+ struct hisi_sas_tmf_task {
++ int force_phy;
++ int phy_id;
+ u8 tmf;
+ u16 tag_of_task_to_be_managed;
+ };
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index fafb3f1835be..369ef7ebb1e0 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -296,6 +296,10 @@
+ #define CMD_HDR_RESP_REPORT_MSK (0x1 << CMD_HDR_RESP_REPORT_OFF)
+ #define CMD_HDR_TLR_CTRL_OFF 6
+ #define CMD_HDR_TLR_CTRL_MSK (0x3 << CMD_HDR_TLR_CTRL_OFF)
++#define CMD_HDR_PHY_ID_OFF 8
++#define CMD_HDR_PHY_ID_MSK (0x1ff << CMD_HDR_PHY_ID_OFF)
++#define CMD_HDR_FORCE_PHY_OFF 17
++#define CMD_HDR_FORCE_PHY_MSK (0x1 << CMD_HDR_FORCE_PHY_OFF)
+ #define CMD_HDR_PORT_OFF 18
+ #define CMD_HDR_PORT_MSK (0xf << CMD_HDR_PORT_OFF)
+ #define CMD_HDR_PRIORITY_OFF 27
+@@ -2512,6 +2516,7 @@ static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ struct hisi_sas_tmf_task *tmf = slot->tmf;
+ u8 *buf_cmd;
+ int has_data = 0, hdr_tag = 0;
+ u32 dw1 = 0, dw2 = 0;
+@@ -2524,6 +2529,12 @@ static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+ else
+ hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF);
+
++ if (tmf && tmf->force_phy) {
++ hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK;
++ hdr->dw0 |= cpu_to_le32((1 << tmf->phy_id)
++ << CMD_HDR_PHY_ID_OFF);
++ }
++
+ /* dw1 */
+ switch (task->data_dir) {
+ case DMA_TO_DEVICE:
+
diff --git a/patches.drivers/scsi-hisi_sas-add-v2-hw-port-axi-error-handling-support.patch b/patches.drivers/scsi-hisi_sas-add-v2-hw-port-axi-error-handling-support.patch
new file mode 100644
index 0000000000..08582a8f8d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-v2-hw-port-axi-error-handling-support.patch
@@ -0,0 +1,106 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:43 +0800
+Subject: scsi: hisi_sas: add v2 hw port AXI error handling support
+Git-commit: 72f7fc3050d55e9877ecc56f33b7a434fca186f5
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Add port AXI errors handling for v2 hw. We do host controller reset for such
+errors.
+
+Besides, change port muli-bits ECC error handling, and we should also do host
+reset for such error. So, this patch put them in the same struct with port AXI
+error.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 51 ++++++++++++++++++++++++++++++----
+ 1 file changed, 45 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 4c4a000c5db0..725731125177 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -240,6 +240,10 @@
+ #define CHL_INT1_DMAC_TX_ECC_ERR_MSK (0x1 << CHL_INT1_DMAC_TX_ECC_ERR_OFF)
+ #define CHL_INT1_DMAC_RX_ECC_ERR_OFF 17
+ #define CHL_INT1_DMAC_RX_ECC_ERR_MSK (0x1 << CHL_INT1_DMAC_RX_ECC_ERR_OFF)
++#define CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF 19
++#define CHL_INT1_DMAC_TX_AXI_RD_ERR_OFF 20
++#define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21
++#define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22
+ #define CHL_INT2 (PORT_BASE + 0x1bc)
+ #define CHL_INT0_MSK (PORT_BASE + 0x1c0)
+ #define CHL_INT1_MSK (PORT_BASE + 0x1c4)
+@@ -1182,7 +1186,7 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xfff87fff);
+ hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
+- hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xffffffff);
++ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xff857fff);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbff);
+ hisi_sas_phy_write32(hisi_hba, i, SL_CFG, 0x13f801fc);
+ hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
+@@ -2832,6 +2836,33 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
+ }
+
++static const struct hisi_sas_hw_error port_ecc_axi_error[] = {
++ {
++ .irq_msk = BIT(CHL_INT1_DMAC_TX_ECC_ERR_OFF),
++ .msg = "dmac_tx_ecc_bad_err",
++ },
++ {
++ .irq_msk = BIT(CHL_INT1_DMAC_RX_ECC_ERR_OFF),
++ .msg = "dmac_rx_ecc_bad_err",
++ },
++ {
++ .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF),
++ .msg = "dma_tx_axi_wr_err",
++ },
++ {
++ .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_RD_ERR_OFF),
++ .msg = "dma_tx_axi_rd_err",
++ },
++ {
++ .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF),
++ .msg = "dma_rx_axi_wr_err",
++ },
++ {
++ .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF),
++ .msg = "dma_rx_axi_rd_err",
++ },
++};
++
+ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
+ {
+ struct hisi_hba *hisi_hba = p;
+@@ -2856,11 +2887,19 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
+ CHL_INT2);
+
+ if ((irq_msk & (1 << phy_no)) && irq_value1) {
+- if (irq_value1 & (CHL_INT1_DMAC_RX_ECC_ERR_MSK |
+- CHL_INT1_DMAC_TX_ECC_ERR_MSK))
+- panic("%s: DMAC RX/TX ecc bad error!\
+- (0x%x)",
+- dev_name(dev), irq_value1);
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(port_ecc_axi_error); i++) {
++ const struct hisi_sas_hw_error *error =
++ &port_ecc_axi_error[i];
++
++ if (!(irq_value1 & error->irq_msk))
++ continue;
++
++ dev_warn(dev, "%s error (phy%d 0x%x) found!\n",
++ error->msg, phy_no, irq_value1);
++ queue_work(hisi_hba->wq, &hisi_hba->rst_work);
++ }
+
+ hisi_sas_phy_write32(hisi_hba, phy_no,
+ CHL_INT1, irq_value1);
+
diff --git a/patches.drivers/scsi-hisi_sas-add-v3-hw-module_device_table.patch b/patches.drivers/scsi-hisi_sas-add-v3-hw-module_device_table.patch
new file mode 100644
index 0000000000..422361689b
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-v3-hw-module_device_table.patch
@@ -0,0 +1,39 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 7 Mar 2018 20:25:14 +0800
+Subject: scsi: hisi_sas: add v3 hw MODULE_DEVICE_TABLE()
+Git-commit: 40ec66b1bf4352315025b821f7a5aead3d8ea645
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+Export device table of v3 hw to userspace, or auto probe will fail for v3
+hw.
+
+Also change the module alias to include "pci", instead of "platform".
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 5ce5ef2caabe..6f3e5ba6b472 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2394,6 +2394,7 @@ static const struct pci_device_id sas_v3_pci_table[] = {
+ { PCI_VDEVICE(HUAWEI, 0xa230), hip08 },
+ {}
+ };
++MODULE_DEVICE_TABLE(pci, sas_v3_pci_table);
+
+ static const struct pci_error_handlers hisi_sas_err_handler = {
+ .error_detected = hisi_sas_error_detected_v3_hw,
+@@ -2416,4 +2417,4 @@ module_pci_driver(sas_v3_pci_driver);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
+ MODULE_DESCRIPTION("HISILICON SAS controller v3 hw driver based on pci device");
+-MODULE_ALIAS("platform:" DRV_NAME);
++MODULE_ALIAS("pci:" DRV_NAME);
+
diff --git a/patches.drivers/scsi-hisi_sas-add-v3-hw-suspend-and-resume.patch b/patches.drivers/scsi-hisi_sas-add-v3-hw-suspend-and-resume.patch
new file mode 100644
index 0000000000..6c0b07b7ee
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-add-v3-hw-suspend-and-resume.patch
@@ -0,0 +1,172 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:50 +0800
+Subject: scsi: hisi_sas: add v3 hw suspend and resume
+Git-commit: 4d0951ee70d348b694ce2bbdcc65b684239da4b4
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+For v3 hw SAS, it supports configuring power state from D0 to D3 for entering
+Low Power status and power state from D3 to D0 for quit Low Power status.
+
+When power state from D0 to D3, HW will send FLR to clear the registers of
+ECAM and BAR space, and when power state from D3 to D0, it will clear the
+registers of ECAM space only.
+
+So when suspend, need to do like controller reset (including disable
+interrupts/DQ/PHY/BUS), and also release slots after FLR. When resume,
+re-config the registers of BAR space.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 +
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 94 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 97 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 4343c4ce338d..cc050299cc0b 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -461,4 +461,5 @@ extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);
+ extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba);
+ extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
+ enum hisi_sas_phy_event event);
++extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba);
+ #endif
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index ad122378b84a..04e1172b0bc5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -737,7 +737,7 @@ static void hisi_sas_release_task(struct hisi_hba *hisi_hba,
+ hisi_sas_do_release_task(hisi_hba, slot->task, slot);
+ }
+
+-static void hisi_sas_release_tasks(struct hisi_hba *hisi_hba)
++void hisi_sas_release_tasks(struct hisi_hba *hisi_hba)
+ {
+ struct hisi_sas_device *sas_dev;
+ struct domain_device *device;
+@@ -754,6 +754,7 @@ static void hisi_sas_release_tasks(struct hisi_hba *hisi_hba)
+ hisi_sas_release_task(hisi_hba, device);
+ }
+ }
++EXPORT_SYMBOL_GPL(hisi_sas_release_tasks);
+
+ static void hisi_sas_dereg_device(struct hisi_hba *hisi_hba,
+ struct domain_device *device)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 9e321050cdc2..6a408d2e92f5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2303,6 +2303,98 @@ enum {
+ hip08,
+ };
+
++static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
++{
++ struct sas_ha_struct *sha = pci_get_drvdata(pdev);
++ struct hisi_hba *hisi_hba = sha->lldd_ha;
++ struct device *dev = hisi_hba->dev;
++ struct Scsi_Host *shost = hisi_hba->shost;
++ u32 device_state, status;
++ int rc;
++ u32 reg_val;
++ unsigned long flags;
++
++ if (!pdev->pm_cap) {
++ dev_err(dev, "PCI PM not supported\n");
++ return -ENODEV;
++ }
++
++ set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
++ scsi_block_requests(shost);
++ set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
++ flush_workqueue(hisi_hba->wq);
++ /* disable DQ/PHY/bus */
++ interrupt_disable_v3_hw(hisi_hba);
++ hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0);
++ hisi_sas_kill_tasklets(hisi_hba);
++
++ hisi_sas_stop_phys(hisi_hba);
++
++ reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE +
++ AM_CTRL_GLOBAL);
++ reg_val |= 0x1;
++ hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE +
++ AM_CTRL_GLOBAL, reg_val);
++
++ /* wait until bus idle */
++ rc = readl_poll_timeout(hisi_hba->regs + AXI_MASTER_CFG_BASE +
++ AM_CURR_TRANS_RETURN, status, status == 0x3, 10, 100);
++ if (rc) {
++ dev_err(dev, "axi bus is not idle, rc = %d\n", rc);
++ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
++ clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
++ scsi_unblock_requests(shost);
++ return rc;
++ }
++
++ hisi_sas_init_mem(hisi_hba);
++
++ device_state = pci_choose_state(pdev, state);
++ dev_warn(dev, "entering operating state [D%d]\n",
++ device_state);
++ pci_save_state(pdev);
++ pci_disable_device(pdev);
++ pci_set_power_state(pdev, device_state);
++
++ spin_lock_irqsave(&hisi_hba->lock, flags);
++ hisi_sas_release_tasks(hisi_hba);
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
++
++ sas_suspend_ha(sha);
++ return 0;
++}
++
++static int hisi_sas_v3_resume(struct pci_dev *pdev)
++{
++ struct sas_ha_struct *sha = pci_get_drvdata(pdev);
++ struct hisi_hba *hisi_hba = sha->lldd_ha;
++ struct Scsi_Host *shost = hisi_hba->shost;
++ struct device *dev = hisi_hba->dev;
++ unsigned int rc;
++ u32 device_state = pdev->current_state;
++
++ dev_warn(dev, "resuming from operating state [D%d]\n",
++ device_state);
++ pci_set_power_state(pdev, PCI_D0);
++ pci_enable_wake(pdev, PCI_D0, 0);
++ pci_restore_state(pdev);
++ rc = pci_enable_device(pdev);
++ if (rc)
++ dev_err(dev, "enable device failed during resume (%d)\n", rc);
++
++ pci_set_master(pdev);
++ scsi_unblock_requests(shost);
++ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
++
++ sas_prep_resume_ha(sha);
++ init_reg_v3_hw(hisi_hba);
++ hisi_hba->hw->phys_init(hisi_hba);
++ sas_resume_ha(sha);
++ clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
++
++ return 0;
++}
++
+ static const struct pci_device_id sas_v3_pci_table[] = {
+ { PCI_VDEVICE(HUAWEI, 0xa230), hip08 },
+ {}
+@@ -2319,6 +2411,8 @@ static struct pci_driver sas_v3_pci_driver = {
+ .id_table = sas_v3_pci_table,
+ .probe = hisi_sas_v3_probe,
+ .remove = hisi_sas_v3_remove,
++ .suspend = hisi_sas_v3_suspend,
++ .resume = hisi_sas_v3_resume,
+ .err_handler = &hisi_sas_err_handler,
+ };
+
+
diff --git a/patches.drivers/scsi-hisi_sas-allocate-slot-buffer-earlier.patch b/patches.drivers/scsi-hisi_sas-allocate-slot-buffer-earlier.patch
new file mode 100644
index 0000000000..54bfb0443f
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-allocate-slot-buffer-earlier.patch
@@ -0,0 +1,141 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 9 May 2018 23:10:47 +0800
+Subject: scsi: hisi_sas: allocate slot buffer earlier
+Git-commit: 3de0026dad6b8e83d8a699aef92638c50ba966f7
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Currently we allocate the slot's memory buffer after allocating the DQ
+slot.
+
+To aid DQ lockout reduction, and allow slots to be built in parallel,
+move this step (which can fail) prior to allocating the slot.
+
+Also a stray spin_unlock_irqrestore() is removed from internal task exec
+function.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 55 ++++++++++++++++++++---------------
+ 1 file changed, 31 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 2772e920572d..58cbe1f0e0b6 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -412,14 +412,22 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ if (rc)
+ goto err_out_dma_unmap;
+
++ slot = &hisi_hba->slot_info[slot_idx];
++ memset(slot, 0, sizeof(struct hisi_sas_slot));
++
++ slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
++ GFP_ATOMIC, &slot->buf_dma);
++ if (!slot->buf) {
++ rc = -ENOMEM;
++ goto err_out_tag;
++ }
++
+ rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
+ if (rc)
+- goto err_out_tag;
++ goto err_out_buf;
+
+ dlvry_queue = dq->id;
+ dlvry_queue_slot = dq->wr_point;
+- slot = &hisi_hba->slot_info[slot_idx];
+- memset(slot, 0, sizeof(struct hisi_sas_slot));
+
+ slot->idx = slot_idx;
+ slot->n_elem = n_elem;
+@@ -434,12 +442,6 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ task->lldd_task = slot;
+ INIT_WORK(&slot->abort_slot, hisi_sas_slot_abort);
+
+- slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
+- GFP_ATOMIC, &slot->buf_dma);
+- if (!slot->buf) {
+- rc = -ENOMEM;
+- goto err_out_slot_buf;
+- }
+ memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
+ memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ);
+ memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ);
+@@ -474,8 +476,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+
+ return 0;
+
+-err_out_slot_buf:
+- /* Nothing to be done */
++err_out_buf:
++ dma_pool_free(hisi_hba->buffer_pool, slot->buf,
++ slot->buf_dma);
+ err_out_tag:
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+@@ -1519,17 +1522,26 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+ }
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
++ slot = &hisi_hba->slot_info[slot_idx];
++ memset(slot, 0, sizeof(struct hisi_sas_slot));
++
++ slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
++ GFP_ATOMIC, &slot->buf_dma);
++ if (!slot->buf) {
++ rc = -ENOMEM;
++ goto err_out_tag;
++ }
+ spin_lock_irqsave(&dq->lock, flags_dq);
+ rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
+- if (rc)
+- goto err_out_tag;
++ if (rc) {
++ rc = -ENOMEM;
++ spin_unlock_irqrestore(&dq->lock, flags_dq);
++ goto err_out_buf;
++ }
+
+ dlvry_queue = dq->id;
+ dlvry_queue_slot = dq->wr_point;
+
+- slot = &hisi_hba->slot_info[slot_idx];
+- memset(slot, 0, sizeof(struct hisi_sas_slot));
+-
+ slot->idx = slot_idx;
+ slot->n_elem = n_elem;
+ slot->dlvry_queue = dlvry_queue;
+@@ -1541,13 +1553,6 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+ slot->is_internal = true;
+ task->lldd_task = slot;
+
+- slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
+- GFP_ATOMIC, &slot->buf_dma);
+- if (!slot->buf) {
+- rc = -ENOMEM;
+- goto err_out_tag;
+- }
+-
+ memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
+ memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ);
+ memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ);
+@@ -1570,11 +1575,13 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+
+ return 0;
+
++err_out_buf:
++ dma_pool_free(hisi_hba->buffer_pool, slot->buf,
++ slot->buf_dma);
+ err_out_tag:
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- spin_unlock_irqrestore(&dq->lock, flags_dq);
+ err_out:
+ dev_err(dev, "internal abort task prep: failed[%d]!\n", rc);
+
+
diff --git a/patches.drivers/scsi-hisi_sas-change-common-allocation-mode-of-device-id.patch b/patches.drivers/scsi-hisi_sas-change-common-allocation-mode-of-device-id.patch
new file mode 100644
index 0000000000..f51196e11e
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-change-common-allocation-mode-of-device-id.patch
@@ -0,0 +1,61 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 21 May 2018 18:09:15 +0800
+Subject: scsi: hisi_sas: Change common allocation mode of device id
+Git-commit: 1b86518581f6111f5996ff8d4304bde2e3b05eb9
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+To reduce possibility of hitting unknown SoC bugs and aid debugging and
+test, change allocation mode of device id from last used device id instead
+of lowest available index.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 +
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 +++++-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 3c8840089cd5..b4717bd8af3f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -275,6 +275,7 @@ struct hisi_hba {
+
+ int slot_index_count;
+ int last_slot_index;
++ int last_dev_id;
+ unsigned long *slot_index_tags;
+ unsigned long reject_stp_links_msk;
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 796fdfc73c75..a7e4c6e77068 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -596,10 +596,12 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct hisi_sas_device *sas_dev = NULL;
+ unsigned long flags;
++ int last = hisi_hba->last_dev_id;
++ int first = (hisi_hba->last_dev_id + 1) % HISI_SAS_MAX_DEVICES;
+ int i;
+
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+- for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
++ for (i = first; i != last; i %= HISI_SAS_MAX_DEVICES) {
+ if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) {
+ int queue = i % hisi_hba->queue_count;
+ struct hisi_sas_dq *dq = &hisi_hba->dq[queue];
+@@ -614,7 +616,9 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
+ INIT_LIST_HEAD(&hisi_hba->devices[i].list);
+ break;
+ }
++ i++;
+ }
++ hisi_hba->last_dev_id = i;
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
+ return sas_dev;
+
diff --git a/patches.drivers/scsi-hisi_sas-change-frame-type-for-set-max-commands.patch b/patches.drivers/scsi-hisi_sas-change-frame-type-for-set-max-commands.patch
new file mode 100644
index 0000000000..5438917ed1
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-change-frame-type-for-set-max-commands.patch
@@ -0,0 +1,106 @@
+From: chenxiang <chenxiang66@hisilicon.com>
+Date: Thu, 28 Dec 2017 18:20:47 +0800
+Subject: scsi: hisi_sas: Change frame type for SET MAX commands
+Git-commit: 468f4b8d0711146f0075513e6047079a26fc3903
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+According to ATA protocol, SET MAX commands belong to different frame
+types. So judge features field of SET MAX commands to decide which
+frame type they belongs to.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 3 ++-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 20 ++++++++++++++++++--
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 4 files changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index cc050299cc0b..4000de429430 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -441,7 +441,8 @@ extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba);
+ extern void hisi_sas_init_add(struct hisi_hba *hisi_hba);
+ extern int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost);
+ extern void hisi_sas_free(struct hisi_hba *hisi_hba);
+-extern u8 hisi_sas_get_ata_protocol(u8 cmd, int direction);
++extern u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis,
++ int direction);
+ extern struct hisi_sas_port *to_hisi_sas_port(struct asd_sas_port *sas_port);
+ extern void hisi_sas_sata_done(struct sas_task *task,
+ struct hisi_sas_slot *slot);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 819b1d0ded89..360ecefba10a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -25,9 +25,9 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device);
+ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
+ void *funcdata);
+
+-u8 hisi_sas_get_ata_protocol(u8 cmd, int direction)
++u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+ {
+- switch (cmd) {
++ switch (fis->command) {
+ case ATA_CMD_FPDMA_WRITE:
+ case ATA_CMD_FPDMA_READ:
+ case ATA_CMD_FPDMA_RECV:
+@@ -79,10 +79,26 @@ u8 hisi_sas_get_ata_protocol(u8 cmd, int direction)
+ case ATA_CMD_ZAC_MGMT_OUT:
+ return HISI_SAS_SATA_PROTOCOL_NONDATA;
+ default:
++ {
++ if (fis->command == ATA_CMD_SET_MAX) {
++ switch (fis->features) {
++ case ATA_SET_MAX_PASSWD:
++ case ATA_SET_MAX_LOCK:
++ return HISI_SAS_SATA_PROTOCOL_PIO;
++
++ case ATA_SET_MAX_PASSWD_DMA:
++ case ATA_SET_MAX_UNLOCK_DMA:
++ return HISI_SAS_SATA_PROTOCOL_DMA;
++
++ default:
++ return HISI_SAS_SATA_PROTOCOL_NONDATA;
++ }
++ }
+ if (direction == DMA_NONE)
+ return HISI_SAS_SATA_PROTOCOL_NONDATA;
+ return HISI_SAS_SATA_PROTOCOL_PIO;
+ }
++ }
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_get_ata_protocol);
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index b8fe08d9b1ce..ebee2e463245 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2539,7 +2539,7 @@ static int prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+ dw1 |= 1 << CMD_HDR_RESET_OFF;
+
+ dw1 |= (hisi_sas_get_ata_protocol(
+- task->ata_task.fis.command, task->data_dir))
++ &task->ata_task.fis, task->data_dir))
+ << CMD_HDR_FRAME_TYPE_OFF;
+ dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+ hdr->dw1 = cpu_to_le32(dw1);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 6a408d2e92f5..a1f18689729a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1047,7 +1047,7 @@ static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+ dw1 |= 1 << CMD_HDR_RESET_OFF;
+
+ dw1 |= (hisi_sas_get_ata_protocol(
+- task->ata_task.fis.command, task->data_dir))
++ &task->ata_task.fis, task->data_dir))
+ << CMD_HDR_FRAME_TYPE_OFF;
+ dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+
+
diff --git a/patches.drivers/scsi-hisi_sas-change-ncq-process-for-v3-hw.patch b/patches.drivers/scsi-hisi_sas-change-ncq-process-for-v3-hw.patch
new file mode 100644
index 0000000000..76a8610ab5
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-change-ncq-process-for-v3-hw.patch
@@ -0,0 +1,78 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:39 +0800
+Subject: scsi: hisi_sas: change ncq process for v3 hw
+Git-commit: 9f347b2face51d782d1e03f2f05b7c3f93a6dc9a
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+For v3 hw, each NCQ will return a CQ, so it is no need to acquire IPTT from
+ITCT, just acquire it from IPTT field of CQ.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 40 +++++-----------------------------
+ 1 file changed, 6 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 44f07bc37177..69aa7bc15783 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1653,9 +1653,8 @@ static void cq_tasklet_v3_hw(unsigned long val)
+ struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val;
+ struct hisi_hba *hisi_hba = cq->hisi_hba;
+ struct hisi_sas_slot *slot;
+- struct hisi_sas_itct *itct;
+ struct hisi_sas_complete_v3_hdr *complete_queue;
+- u32 rd_point = cq->rd_point, wr_point, dev_id;
++ u32 rd_point = cq->rd_point, wr_point;
+ int queue = cq->id;
+ struct hisi_sas_dq *dq = &hisi_hba->dq[queue];
+
+@@ -1671,38 +1670,11 @@ static void cq_tasklet_v3_hw(unsigned long val)
+
+ complete_hdr = &complete_queue[rd_point];
+
+- /* Check for NCQ completion */
+- if (complete_hdr->act) {
+- u32 act_tmp = complete_hdr->act;
+- int ncq_tag_count = ffs(act_tmp);
+-
+- dev_id = (complete_hdr->dw1 & CMPLT_HDR_DEV_ID_MSK) >>
+- CMPLT_HDR_DEV_ID_OFF;
+- itct = &hisi_hba->itct[dev_id];
+-
+- /* The NCQ tags are held in the itct header */
+- while (ncq_tag_count) {
+- __le64 *ncq_tag = &itct->qw4_15[0];
+-
+- ncq_tag_count -= 1;
+- iptt = (ncq_tag[ncq_tag_count / 5]
+- >> (ncq_tag_count % 5) * 12) & 0xfff;
+-
+- slot = &hisi_hba->slot_info[iptt];
+- slot->cmplt_queue_slot = rd_point;
+- slot->cmplt_queue = queue;
+- slot_complete_v3_hw(hisi_hba, slot);
+-
+- act_tmp &= ~(1 << ncq_tag_count);
+- ncq_tag_count = ffs(act_tmp);
+- }
+- } else {
+- iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
+- slot = &hisi_hba->slot_info[iptt];
+- slot->cmplt_queue_slot = rd_point;
+- slot->cmplt_queue = queue;
+- slot_complete_v3_hw(hisi_hba, slot);
+- }
++ iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
++ slot = &hisi_hba->slot_info[iptt];
++ slot->cmplt_queue_slot = rd_point;
++ slot->cmplt_queue = queue;
++ slot_complete_v3_hw(hisi_hba, slot);
+
+ if (++rd_point >= HISI_SAS_QUEUE_SLOTS)
+ rd_point = 0;
+
diff --git a/patches.drivers/scsi-hisi_sas-change-slot-index-allocation-mode.patch b/patches.drivers/scsi-hisi_sas-change-slot-index-allocation-mode.patch
new file mode 100644
index 0000000000..07ba557e18
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-change-slot-index-allocation-mode.patch
@@ -0,0 +1,64 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 21 May 2018 18:09:14 +0800
+Subject: scsi: hisi_sas: change slot index allocation mode
+Git-commit: fa3be0f23139ddc4dffbfdef6bbd118e30dfcafe
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Currently we find the lowest available empty bit in the IPTT bitmap to
+allocate the IPTT for a command.
+
+To reduce possibility of hitting unknown SoC bugs and also aid in the
+debugging of those same bugs, change the allocation mode.
+
+The next allocation method is to use the next free slot adjacent to the
+most recently allocated slot, in a round-robin fashion.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 +
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 13 ++++++++++---
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 52fc709dd862..3c8840089cd5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -274,6 +274,7 @@ struct hisi_hba {
+ struct workqueue_struct *wq;
+
+ int slot_index_count;
++ int last_slot_index;
+ unsigned long *slot_index_tags;
+ unsigned long reject_stp_links_msk;
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 66388741e73c..796fdfc73c75 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -195,11 +195,18 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx)
+ unsigned int index;
+ void *bitmap = hisi_hba->slot_index_tags;
+
+- index = find_first_zero_bit(bitmap, hisi_hba->slot_index_count);
+- if (index >= hisi_hba->slot_index_count)
+- return -SAS_QUEUE_FULL;
++ index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
++ hisi_hba->last_slot_index + 1);
++ if (index >= hisi_hba->slot_index_count) {
++ index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
++ 0);
++ if (index >= hisi_hba->slot_index_count)
++ return -SAS_QUEUE_FULL;
++ }
+ hisi_sas_slot_index_set(hisi_hba, index);
+ *slot_idx = index;
++ hisi_hba->last_slot_index = index;
++
+ return 0;
+ }
+
+
diff --git a/patches.drivers/scsi-hisi_sas-check-host-frozen-before-calling-done-function.patch b/patches.drivers/scsi-hisi_sas-check-host-frozen-before-calling-done-function.patch
new file mode 100644
index 0000000000..f84bb379ae
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-check-host-frozen-before-calling-done-function.patch
@@ -0,0 +1,164 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 2 May 2018 23:56:26 +0800
+Subject: scsi: hisi_sas: check host frozen before calling "done" function
+Git-commit: cd938e535e909b80948f26d284ba7475adee0c08
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+When the host is frozen in SCSI EH state, at any point after the LLDD
+sets SAS_TASK_STATE_DONE for the sas_task task state, libsas may free
+the task; see sas_scsi_find_task().
+
+This puts the LLDD in a difficult position, in that once it sets
+SAS_TASK_STATE_DONE for the task state it should not reference the
+sas_task again. But the LLDD needs will check the sas_task indirectly in
+calling task->task_done()->sas_scsi_task_done() or sas_ata_task_done()
+(to check if the host is frozen state actually).
+
+And the LLDD cannot set SAS_TASK_STATE_DONE for the task state after
+task->task_done() is called (as the sas_task is free'd at this point).
+
+This situation would seem to be a problem made by libsas.
+
+To work around, check in the LLDD whether the host is in frozen state to
+ensure it is ok to call task->task_done() function. If in the frozen
+state, we rely on SCSI EH and libsas to free the sas_task directly.
+
+We do not do this for the following IO types:
+
+ - SMP - they are managed in libsas directly, outside SCSI EH
+ - Any internally originated IO, for similar reason
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 +
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 14 ++++++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 14 ++++++++++++++
+ 4 files changed, 32 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index d413d05fda26..147cfafdad9f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -196,6 +196,7 @@ struct hisi_sas_slot {
+ dma_addr_t cmd_hdr_dma;
+ struct work_struct abort_slot;
+ struct timer_list internal_abort_timer;
++ bool is_internal;
+ };
+
+ struct hisi_sas_tmf_task {
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 52746e2e7f6f..8f8e6424ee1d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -382,6 +382,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ slot->cmd_hdr = &cmd_hdr_base[dlvry_queue_slot];
+ slot->task = task;
+ slot->port = port;
++ if (is_tmf)
++ slot->is_internal = true;
+ task->lldd_task = slot;
+ INIT_WORK(&slot->abort_slot, hisi_sas_slot_abort);
+
+@@ -1486,6 +1488,7 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+ slot->cmd_hdr = &cmd_hdr_base[dlvry_queue_slot];
+ slot->task = task;
+ slot->port = port;
++ slot->is_internal = true;
+ task->lldd_task = slot;
+
+ slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 8ca0044e09be..6dda6eb50918 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2380,18 +2380,21 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ struct device *dev = hisi_hba->dev;
+ struct task_status_struct *ts;
+ struct domain_device *device;
++ struct sas_ha_struct *ha;
+ enum exec_status sts;
+ struct hisi_sas_complete_v2_hdr *complete_queue =
+ hisi_hba->complete_hdr[slot->cmplt_queue];
+ struct hisi_sas_complete_v2_hdr *complete_hdr =
+ &complete_queue[slot->cmplt_queue_slot];
+ unsigned long flags;
++ bool is_internal = slot->is_internal;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+ return -EINVAL;
+
+ ts = &task->task_status;
+ device = task->dev;
++ ha = device->port->ha;
+ sas_dev = device->lldd_dev;
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+@@ -2523,6 +2526,17 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ task->task_state_flags |= SAS_TASK_STATE_DONE;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
++ if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
++ spin_lock_irqsave(&device->done_lock, flags);
++ if (test_bit(SAS_HA_FROZEN, &ha->state)) {
++ spin_unlock_irqrestore(&device->done_lock, flags);
++ dev_info(dev, "slot complete: task(%p) ignored\n ",
++ task);
++ return sts;
++ }
++ spin_unlock_irqrestore(&device->done_lock, flags);
++ }
++
+ if (task->task_done)
+ task->task_done(task);
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 734611046d3e..5c0d9683630b 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1571,18 +1571,21 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ struct device *dev = hisi_hba->dev;
+ struct task_status_struct *ts;
+ struct domain_device *device;
++ struct sas_ha_struct *ha;
+ enum exec_status sts;
+ struct hisi_sas_complete_v3_hdr *complete_queue =
+ hisi_hba->complete_hdr[slot->cmplt_queue];
+ struct hisi_sas_complete_v3_hdr *complete_hdr =
+ &complete_queue[slot->cmplt_queue_slot];
+ unsigned long flags;
++ bool is_internal = slot->is_internal;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+ return -EINVAL;
+
+ ts = &task->task_status;
+ device = task->dev;
++ ha = device->port->ha;
+ sas_dev = device->lldd_dev;
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+@@ -1700,6 +1703,17 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ task->task_state_flags |= SAS_TASK_STATE_DONE;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
++ if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
++ spin_lock_irqsave(&device->done_lock, flags);
++ if (test_bit(SAS_HA_FROZEN, &ha->state)) {
++ spin_unlock_irqrestore(&device->done_lock, flags);
++ dev_info(dev, "slot complete: task(%p) ignored\n ",
++ task);
++ return sts;
++ }
++ spin_unlock_irqrestore(&device->done_lock, flags);
++ }
++
+ if (task->task_done)
+ task->task_done(task);
+
+
diff --git a/patches.drivers/scsi-hisi_sas-check-iptt-is-valid-before-using-it-for-v3-hw.patch b/patches.drivers/scsi-hisi_sas-check-iptt-is-valid-before-using-it-for-v3-hw.patch
new file mode 100644
index 0000000000..d12338aa2a
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-check-iptt-is-valid-before-using-it-for-v3-hw.patch
@@ -0,0 +1,53 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 24 Mar 2018 00:05:13 +0800
+Subject: scsi: hisi_sas: check IPTT is valid before using it for v3 hw
+Git-commit: 327f242fa806c199a183c2197592e94d336c8266
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+There is a bug of v3 hw development version. When AXI error happen, hw
+may return an abnormal CQ that IPTT value is 0xffff. This will cause
+IPTT out-of-bounds reference.
+
+This patch adds a check of IPTT in cq_tasklet_v3_hw() and discards
+invalid slot. This workaround scheme is just to enhance fault-tolerance
+of the driver. So, we will apply this scheme for all version of v3 hw,
+although release version has fixed this SoC bug.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index efe64bcfa4f2..aa52d5e424f7 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1731,15 +1731,19 @@ static void cq_tasklet_v3_hw(unsigned long val)
+
+ while (rd_point != wr_point) {
+ struct hisi_sas_complete_v3_hdr *complete_hdr;
++ struct device *dev = hisi_hba->dev;
+ int iptt;
+
+ complete_hdr = &complete_queue[rd_point];
+
+ iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
+- slot = &hisi_hba->slot_info[iptt];
+- slot->cmplt_queue_slot = rd_point;
+- slot->cmplt_queue = queue;
+- slot_complete_v3_hw(hisi_hba, slot);
++ if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) {
++ slot = &hisi_hba->slot_info[iptt];
++ slot->cmplt_queue_slot = rd_point;
++ slot->cmplt_queue = queue;
++ slot_complete_v3_hw(hisi_hba, slot);
++ } else
++ dev_err(dev, "IPTT %d is invalid, discard it.\n", iptt);
+
+ if (++rd_point >= HISI_SAS_QUEUE_SLOTS)
+ rd_point = 0;
+
diff --git a/patches.drivers/scsi-hisi_sas-check-sas_dev-gone-earlier-in-hisi_sas_abort_task.patch b/patches.drivers/scsi-hisi_sas-check-sas_dev-gone-earlier-in-hisi_sas_abort_task.patch
new file mode 100644
index 0000000000..63b876d1bc
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-check-sas_dev-gone-earlier-in-hisi_sas_abort_task.patch
@@ -0,0 +1,55 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 2 May 2018 23:56:28 +0800
+Subject: scsi: hisi_sas: check sas_dev gone earlier in hisi_sas_abort_task()
+Git-commit: c6ef895472696cac8e50f0ce69b301cc10233a67
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+It is possible to dereference a NULL-pointer in hisi_sas_abort_task() in
+special scenario when the device has been removed.
+
+If an SMP task times-out, it will call hisi_sas_abort_task() to
+recover. And currently there is a check in hisi_sas_abort_task() to
+avoid the situation of processing the abort for the removed device.
+
+However we have an ordering problem, in that we may reference a task for
+the removed device before checking if the device has been removed.
+
+Fix this by only referencing the sas_dev after we know it is still
+present.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 8f8e6424ee1d..24416bb66027 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1166,15 +1166,16 @@ static int hisi_sas_abort_task(struct sas_task *task)
+ struct hisi_sas_tmf_task tmf_task;
+ struct domain_device *device = task->dev;
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+- struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev);
+- struct device *dev = hisi_hba->dev;
++ struct hisi_hba *hisi_hba;
++ struct device *dev;
+ int rc = TMF_RESP_FUNC_FAILED;
+ unsigned long flags;
+
+- if (!sas_dev) {
+- dev_warn(dev, "Device has been removed\n");
++ if (!sas_dev)
+ return TMF_RESP_FUNC_FAILED;
+- }
++
++ hisi_hba = dev_to_hisi_hba(task->dev);
++ dev = hisi_hba->dev;
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ if (task->task_state_flags & SAS_TASK_STATE_DONE) {
+
diff --git a/patches.drivers/scsi-hisi_sas-code-cleanup-and-minor-bug-fixes.patch b/patches.drivers/scsi-hisi_sas-code-cleanup-and-minor-bug-fixes.patch
new file mode 100644
index 0000000000..2b24bee100
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-code-cleanup-and-minor-bug-fixes.patch
@@ -0,0 +1,244 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 7 Mar 2018 20:25:12 +0800
+Subject: scsi: hisi_sas: Code cleanup and minor bug fixes
+Git-commit: edafeef4f28ded4ea9ba7876cc35861d43c7b2b1
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+The patch does some code cleanup and fixes some small bugs:
+
+- Correct return status of phy_up_v3_hw() and phy_bcast_v3_hw()
+- Add static for function phy_get_max_linkrate_v3_hw()
+- Change exception return status when no reset method
+- Change magic value to ts->stat in slot_complete_vx_hw()
+- Remove unnecessary check for dev_is_sata()
+- Fix some issues of alignment and indents (Authored by Xiaofei Tan in
+ another patch, but added here to be practical)
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 14 +++++++-------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +++-
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 10 ++++++----
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 28 +++++++++++++++++-----------
+ 4 files changed, 33 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index dff972393086..49c1fa643803 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -33,7 +33,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+ case ATA_CMD_FPDMA_RECV:
+ case ATA_CMD_FPDMA_SEND:
+ case ATA_CMD_NCQ_NON_DATA:
+- return HISI_SAS_SATA_PROTOCOL_FPDMA;
++ return HISI_SAS_SATA_PROTOCOL_FPDMA;
+
+ case ATA_CMD_DOWNLOAD_MICRO:
+ case ATA_CMD_ID_ATA:
+@@ -45,7 +45,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+ case ATA_CMD_WRITE_LOG_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
+- return HISI_SAS_SATA_PROTOCOL_PIO;
++ return HISI_SAS_SATA_PROTOCOL_PIO;
+
+ case ATA_CMD_DSM:
+ case ATA_CMD_DOWNLOAD_MICRO_DMA:
+@@ -64,7 +64,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+ case ATA_CMD_WRITE_LOG_DMA_EXT:
+ case ATA_CMD_WRITE_STREAM_DMA_EXT:
+ case ATA_CMD_ZAC_MGMT_IN:
+- return HISI_SAS_SATA_PROTOCOL_DMA;
++ return HISI_SAS_SATA_PROTOCOL_DMA;
+
+ case ATA_CMD_CHK_POWER:
+ case ATA_CMD_DEV_RESET:
+@@ -77,21 +77,21 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+ case ATA_CMD_STANDBY:
+ case ATA_CMD_STANDBYNOW1:
+ case ATA_CMD_ZAC_MGMT_OUT:
+- return HISI_SAS_SATA_PROTOCOL_NONDATA;
++ return HISI_SAS_SATA_PROTOCOL_NONDATA;
+ default:
+ {
+ if (fis->command == ATA_CMD_SET_MAX) {
+ switch (fis->features) {
+ case ATA_SET_MAX_PASSWD:
+ case ATA_SET_MAX_LOCK:
+- return HISI_SAS_SATA_PROTOCOL_PIO;
++ return HISI_SAS_SATA_PROTOCOL_PIO;
+
+ case ATA_SET_MAX_PASSWD_DMA:
+ case ATA_SET_MAX_UNLOCK_DMA:
+- return HISI_SAS_SATA_PROTOCOL_DMA;
++ return HISI_SAS_SATA_PROTOCOL_DMA;
+
+ default:
+- return HISI_SAS_SATA_PROTOCOL_NONDATA;
++ return HISI_SAS_SATA_PROTOCOL_NONDATA;
+ }
+ }
+ if (direction == DMA_NONE)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 8dd0e6a6ff8a..84a0ccc4daf5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -651,8 +651,10 @@ static int reset_hw_v1_hw(struct hisi_hba *hisi_hba)
+ dev_err(dev, "De-reset failed\n");
+ return -EIO;
+ }
+- } else
++ } else {
+ dev_warn(dev, "no reset method\n");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index bd1a48a590bc..f89fb9a49ea9 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1095,8 +1095,10 @@ static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
+ dev_err(dev, "SAS de-reset fail.\n");
+ return -EIO;
+ }
+- } else
+- dev_warn(dev, "no reset method\n");
++ } else {
++ dev_err(dev, "no reset method\n");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+@@ -2408,7 +2410,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_task_free(hisi_hba, task, slot);
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- return -1;
++ return ts->stat;
+ }
+
+ if (unlikely(!sas_dev)) {
+@@ -2667,7 +2669,7 @@ static int prep_abort_v2_hw(struct hisi_hba *hisi_hba,
+ /* dw0 */
+ hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/
+ (port->id << CMD_HDR_PORT_OFF) |
+- ((dev_is_sata(dev) ? 1:0) <<
++ (dev_is_sata(dev) <<
+ CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
+ (abort_flag << CMD_HDR_ABORT_FLAG_OFF));
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 8da9de7d67e5..4023fcbc3f04 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -670,8 +670,10 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba)
+ dev_err(dev, "Reset failed\n");
+ return -EIO;
+ }
+- } else
++ } else {
+ dev_err(dev, "no reset method!\n");
++ return -EINVAL;
++ }
+
+ return 0;
+ }
+@@ -731,7 +733,7 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+ start_phy_v3_hw(hisi_hba, phy_no);
+ }
+
+-enum sas_linkrate phy_get_max_linkrate_v3_hw(void)
++static enum sas_linkrate phy_get_max_linkrate_v3_hw(void)
+ {
+ return SAS_LINK_RATE_12_0_GBPS;
+ }
+@@ -1096,7 +1098,7 @@ static int prep_abort_v3_hw(struct hisi_hba *hisi_hba,
+ /* dw0 */
+ hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/
+ (port->id << CMD_HDR_PORT_OFF) |
+- ((dev_is_sata(dev) ? 1:0)
++ (dev_is_sata(dev)
+ << CMD_HDR_ABORT_DEVICE_TYPE_OFF) |
+ (abort_flag
+ << CMD_HDR_ABORT_FLAG_OFF));
+@@ -1112,9 +1114,9 @@ static int prep_abort_v3_hw(struct hisi_hba *hisi_hba,
+ return 0;
+ }
+
+-static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
++static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ {
+- int i, res = 0;
++ int i, res;
+ u32 context, port_id, link_rate;
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+@@ -1186,7 +1188,7 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ phy->port_id = port_id;
+ phy->phy_attached = 1;
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+-
++ res = IRQ_HANDLED;
+ end:
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+ CHL_INT0_SL_PHY_ENABLE_MSK);
+@@ -1195,7 +1197,7 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ return res;
+ }
+
+-static int phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
++static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ {
+ u32 phy_state, sl_ctrl, txid_auto;
+ struct device *dev = hisi_hba->dev;
+@@ -1217,10 +1219,10 @@ static int phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_NOT_RDY_MSK);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 0);
+
+- return 0;
++ return IRQ_HANDLED;
+ }
+
+-static void phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
++static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ {
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+@@ -1231,6 +1233,8 @@ static void phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+ CHL_INT0_SL_RX_BCST_ACK_MSK);
+ hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
++
++ return IRQ_HANDLED;
+ }
+
+ static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p)
+@@ -1257,7 +1261,9 @@ static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p)
+ res = IRQ_HANDLED;
+ if (irq_value & CHL_INT0_SL_RX_BCST_ACK_MSK)
+ /* phy bcast */
+- phy_bcast_v3_hw(phy_no, hisi_hba);
++ if (phy_bcast_v3_hw(phy_no, hisi_hba)
++ == IRQ_HANDLED)
++ res = IRQ_HANDLED;
+ } else {
+ if (irq_value & CHL_INT0_NOT_RDY_MSK)
+ /* phy down */
+@@ -1573,7 +1579,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_task_free(hisi_hba, task, slot);
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- return -1;
++ return ts->stat;
+ }
+
+ if (unlikely(!sas_dev)) {
+
diff --git a/patches.drivers/scsi-hisi_sas-config-ata-de-reset-as-an-constrained-command-for-v3-hw.patch b/patches.drivers/scsi-hisi_sas-config-ata-de-reset-as-an-constrained-command-for-v3-hw.patch
new file mode 100644
index 0000000000..261bf20b2c
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-config-ata-de-reset-as-an-constrained-command-for-v3-hw.patch
@@ -0,0 +1,62 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 2 May 2018 23:56:31 +0800
+Subject: scsi: hisi_sas: config ATA de-reset as an constrained command for v3
+ hw
+Git-commit: 9413532788df7470297dd0475995c5dc5b07f362
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+As a unconstrained command, a command can be sent to SATA disk even if
+SATA disk status is BUSY, ERR or DRQ.
+
+If an ATA reset assert is successful but ATA reset de-assert fails, then
+it will retry the reset de-assert. If reset de- assert retry is
+successful, we think it is okay to probe the device but actually it
+still has Err status.
+
+Apparently we need to retry the ATA reset assertion and de- assertion
+instead for this mentioned scenario.
+
+As such, we config ATA reset assert as a constrained command, if ATA
+reset de-assert fails, then ATA reset de-assert retry will also
+fail. Then we will retry the proper process of ATA reset assert and
+de-assert again.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index ffa3cea5ca8f..026faeee5ead 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -351,10 +351,11 @@ struct hisi_sas_err_record_v3 {
+ #define DIR_TO_DEVICE 2
+ #define DIR_RESERVED 3
+
+-#define CMD_IS_UNCONSTRAINT(cmd) \
+- ((cmd == ATA_CMD_READ_LOG_EXT) || \
+- (cmd == ATA_CMD_READ_LOG_DMA_EXT) || \
+- (cmd == ATA_CMD_DEV_RESET))
++#define FIS_CMD_IS_UNCONSTRAINED(fis) \
++ ((fis.command == ATA_CMD_READ_LOG_EXT) || \
++ (fis.command == ATA_CMD_READ_LOG_DMA_EXT) || \
++ ((fis.command == ATA_CMD_DEV_RESET) && \
++ ((fis.control & ATA_SRST) != 0)))
+
+ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
+ {
+@@ -1075,7 +1076,7 @@ static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+ << CMD_HDR_FRAME_TYPE_OFF;
+ dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+
+- if (CMD_IS_UNCONSTRAINT(task->ata_task.fis.command))
++ if (FIS_CMD_IS_UNCONSTRAINED(task->ata_task.fis))
+ dw1 |= 1 << CMD_HDR_UNCON_CMD_OFF;
+
+ hdr->dw1 = cpu_to_le32(dw1);
+
diff --git a/patches.drivers/scsi-hisi_sas-consolidate-command-check-in-hisi_sas_get_ata_protocol.patch b/patches.drivers/scsi-hisi_sas-consolidate-command-check-in-hisi_sas_get_ata_protocol.patch
new file mode 100644
index 0000000000..32e5261d07
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-consolidate-command-check-in-hisi_sas_get_ata_protocol.patch
@@ -0,0 +1,63 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 24 Mar 2018 00:05:12 +0800
+Subject: scsi: hisi_sas: consolidate command check in
+ hisi_sas_get_ata_protocol()
+Git-commit: 3ff0f0b657eb414c1f8f1f22b91d52b892d8a850
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Currently we check the fis->command value in 2 locations in
+hisi_sas_get_ata_protocol() switch statement. Fix this by consolidating
+the check for fis->command value to 1 location only.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 29 +++++++++++++++--------------
+ 1 file changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 9563dfa72181..8557fd08ed8e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -78,22 +78,23 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+ case ATA_CMD_STANDBYNOW1:
+ case ATA_CMD_ZAC_MGMT_OUT:
+ return HISI_SAS_SATA_PROTOCOL_NONDATA;
++
++ case ATA_CMD_SET_MAX:
++ switch (fis->features) {
++ case ATA_SET_MAX_PASSWD:
++ case ATA_SET_MAX_LOCK:
++ return HISI_SAS_SATA_PROTOCOL_PIO;
++
++ case ATA_SET_MAX_PASSWD_DMA:
++ case ATA_SET_MAX_UNLOCK_DMA:
++ return HISI_SAS_SATA_PROTOCOL_DMA;
++
++ default:
++ return HISI_SAS_SATA_PROTOCOL_NONDATA;
++ }
++
+ default:
+ {
+- if (fis->command == ATA_CMD_SET_MAX) {
+- switch (fis->features) {
+- case ATA_SET_MAX_PASSWD:
+- case ATA_SET_MAX_LOCK:
+- return HISI_SAS_SATA_PROTOCOL_PIO;
+-
+- case ATA_SET_MAX_PASSWD_DMA:
+- case ATA_SET_MAX_UNLOCK_DMA:
+- return HISI_SAS_SATA_PROTOCOL_DMA;
+-
+- default:
+- return HISI_SAS_SATA_PROTOCOL_NONDATA;
+- }
+- }
+ if (direction == DMA_NONE)
+ return HISI_SAS_SATA_PROTOCOL_NONDATA;
+ return HISI_SAS_SATA_PROTOCOL_PIO;
+
diff --git a/patches.drivers/scsi-hisi_sas-create-a-scsi_host_template-per-hw-module.patch b/patches.drivers/scsi-hisi_sas-create-a-scsi_host_template-per-hw-module.patch
new file mode 100644
index 0000000000..63fbf76537
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-create-a-scsi_host_template-per-hw-module.patch
@@ -0,0 +1,287 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 21 May 2018 18:09:18 +0800
+Subject: scsi: hisi_sas: Create a scsi_host_template per HW module
+Git-commit: 235bfc7ff63027e90c25663ed7a976083f5afb47
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+When a SCSI host is registered, the SCSI mid-layer takes a reference to a
+module in Scsi_host.hostt.module. In doing this, we are prevented from
+removing the driver module for the host in dangerous scenario, like when a
+disk is mounted.
+
+Currently there is only one scsi_host_template (sht) for all HW versions,
+and this is the main.c module. So this means that we can possibly remove
+the HW module in this dangerous scenario, as SCSI mid-layer is only
+referencing the main.c module.
+
+To fix this, create a sht per module, referencing that same module to
+create the Scsi host.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 8 +++++--
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 40 +++++++++-------------------------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 23 +++++++++++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 24 ++++++++++++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 24 +++++++++++++++++++-
+ 5 files changed, 86 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index b4717bd8af3f..37c9a6246dc8 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -248,6 +248,7 @@ struct hisi_sas_hw {
+ u8 reg_index, u8 reg_count, u8 *write_data);
+ int max_command_entries;
+ int complete_hdr_size;
++ struct scsi_host_template *sht;
+ };
+
+ struct hisi_hba {
+@@ -440,8 +441,6 @@ struct hisi_sas_slot_buf_table {
+ };
+
+ extern struct scsi_transport_template *hisi_sas_stt;
+-extern struct scsi_host_template *hisi_sas_sht;
+-
+ extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba);
+ extern int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost);
+ extern void hisi_sas_free(struct hisi_hba *hisi_hba);
+@@ -456,6 +455,11 @@ extern int hisi_sas_probe(struct platform_device *pdev,
+ const struct hisi_sas_hw *ops);
+ extern int hisi_sas_remove(struct platform_device *pdev);
+
++extern int hisi_sas_slave_configure(struct scsi_device *sdev);
++extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time);
++extern void hisi_sas_scan_start(struct Scsi_Host *shost);
++extern struct device_attribute *host_attrs[];
++extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
+ extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
+ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
+ struct sas_task *task,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index c8e647a65b30..664aaf7f5147 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -719,7 +719,7 @@ static int hisi_sas_dev_found(struct domain_device *device)
+ return rc;
+ }
+
+-static int hisi_sas_slave_configure(struct scsi_device *sdev)
++int hisi_sas_slave_configure(struct scsi_device *sdev)
+ {
+ struct domain_device *dev = sdev_to_domain_dev(sdev);
+ int ret = sas_slave_configure(sdev);
+@@ -731,15 +731,17 @@ static int hisi_sas_slave_configure(struct scsi_device *sdev)
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(hisi_sas_slave_configure);
+
+-static void hisi_sas_scan_start(struct Scsi_Host *shost)
++void hisi_sas_scan_start(struct Scsi_Host *shost)
+ {
+ struct hisi_hba *hisi_hba = shost_priv(shost);
+
+ hisi_hba->hw->phys_init(hisi_hba);
+ }
++EXPORT_SYMBOL_GPL(hisi_sas_scan_start);
+
+-static int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time)
++int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time)
+ {
+ struct hisi_hba *hisi_hba = shost_priv(shost);
+ struct sas_ha_struct *sha = &hisi_hba->sha;
+@@ -751,6 +753,7 @@ static int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time)
+ sas_drain_work(sha);
+ return 1;
+ }
++EXPORT_SYMBOL_GPL(hisi_sas_scan_finished);
+
+ static void hisi_sas_phyup_work(struct work_struct *work)
+ {
+@@ -1824,34 +1827,11 @@ EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets);
+ struct scsi_transport_template *hisi_sas_stt;
+ EXPORT_SYMBOL_GPL(hisi_sas_stt);
+
+-static struct device_attribute *host_attrs[] = {
++struct device_attribute *host_attrs[] = {
+ &dev_attr_phy_event_threshold,
+ NULL,
+ };
+-
+-static struct scsi_host_template _hisi_sas_sht = {
+- .module = THIS_MODULE,
+- .name = DRV_NAME,
+- .queuecommand = sas_queuecommand,
+- .target_alloc = sas_target_alloc,
+- .slave_configure = hisi_sas_slave_configure,
+- .scan_finished = hisi_sas_scan_finished,
+- .scan_start = hisi_sas_scan_start,
+- .change_queue_depth = sas_change_queue_depth,
+- .bios_param = sas_bios_param,
+- .can_queue = 1,
+- .this_id = -1,
+- .sg_tablesize = SG_ALL,
+- .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+- .use_clustering = ENABLE_CLUSTERING,
+- .eh_device_reset_handler = sas_eh_device_reset_handler,
+- .eh_target_reset_handler = sas_eh_target_reset_handler,
+- .target_destroy = sas_target_destroy,
+- .ioctl = sas_ioctl,
+- .shost_attrs = host_attrs,
+-};
+-struct scsi_host_template *hisi_sas_sht = &_hisi_sas_sht;
+-EXPORT_SYMBOL_GPL(hisi_sas_sht);
++EXPORT_SYMBOL_GPL(host_attrs);
+
+ static struct sas_domain_function_template hisi_sas_transport_ops = {
+ .lldd_dev_found = hisi_sas_dev_found,
+@@ -2161,7 +2141,7 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
+ struct hisi_hba *hisi_hba;
+ struct device *dev = &pdev->dev;
+
+- shost = scsi_host_alloc(hisi_sas_sht, sizeof(*hisi_hba));
++ shost = scsi_host_alloc(hw->sht, sizeof(*hisi_hba));
+ if (!shost) {
+ dev_err(dev, "scsi host alloc failed\n");
+ return NULL;
+@@ -2211,7 +2191,7 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
+ }
+
+ int hisi_sas_probe(struct platform_device *pdev,
+- const struct hisi_sas_hw *hw)
++ const struct hisi_sas_hw *hw)
+ {
+ struct Scsi_Host *shost;
+ struct hisi_hba *hisi_hba;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 8fa79d0968a6..8d5d8575d939 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1788,6 +1788,28 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba)
+ return 0;
+ }
+
++static struct scsi_host_template sht_v1_hw = {
++ .name = DRV_NAME,
++ .module = THIS_MODULE,
++ .queuecommand = sas_queuecommand,
++ .target_alloc = sas_target_alloc,
++ .slave_configure = hisi_sas_slave_configure,
++ .scan_finished = hisi_sas_scan_finished,
++ .scan_start = hisi_sas_scan_start,
++ .change_queue_depth = sas_change_queue_depth,
++ .bios_param = sas_bios_param,
++ .can_queue = 1,
++ .this_id = -1,
++ .sg_tablesize = SG_ALL,
++ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
++ .use_clustering = ENABLE_CLUSTERING,
++ .eh_device_reset_handler = sas_eh_device_reset_handler,
++ .eh_target_reset_handler = sas_eh_target_reset_handler,
++ .target_destroy = sas_target_destroy,
++ .ioctl = sas_ioctl,
++ .shost_attrs = host_attrs,
++};
++
+ static const struct hisi_sas_hw hisi_sas_v1_hw = {
+ .hw_init = hisi_sas_v1_init,
+ .setup_itct = setup_itct_v1_hw,
+@@ -1807,6 +1829,7 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = {
+ .get_wideport_bitmap = get_wideport_bitmap_v1_hw,
+ .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V1_HW,
+ .complete_hdr_size = sizeof(struct hisi_sas_complete_v1_hdr),
++ .sht = &sht_v1_hw,
+ };
+
+ static int hisi_sas_v1_probe(struct platform_device *pdev)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index fb0e966a44a8..8def327c4f46 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3501,6 +3501,29 @@ static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type,
+ return 0;
+ }
+
++
++static struct scsi_host_template sht_v2_hw = {
++ .name = DRV_NAME,
++ .module = THIS_MODULE,
++ .queuecommand = sas_queuecommand,
++ .target_alloc = sas_target_alloc,
++ .slave_configure = hisi_sas_slave_configure,
++ .scan_finished = hisi_sas_scan_finished,
++ .scan_start = hisi_sas_scan_start,
++ .change_queue_depth = sas_change_queue_depth,
++ .bios_param = sas_bios_param,
++ .can_queue = 1,
++ .this_id = -1,
++ .sg_tablesize = SG_ALL,
++ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
++ .use_clustering = ENABLE_CLUSTERING,
++ .eh_device_reset_handler = sas_eh_device_reset_handler,
++ .eh_target_reset_handler = sas_eh_target_reset_handler,
++ .target_destroy = sas_target_destroy,
++ .ioctl = sas_ioctl,
++ .shost_attrs = host_attrs,
++};
++
+ static const struct hisi_sas_hw hisi_sas_v2_hw = {
+ .hw_init = hisi_sas_v2_init,
+ .setup_itct = setup_itct_v2_hw,
+@@ -3529,6 +3552,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
+ .soft_reset = soft_reset_v2_hw,
+ .get_phys_state = get_phys_state_v2_hw,
+ .write_gpio = write_gpio_v2_hw,
++ .sht = &sht_v2_hw,
+ };
+
+ static int hisi_sas_v2_probe(struct platform_device *pdev)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index a043d9cdbf48..13d21349d1ba 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2015,6 +2015,28 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type,
+ return 0;
+ }
+
++static struct scsi_host_template sht_v3_hw = {
++ .name = DRV_NAME,
++ .module = THIS_MODULE,
++ .queuecommand = sas_queuecommand,
++ .target_alloc = sas_target_alloc,
++ .slave_configure = hisi_sas_slave_configure,
++ .scan_finished = hisi_sas_scan_finished,
++ .scan_start = hisi_sas_scan_start,
++ .change_queue_depth = sas_change_queue_depth,
++ .bios_param = sas_bios_param,
++ .can_queue = 1,
++ .this_id = -1,
++ .sg_tablesize = SG_ALL,
++ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
++ .use_clustering = ENABLE_CLUSTERING,
++ .eh_device_reset_handler = sas_eh_device_reset_handler,
++ .eh_target_reset_handler = sas_eh_target_reset_handler,
++ .target_destroy = sas_target_destroy,
++ .ioctl = sas_ioctl,
++ .shost_attrs = host_attrs,
++};
++
+ static const struct hisi_sas_hw hisi_sas_v3_hw = {
+ .hw_init = hisi_sas_v3_init,
+ .setup_itct = setup_itct_v3_hw,
+@@ -2050,7 +2072,7 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
+ struct hisi_hba *hisi_hba;
+ struct device *dev = &pdev->dev;
+
+- shost = scsi_host_alloc(hisi_sas_sht, sizeof(*hisi_hba));
++ shost = scsi_host_alloc(&sht_v3_hw, sizeof(*hisi_hba));
+ if (!shost) {
+ dev_err(dev, "shost alloc failed\n");
+ return NULL;
+
diff --git a/patches.drivers/scsi-hisi_sas-delete-timer-when-removing-hisi_sas-driver.patch b/patches.drivers/scsi-hisi_sas-delete-timer-when-removing-hisi_sas-driver.patch
new file mode 100644
index 0000000000..d744232073
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-delete-timer-when-removing-hisi_sas-driver.patch
@@ -0,0 +1,62 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 24 Mar 2018 00:05:10 +0800
+Subject: scsi: hisi_sas: delete timer when removing hisi_sas driver
+Git-commit: 5df41af4b18720061b1024f93f54b957864cdd44
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Delete timer for v1 and v3 hw when removing hisi_sas driver.
+
+Signed-off-by: Xiang chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 3 ---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +++
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 49c1fa643803..a21679574142 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2177,6 +2177,9 @@ int hisi_sas_remove(struct platform_device *pdev)
+ struct hisi_hba *hisi_hba = sha->lldd_ha;
+ struct Scsi_Host *shost = sha->core.shost;
+
++ if (timer_pending(&hisi_hba->timer))
++ del_timer(&hisi_hba->timer);
++
+ sas_unregister_ha(sha);
+ sas_remove_host(sha->core.shost);
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 89b9505c0654..bed6afb324a1 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3599,9 +3599,6 @@ static int hisi_sas_v2_remove(struct platform_device *pdev)
+ struct sas_ha_struct *sha = platform_get_drvdata(pdev);
+ struct hisi_hba *hisi_hba = sha->lldd_ha;
+
+- if (timer_pending(&hisi_hba->timer))
+- del_timer(&hisi_hba->timer);
+-
+ hisi_sas_kill_tasklets(hisi_hba);
+
+ return hisi_sas_remove(pdev);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index df5414a0bdd9..efe64bcfa4f2 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2183,6 +2183,9 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
+ struct hisi_hba *hisi_hba = sha->lldd_ha;
+ struct Scsi_Host *shost = sha->core.shost;
+
++ if (timer_pending(&hisi_hba->timer))
++ del_timer(&hisi_hba->timer);
++
+ sas_unregister_ha(sha);
+ sas_remove_host(sha->core.shost);
+
+
diff --git a/patches.drivers/scsi-hisi_sas-directly-attached-disk-LED-feature-for.patch b/patches.drivers/scsi-hisi_sas-directly-attached-disk-LED-feature-for.patch
index 83c049b30e..8236268774 100644
--- a/patches.drivers/scsi-hisi_sas-directly-attached-disk-LED-feature-for.patch
+++ b/patches.drivers/scsi-hisi_sas-directly-attached-disk-LED-feature-for.patch
@@ -24,7 +24,7 @@ Signed-off-by: Matthias Brugger <mbrugger@suse.com>
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
-@@ -213,6 +213,8 @@ struct hisi_sas_hw {
+@@ -245,6 +245,8 @@ struct hisi_sas_hw {
struct domain_device *device);
int (*soft_reset)(struct hisi_hba *hisi_hba);
u32 (*get_phys_state)(struct hisi_hba *hisi_hba);
@@ -33,7 +33,7 @@ Signed-off-by: Matthias Brugger <mbrugger@suse.com>
int max_command_entries;
int complete_hdr_size;
};
-@@ -226,6 +228,7 @@ struct hisi_hba {
+@@ -258,6 +260,7 @@ struct hisi_hba {
struct device *dev;
void __iomem *regs;
@@ -43,8 +43,8 @@ Signed-off-by: Matthias Brugger <mbrugger@suse.com>
u32 ctrl_reset_sts_reg;
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
-@@ -1509,6 +1509,18 @@ static void hisi_sas_port_formed(struct
- hisi_sas_port_notify_formed(sas_phy);
+@@ -1636,6 +1636,18 @@ static void hisi_sas_port_deformed(struc
+ {
}
+static int hisi_sas_write_gpio(struct sas_ha_struct *sha, u8 reg_type,
@@ -62,15 +62,15 @@ Signed-off-by: Matthias Brugger <mbrugger@suse.com>
static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy)
{
phy->phy_attached = 0;
-@@ -1599,6 +1611,7 @@ static struct sas_domain_function_templa
- .lldd_query_task = hisi_sas_query_task,
- .lldd_clear_nexus_ha = hisi_sas_clear_nexus_ha,
- .lldd_port_formed = hisi_sas_port_formed,
+@@ -1726,6 +1738,7 @@ static struct sas_domain_function_templa
+ .lldd_control_phy = hisi_sas_control_phy,
+ .lldd_abort_task = hisi_sas_abort_task,
+ .lldd_abort_task_set = hisi_sas_abort_task_set,
+ .lldd_write_gpio = hisi_sas_write_gpio,
- };
-
- void hisi_sas_init_mem(struct hisi_hba *hisi_hba)
-@@ -1911,6 +1924,13 @@ static struct Scsi_Host *hisi_sas_shost_
+ .lldd_clear_aca = hisi_sas_clear_aca,
+ .lldd_I_T_nexus_reset = hisi_sas_I_T_nexus_reset,
+ .lldd_lu_reset = hisi_sas_lu_reset,
+@@ -2057,6 +2070,13 @@ static struct Scsi_Host *hisi_sas_shost_
if (IS_ERR(hisi_hba->regs))
goto err_out;
@@ -86,7 +86,7 @@ Signed-off-by: Matthias Brugger <mbrugger@suse.com>
goto err_out;
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
-@@ -3410,6 +3410,44 @@ static int soft_reset_v2_hw(struct hisi_
+@@ -3476,6 +3476,44 @@ static int soft_reset_v2_hw(struct hisi_
return 0;
}
@@ -131,7 +131,7 @@ Signed-off-by: Matthias Brugger <mbrugger@suse.com>
static const struct hisi_sas_hw hisi_sas_v2_hw = {
.hw_init = hisi_sas_v2_init,
.setup_itct = setup_itct_v2_hw,
-@@ -3436,6 +3474,7 @@ static const struct hisi_sas_hw hisi_sas
+@@ -3503,6 +3541,7 @@ static const struct hisi_sas_hw hisi_sas
.complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr),
.soft_reset = soft_reset_v2_hw,
.get_phys_state = get_phys_state_v2_hw,
diff --git a/patches.drivers/scsi-hisi_sas-do-link-reset-for-some-chl_int2-ints.patch b/patches.drivers/scsi-hisi_sas-do-link-reset-for-some-chl_int2-ints.patch
new file mode 100644
index 0000000000..e4fd59c581
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-do-link-reset-for-some-chl_int2-ints.patch
@@ -0,0 +1,180 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:45 +0800
+Subject: scsi: hisi_sas: do link reset for some CHL_INT2 ints
+Git-commit: 057c3d1f07617049671a41bf05652d20071eb639
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+We should do link reset of PHY when identify timeout or STP link timeout. They
+are internal events of SOC and are notified to driver through interrupts of
+CHL_INT2.
+
+Besides, we should add an delay work to do link reset as it needs sleep. So,
+this patch add an new PHY event HISI_PHYE_LINK_RESET for this.
+
+Notes: v2 HW doesn't report the event of STP link timeout. So, we only need
+to handle event of identify timeout for v2 HW.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 +
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 18 ++++++++++++++----
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 29 +++++++++++++++++++++++++++--
+ 4 files changed, 54 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index aa14638ab08f..4343c4ce338d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -126,6 +126,7 @@ enum hisi_sas_bit_err_type {
+
+ enum hisi_sas_phy_event {
+ HISI_PHYE_PHY_UP = 0U,
++ HISI_PHYE_LINK_RESET,
+ HISI_PHYES_NUM,
+ };
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 326dc8169073..7446a39f9442 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -22,6 +22,8 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
+ struct domain_device *device,
+ int abort_flag, int tag);
+ static int hisi_sas_softreset_ata_disk(struct domain_device *device);
++static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
++ void *funcdata);
+
+ u8 hisi_sas_get_ata_protocol(u8 cmd, int direction)
+ {
+@@ -631,8 +633,18 @@ static void hisi_sas_phyup_work(struct work_struct *work)
+ hisi_sas_bytes_dmaed(hisi_hba, phy_no);
+ }
+
++static void hisi_sas_linkreset_work(struct work_struct *work)
++{
++ struct hisi_sas_phy *phy =
++ container_of(work, typeof(*phy), works[HISI_PHYE_LINK_RESET]);
++ struct asd_sas_phy *sas_phy = &phy->sas_phy;
++
++ hisi_sas_control_phy(sas_phy, PHY_FUNC_LINK_RESET, NULL);
++}
++
+ static const work_func_t hisi_sas_phye_fns[HISI_PHYES_NUM] = {
+ [HISI_PHYE_PHY_UP] = hisi_sas_phyup_work,
++ [HISI_PHYE_LINK_RESET] = hisi_sas_linkreset_work,
+ };
+
+ bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index e521c420efee..b8fe08d9b1ce 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -245,6 +245,7 @@
+ #define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21
+ #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22
+ #define CHL_INT2 (PORT_BASE + 0x1bc)
++#define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0
+ #define CHL_INT0_MSK (PORT_BASE + 0x1c0)
+ #define CHL_INT1_MSK (PORT_BASE + 0x1c4)
+ #define CHL_INT2_MSK (PORT_BASE + 0x1c8)
+@@ -1187,7 +1188,7 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xfff87fff);
+ hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xff857fff);
+- hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbff);
++ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbfe);
+ hisi_sas_phy_write32(hisi_hba, i, SL_CFG, 0x13f801fc);
+ hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
+ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
+@@ -2905,10 +2906,19 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
+ CHL_INT1, irq_value1);
+ }
+
+- if ((irq_msk & (1 << phy_no)) && irq_value2)
+- hisi_sas_phy_write32(hisi_hba, phy_no,
+- CHL_INT2, irq_value2);
++ if ((irq_msk & (1 << phy_no)) && irq_value2) {
++ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
++
++ if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
++ dev_warn(dev, "phy%d identify timeout\n",
++ phy_no);
++ hisi_sas_notify_phy_event(phy,
++ HISI_PHYE_LINK_RESET);
++ }
+
++ hisi_sas_phy_write32(hisi_hba, phy_no,
++ CHL_INT2, irq_value2);
++ }
+
+ if ((irq_msk & (1 << phy_no)) && irq_value0) {
+ if (irq_value0 & CHL_INT0_SL_RX_BCST_ACK_MSK)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 4b7f251edbd2..9e321050cdc2 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -140,6 +140,7 @@
+ #define RX_IDAF_DWORD0 (PORT_BASE + 0xc4)
+ #define RXOP_CHECK_CFG_H (PORT_BASE + 0xfc)
+ #define STP_LINK_TIMER (PORT_BASE + 0x120)
++#define STP_LINK_TIMEOUT_STATE (PORT_BASE + 0x124)
+ #define CON_CFG_DRIVER (PORT_BASE + 0x130)
+ #define SAS_SSP_CON_TIMER_CFG (PORT_BASE + 0x134)
+ #define SAS_SMP_CON_TIMER_CFG (PORT_BASE + 0x138)
+@@ -165,6 +166,8 @@
+ #define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21
+ #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22
+ #define CHL_INT2 (PORT_BASE + 0x1bc)
++#define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0
++#define CHL_INT2_STP_LINK_TIMEOUT_OFF 31
+ #define CHL_INT0_MSK (PORT_BASE + 0x1c0)
+ #define CHL_INT1_MSK (PORT_BASE + 0x1c4)
+ #define CHL_INT2_MSK (PORT_BASE + 0x1c8)
+@@ -429,7 +432,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
+ hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xff87ffff);
+- hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbff);
++ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe);
+ hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
+ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
+ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
+@@ -1342,9 +1345,31 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+ CHL_INT1, irq_value1);
+ }
+
+- if (irq_msk & (8 << (phy_no * 4)) && irq_value2)
++ if (irq_msk & (8 << (phy_no * 4)) && irq_value2) {
++ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
++
++ if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
++ dev_warn(dev, "phy%d identify timeout\n",
++ phy_no);
++ hisi_sas_notify_phy_event(phy,
++ HISI_PHYE_LINK_RESET);
++
++ }
++
++ if (irq_value2 & BIT(CHL_INT2_STP_LINK_TIMEOUT_OFF)) {
++ u32 reg_value = hisi_sas_phy_read32(hisi_hba,
++ phy_no, STP_LINK_TIMEOUT_STATE);
++
++ dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
++ phy_no, reg_value);
++ if (reg_value & BIT(4))
++ hisi_sas_notify_phy_event(phy,
++ HISI_PHYE_LINK_RESET);
++ }
++
+ hisi_sas_phy_write32(hisi_hba, phy_no,
+ CHL_INT2, irq_value2);
++ }
+
+
+ if (irq_msk & (2 << (phy_no * 4)) && irq_value0) {
+
diff --git a/patches.drivers/scsi-hisi_sas-don-t-lock-dq-for-complete-task-sending.patch b/patches.drivers/scsi-hisi_sas-don-t-lock-dq-for-complete-task-sending.patch
new file mode 100644
index 0000000000..64864fbe7d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-don-t-lock-dq-for-complete-task-sending.patch
@@ -0,0 +1,338 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 9 May 2018 23:10:48 +0800
+Subject: scsi: hisi_sas: Don't lock DQ for complete task sending
+Git-commit: fa222db0b036899cd4020a380568699ffb1de08d
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Currently we lock the DQ to protect whole delivery process. So this
+stops us building slots for the same queue in parallel, and can affect
+performance.
+
+To optimise it, only lock the DQ during special periods, specifically
+when allocating a slot from the DQ and when delivering a slot to the HW.
+
+This approach is now safe, thanks to the previous patches to ensure that
+we always deliver a slot to the HW once allocated.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 4 ++-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 49 ++++++++++++++++++++--------------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 27 ++++++++++++++-----
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 29 +++++++++++++++-----
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 28 ++++++++++++++-----
+ 5 files changed, 96 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 3a1caa04407e..52fc709dd862 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -161,7 +161,7 @@ struct hisi_sas_cq {
+
+ struct hisi_sas_dq {
+ struct hisi_hba *hisi_hba;
+- struct hisi_sas_slot *slot_prep;
++ struct list_head list;
+ spinlock_t lock;
+ int wr_point;
+ int id;
+@@ -181,6 +181,7 @@ struct hisi_sas_device {
+
+ struct hisi_sas_slot {
+ struct list_head entry;
++ struct list_head delivery;
+ struct sas_task *task;
+ struct hisi_sas_port *port;
+ u64 n_elem;
+@@ -190,6 +191,7 @@ struct hisi_sas_slot {
+ int cmplt_queue_slot;
+ int idx;
+ int abort;
++ int ready;
+ void *buf;
+ dma_addr_t buf_dma;
+ void *cmd_hdr;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 58cbe1f0e0b6..bf374a795962 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -307,9 +307,9 @@ static void hisi_sas_slot_abort(struct work_struct *work)
+ task->task_done(task);
+ }
+
+-static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+- *dq, int is_tmf, struct hisi_sas_tmf_task *tmf,
+- int *pass)
++static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq *dq,
++ int is_tmf, struct hisi_sas_tmf_task *tmf,
++ int *pass)
+ {
+ struct hisi_hba *hisi_hba = dq->hisi_hba;
+ struct domain_device *device = task->dev;
+@@ -321,7 +321,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ struct device *dev = hisi_hba->dev;
+ int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
+ int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
+- unsigned long flags;
++ unsigned long flags, flags_dq;
++ int wr_q_index;
+
+ if (!sas_port) {
+ struct task_status_struct *ts = &task->task_status;
+@@ -422,12 +423,18 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ goto err_out_tag;
+ }
+
+- rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
+- if (rc)
++ spin_lock_irqsave(&dq->lock, flags_dq);
++ wr_q_index = hisi_hba->hw->get_free_slot(hisi_hba, dq);
++ if (wr_q_index < 0) {
++ spin_unlock_irqrestore(&dq->lock, flags_dq);
+ goto err_out_buf;
++ }
++
++ list_add_tail(&slot->delivery, &dq->list);
++ spin_unlock_irqrestore(&dq->lock, flags_dq);
+
+ dlvry_queue = dq->id;
+- dlvry_queue_slot = dq->wr_point;
++ dlvry_queue_slot = wr_q_index;
+
+ slot->idx = slot_idx;
+ slot->n_elem = n_elem;
+@@ -471,8 +478,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+- dq->slot_prep = slot;
+ ++(*pass);
++ slot->ready = 1;
+
+ return 0;
+
+@@ -518,11 +525,11 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
+ return -EINVAL;
+
+ /* protect task_prep and start_delivery sequence */
+- spin_lock_irqsave(&dq->lock, flags);
+ rc = hisi_sas_task_prep(task, dq, is_tmf, tmf, &pass);
+ if (rc)
+ dev_err(dev, "task exec: failed[%d]!\n", rc);
+
++ spin_lock_irqsave(&dq->lock, flags);
+ if (likely(pass))
+ hisi_hba->hw->start_delivery(dq);
+ spin_unlock_irqrestore(&dq->lock, flags);
+@@ -1503,7 +1510,8 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+ struct hisi_sas_cmd_hdr *cmd_hdr_base;
+ struct hisi_sas_dq *dq = sas_dev->dq;
+ int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx;
+- unsigned long flags, flags_dq;
++ unsigned long flags, flags_dq = 0;
++ int wr_q_index;
+
+ if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags)))
+ return -EINVAL;
+@@ -1531,16 +1539,18 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+ rc = -ENOMEM;
+ goto err_out_tag;
+ }
++
+ spin_lock_irqsave(&dq->lock, flags_dq);
+- rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
+- if (rc) {
+- rc = -ENOMEM;
++ wr_q_index = hisi_hba->hw->get_free_slot(hisi_hba, dq);
++ if (wr_q_index < 0) {
+ spin_unlock_irqrestore(&dq->lock, flags_dq);
+ goto err_out_buf;
+ }
++ list_add_tail(&slot->delivery, &dq->list);
++ spin_unlock_irqrestore(&dq->lock, flags_dq);
+
+ dlvry_queue = dq->id;
+- dlvry_queue_slot = dq->wr_point;
++ dlvry_queue_slot = wr_q_index;
+
+ slot->idx = slot_idx;
+ slot->n_elem = n_elem;
+@@ -1560,18 +1570,16 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+ hisi_sas_task_prep_abort(hisi_hba, slot, device_id,
+ abort_flag, task_tag);
+
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+- list_add_tail(&slot->entry, &sas_dev->list);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+- dq->slot_prep = slot;
+-
++ slot->ready = 1;
+ /* send abort command to the chip */
++ spin_lock_irqsave(&dq->lock, flags);
++ list_add_tail(&slot->entry, &sas_dev->list);
+ hisi_hba->hw->start_delivery(dq);
+- spin_unlock_irqrestore(&dq->lock, flags_dq);
++ spin_unlock_irqrestore(&dq->lock, flags);
+
+ return 0;
+
+@@ -1856,6 +1864,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
+
+ /* Delivery queue structure */
+ spin_lock_init(&dq->lock);
++ INIT_LIST_HEAD(&dq->list);
+ dq->id = i;
+ dq->hisi_hba = hisi_hba;
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 7781a011a750..abe175fddb86 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -921,18 +921,33 @@ get_free_slot_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq)
+ return -EAGAIN;
+ }
+
+- return 0;
++ dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS;
++
++ return w;
+ }
+
++/* DQ lock must be taken here */
+ static void start_delivery_v1_hw(struct hisi_sas_dq *dq)
+ {
+ struct hisi_hba *hisi_hba = dq->hisi_hba;
+- int dlvry_queue = dq->slot_prep->dlvry_queue;
+- int dlvry_queue_slot = dq->slot_prep->dlvry_queue_slot;
++ struct hisi_sas_slot *s, *s1;
++ struct list_head *dq_list;
++ int dlvry_queue = dq->id;
++ int wp, count = 0;
++
++ dq_list = &dq->list;
++ list_for_each_entry_safe(s, s1, &dq->list, delivery) {
++ if (!s->ready)
++ break;
++ count++;
++ wp = (s->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS;
++ list_del(&s->delivery);
++ }
++
++ if (!count)
++ return;
+
+- dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS;
+- hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14),
+- dq->wr_point);
++ hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), wp);
+ }
+
+ static void prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 9f77fd8223f7..911bb76a4d0a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1663,23 +1663,38 @@ get_free_slot_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq)
+ r = hisi_sas_read32_relaxed(hisi_hba,
+ DLVRY_Q_0_RD_PTR + (queue * 0x14));
+ if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) {
+- dev_warn(dev, "full queue=%d r=%d w=%d\n\n",
++ dev_warn(dev, "full queue=%d r=%d w=%d\n",
+ queue, r, w);
+ return -EAGAIN;
+ }
+
+- return 0;
++ dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS;
++
++ return w;
+ }
+
++/* DQ lock must be taken here */
+ static void start_delivery_v2_hw(struct hisi_sas_dq *dq)
+ {
+ struct hisi_hba *hisi_hba = dq->hisi_hba;
+- int dlvry_queue = dq->slot_prep->dlvry_queue;
+- int dlvry_queue_slot = dq->slot_prep->dlvry_queue_slot;
++ struct hisi_sas_slot *s, *s1;
++ struct list_head *dq_list;
++ int dlvry_queue = dq->id;
++ int wp, count = 0;
++
++ dq_list = &dq->list;
++ list_for_each_entry_safe(s, s1, &dq->list, delivery) {
++ if (!s->ready)
++ break;
++ count++;
++ wp = (s->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS;
++ list_del(&s->delivery);
++ }
++
++ if (!count)
++ return;
+
+- dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS;
+- hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14),
+- dq->wr_point);
++ hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), wp);
+ }
+
+ static void prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 8cd13744a090..56f1046b244c 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -840,23 +840,37 @@ get_free_slot_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq)
+ r = hisi_sas_read32_relaxed(hisi_hba,
+ DLVRY_Q_0_RD_PTR + (queue * 0x14));
+ if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) {
+- dev_warn(dev, "full queue=%d r=%d w=%d\n\n",
++ dev_warn(dev, "full queue=%d r=%d w=%d\n",
+ queue, r, w);
+ return -EAGAIN;
+ }
+
+- return 0;
++ dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS;
++
++ return w;
+ }
+
+ static void start_delivery_v3_hw(struct hisi_sas_dq *dq)
+ {
+ struct hisi_hba *hisi_hba = dq->hisi_hba;
+- int dlvry_queue = dq->slot_prep->dlvry_queue;
+- int dlvry_queue_slot = dq->slot_prep->dlvry_queue_slot;
++ struct hisi_sas_slot *s, *s1;
++ struct list_head *dq_list;
++ int dlvry_queue = dq->id;
++ int wp, count = 0;
++
++ dq_list = &dq->list;
++ list_for_each_entry_safe(s, s1, &dq->list, delivery) {
++ if (!s->ready)
++ break;
++ count++;
++ wp = (s->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS;
++ list_del(&s->delivery);
++ }
++
++ if (!count)
++ return;
+
+- dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS;
+- hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14),
+- dq->wr_point);
++ hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), wp);
+ }
+
+ static void prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba,
+
diff --git a/patches.drivers/scsi-hisi_sas-dt-bindings-add-an-property-of-signal-attenuation.patch b/patches.drivers/scsi-hisi_sas-dt-bindings-add-an-property-of-signal-attenuation.patch
new file mode 100644
index 0000000000..80e930a4c0
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-dt-bindings-add-an-property-of-signal-attenuation.patch
@@ -0,0 +1,44 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 7 Mar 2018 20:25:05 +0800
+Subject: scsi: hisi_sas: dt-bindings: add an property of signal attenuation
+Git-commit: 4c40db995eb54c3ee8cb5a8340640f49395d5f9e
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+For some new boards with hip07 chipset we are required to set PHY config
+registers differently. The hw property which determines how to set these
+registers is in the PHY signal attenuation readings.
+
+This patch add an devicetree property, "hisilicon,signal-attenuation", which
+is used to describe the signal attenuation of an board.
+
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ Documentation/devicetree/bindings/scsi/hisilicon-sas.txt | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
+index df3bef7998fa..8c6659ed2cfc 100644
+--- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
++++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
+@@ -53,6 +53,13 @@ Main node required properties:
+ Optional main node properties:
+ - hip06-sas-v2-quirk-amt : when set, indicates that the v2 controller has the
+ "am-max-transmissions" limitation.
++ - hisilicon,signal-attenuation : array of 3 32-bit values, containing de-emphasis,
++ preshoot, and boost attenuation readings for the board. They
++ are used to describe the signal attenuation of the board. These
++ values' range is 7600 to 12400, and used to represent -24dB to
++ 24dB.
++ The formula is "y = (x-10000)/10000". For example, 10478
++ means 4.78dB.
+
+ Example:
+ sas0: sas@c1000000 {
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-a-bug-in-hisi_sas_dev_gone.patch b/patches.drivers/scsi-hisi_sas-fix-a-bug-in-hisi_sas_dev_gone.patch
new file mode 100644
index 0000000000..2c4bf4d84d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-a-bug-in-hisi_sas_dev_gone.patch
@@ -0,0 +1,35 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Thu, 18 Jan 2018 00:46:54 +0800
+Subject: scsi: hisi_sas: fix a bug in hisi_sas_dev_gone()
+Git-commit: 0d762b3af2a5b5095fec18aa4d61f408638aa9ca
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+When device gone, NULL pointer can be accessed in free_device callback
+if during SAS controller reset as we clear structure sas_dev prior.
+
+Actually we can only set dev_type as SAS_PHY_UNUSED and not clear
+structure sas_dev as all the members of structure sas_dev will be
+re-initialized after device found.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 791462d7fbfc..2d4dbed03ee3 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -796,7 +796,6 @@ static void hisi_sas_dev_gone(struct domain_device *device)
+
+ hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
+ device->lldd_dev = NULL;
+- memset(sas_dev, 0, sizeof(*sas_dev));
+ }
+
+ if (hisi_hba->hw->free_device)
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-a-typo-in-hisi_sas_task_prep.patch b/patches.drivers/scsi-hisi_sas-fix-a-typo-in-hisi_sas_task_prep.patch
new file mode 100644
index 0000000000..0598fd6f81
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-a-typo-in-hisi_sas_task_prep.patch
@@ -0,0 +1,31 @@
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Sat, 26 May 2018 09:34:22 +0000
+Subject: scsi: hisi_sas: fix a typo in hisi_sas_task_prep()
+Git-commit: eb217359ebeae7b9ac51045d50f7a516925bc5c2
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Fix a typo in hisi_sas_task_prep().
+
+Fixes: 7eee4b921822 ("scsi: hisi_sas: relocate smp sg map")
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 39f694eb7b00..6d3796553272 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -390,7 +390,7 @@ static int hisi_sas_task_prep(struct sas_task *task,
+ }
+ n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
+ 1, DMA_FROM_DEVICE);
+- if (!n_elem_req) {
++ if (!n_elem_resp) {
+ rc = -ENOMEM;
+ goto err_out_dma_unmap;
+ }
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-dma_unmap_sg-parameter.patch b/patches.drivers/scsi-hisi_sas-fix-dma_unmap_sg-parameter.patch
new file mode 100644
index 0000000000..0e96cd5448
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-dma_unmap_sg-parameter.patch
@@ -0,0 +1,45 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:33 +0800
+Subject: scsi: hisi_sas: fix dma_unmap_sg() parameter
+Git-commit: dc1e4730e2b636065628f8427b675788bca83d34
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+For function dma_unmap_sg(), the <nents> parameter should be number of
+elements in the scatterlist prior to the mapping, not after the mapping.
+
+Fix this usage.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 359ec52fc2fb..d8425303eadd 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -192,7 +192,8 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
+
+ if (!sas_protocol_ata(task->task_proto))
+ if (slot->n_elem)
+- dma_unmap_sg(dev, task->scatter, slot->n_elem,
++ dma_unmap_sg(dev, task->scatter,
++ task->num_scatter,
+ task->data_dir);
+
+ if (sas_dev)
+@@ -431,7 +432,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ dev_err(dev, "task prep: failed[%d]!\n", rc);
+ if (!sas_protocol_ata(task->task_proto))
+ if (n_elem)
+- dma_unmap_sg(dev, task->scatter, n_elem,
++ dma_unmap_sg(dev, task->scatter,
++ task->num_scatter,
+ task->data_dir);
+ prep_out:
+ return rc;
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-pi-memory-size.patch b/patches.drivers/scsi-hisi_sas-fix-pi-memory-size.patch
new file mode 100644
index 0000000000..e66a9d1e8e
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-pi-memory-size.patch
@@ -0,0 +1,35 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 2 May 2018 23:56:27 +0800
+Subject: scsi: hisi_sas: fix PI memory size
+Git-commit: a14da7a20d499c54ebe53e430283e3bc17d3e89f
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+There are 28 bytes of protection information record of SSP for v3 hw, 16
+bytes for v2 hw, and probably 24 for v1 hw (forgotten now).
+
+So use a value big enough in hisi_sas_command_table_ssp.prot to cover
+all cases.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 147cfafdad9f..04a40c427a20 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -410,7 +410,7 @@ struct hisi_sas_command_table_ssp {
+ union {
+ struct {
+ struct ssp_command_iu task;
+- u32 prot[6];
++ u32 prot[7];
+ };
+ struct ssp_tmf_iu ssp_task;
+ struct xfer_rdy_iu xfer_rdy;
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-return-value-of-hisi_sas_task_prep.patch b/patches.drivers/scsi-hisi_sas-fix-return-value-of-hisi_sas_task_prep.patch
new file mode 100644
index 0000000000..2708ab82bf
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-return-value-of-hisi_sas_task_prep.patch
@@ -0,0 +1,58 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 7 Mar 2018 20:25:11 +0800
+Subject: scsi: hisi_sas: fix return value of hisi_sas_task_prep()
+Git-commit: 6bf6db518cd10ad57e659607d0abece1b81956c6
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+It is an implicit regulation that error code that function returned should
+be negative. But hisi_sas_task_prep() doesn't follow this. This may cause
+problems in the upper layer code.
+
+For example, in sas_expander.c of libsas, smp_execute_task_sg() may return
+the number of bytes of underrun. It will be conflicted with the scenaio
+lldd_execute_task() return an positive error code.
+
+This patch change the return value from SAS_PHY_DOWN to -ECOMM in
+hisi_sas_task_prep().
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 88ad8d42ef6f..dff972393086 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -316,7 +316,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ */
+ if (device->dev_type != SAS_SATA_DEV)
+ task->task_done(task);
+- return SAS_PHY_DOWN;
++ return -ECOMM;
+ }
+
+ if (DEV_IS_GONE(sas_dev)) {
+@@ -327,7 +327,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ dev_info(dev, "task prep: device %016llx not ready\n",
+ SAS_ADDR(device->sas_addr));
+
+- return SAS_PHY_DOWN;
++ return -ECOMM;
+ }
+
+ port = to_hisi_sas_port(sas_port);
+@@ -337,7 +337,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ "SATA/STP" : "SAS",
+ device->port->id);
+
+- return SAS_PHY_DOWN;
++ return -ECOMM;
+ }
+
+ if (!sas_protocol_ata(task->task_proto)) {
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-return-value-when-get_free_slot-failed.patch b/patches.drivers/scsi-hisi_sas-fix-return-value-when-get_free_slot-failed.patch
new file mode 100644
index 0000000000..4389c77ff5
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-return-value-when-get_free_slot-failed.patch
@@ -0,0 +1,43 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Mon, 21 May 2018 18:09:24 +0800
+Subject: scsi: hisi_sas: Fix return value when get_free_slot() failed
+Git-commit: d87e72fb4fda6c48909e870811ae5252d0520f99
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+It is an step of executing task to get free slot. If the step fails, we
+will cleanup LLDD resources and should return failure to upper layer or
+internal caller to abort task execution of this time.
+
+But in the current code, the caller of get_free_slot() doesn't return
+failure when get_free_slot() failed. This patch is to fix it.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index cd55849bcd07..3028024cb437 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -443,6 +443,7 @@ static int hisi_sas_task_prep(struct sas_task *task,
+ wr_q_index = hisi_hba->hw->get_free_slot(hisi_hba, dq);
+ if (wr_q_index < 0) {
+ spin_unlock_irqrestore(&dq->lock, flags_dq);
++ rc = -EAGAIN;
+ goto err_out_buf;
+ }
+
+@@ -1708,6 +1709,7 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+ wr_q_index = hisi_hba->hw->get_free_slot(hisi_hba, dq);
+ if (wr_q_index < 0) {
+ spin_unlock_irqrestore(&dq->lock, flags_dq);
++ rc = -EAGAIN;
+ goto err_out_buf;
+ }
+ list_add_tail(&slot->delivery, &dq->list);
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-sas_queue_full-problem-while-running-io.patch b/patches.drivers/scsi-hisi_sas-fix-sas_queue_full-problem-while-running-io.patch
new file mode 100644
index 0000000000..e42ad65592
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-sas_queue_full-problem-while-running-io.patch
@@ -0,0 +1,42 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:48 +0800
+Subject: scsi: hisi_sas: fix SAS_QUEUE_FULL problem while running IO
+Git-commit: 9960a24a1c96a40d6ab984ffefdd0e3003a3377e
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+This patch fix SAS_QUEUE_FULL problem. The test situation is close port while
+running IO.
+
+In sas_eh_handle_sas_errors(), SCSI EH will free sas_task of the device if
+lldd_I_T_nexus_reset() return TMF_RESP_FUNC_COMPLETE or -ENODEV. But in our
+SAS driver, we only free slots of the device when the return value is
+TMF_RESP_FUNC_COMPLETE. So if the return value is -ENODEV, the slot resource
+will not free any more.
+
+As an solution, we should also free slots of the device in
+lldd_I_T_nexus_reset() if the return value is -ENODEV.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 302da84bf9ef..9bd98e5be78e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1308,7 +1308,7 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
+
+ rc = hisi_sas_debug_I_T_nexus_reset(device);
+
+- if (rc == TMF_RESP_FUNC_COMPLETE) {
++ if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV)) {
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_release_task(hisi_hba, device);
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
diff --git a/patches.drivers/scsi-hisi_sas-fix-the-issue-of-link-rate-inconsistency.patch b/patches.drivers/scsi-hisi_sas-fix-the-issue-of-link-rate-inconsistency.patch
new file mode 100644
index 0000000000..5272a4bbcf
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-the-issue-of-link-rate-inconsistency.patch
@@ -0,0 +1,124 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 7 Mar 2018 20:25:07 +0800
+Subject: scsi: hisi_sas: fix the issue of link rate inconsistency
+Git-commit: eba8c20c7178af9673ad842b0f68251c891c8546
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+In sysfs, there are two files about minimum linkrate, and also two files for
+maximum linkrate. Take maximum linkrate example, maximum_linkrate_hw is
+read-only and indicated by the register HARD_PHY_LINKRATE, and
+maximum_linkrate is read-write and corresponding to the register
+PROG_PHY_LINK_RATE.
+
+But in the function phy_up_v*_hw(), we get *_linkrate value from
+HARD_PHY_LINKRATE. It is not right. This patch is to fix this issue.
+
+Unreferenced PHY-interrupt enum is also removed for v3 hw.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 ++
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 8 +-------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 13 +------------
+ 4 files changed, 4 insertions(+), 20 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -683,6 +683,8 @@ static void hisi_sas_phy_init(struct his
+
+ phy->hisi_hba = hisi_hba;
+ phy->port = NULL;
++ phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
++ phy->maximum_linkrate = hisi_hba->hw->phy_get_max_linkrate();
+ init_timer(&phy->timer);
+ sas_phy->enabled = (phy_no < hisi_hba->n_phy) ? 1 : 0;
+ sas_phy->class = SAS;
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -873,7 +873,6 @@ static void phy_set_linkrate_v1_hw(struc
+ sas_phy->phy->maximum_linkrate = max;
+ sas_phy->phy->minimum_linkrate = min;
+
+- min -= SAS_LINK_RATE_1_5_GBPS;
+ max -= SAS_LINK_RATE_1_5_GBPS;
+
+ for (i = 0; i <= max; i++)
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1604,7 +1604,6 @@ static void phy_set_linkrate_v2_hw(struc
+ sas_phy->phy->maximum_linkrate = max;
+ sas_phy->phy->minimum_linkrate = min;
+
+- min -= SAS_LINK_RATE_1_5_GBPS;
+ max -= SAS_LINK_RATE_1_5_GBPS;
+
+ for (i = 0; i <= max; i++)
+@@ -2686,7 +2685,7 @@ static int prep_abort_v2_hw(struct hisi_
+ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
+ {
+ int i, res = IRQ_HANDLED;
+- u32 port_id, link_rate, hard_phy_linkrate;
++ u32 port_id, link_rate;
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ struct device *dev = hisi_hba->dev;
+@@ -2725,11 +2724,6 @@ static int phy_up_v2_hw(int phy_no, stru
+ }
+
+ sas_phy->linkrate = link_rate;
+- hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
+- HARD_PHY_LINKRATE);
+- phy->maximum_linkrate = hard_phy_linkrate & 0xf;
+- phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
+-
+ sas_phy->oob_mode = SAS_OOB_MODE;
+ memcpy(sas_phy->attached_sas_addr, &id->sas_addr, SAS_ADDR_SIZE);
+ dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -340,12 +340,6 @@ struct hisi_sas_err_record_v3 {
+ #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096
+ #define HISI_SAS_MSI_COUNT_V3_HW 32
+
+-enum {
+- HISI_SAS_PHY_PHY_UPDOWN,
+- HISI_SAS_PHY_CHNL_INT,
+- HISI_SAS_PHY_INT_NR
+-};
+-
+ #define DIR_NO_DATA 0
+ #define DIR_TO_INI 1
+ #define DIR_TO_DEVICE 2
+@@ -1121,7 +1115,7 @@ static int prep_abort_v3_hw(struct hisi_
+ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ {
+ int i, res = 0;
+- u32 context, port_id, link_rate, hard_phy_linkrate;
++ u32 context, port_id, link_rate;
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ struct device *dev = hisi_hba->dev;
+@@ -1139,10 +1133,6 @@ static int phy_up_v3_hw(int phy_no, stru
+ goto end;
+ }
+ sas_phy->linkrate = link_rate;
+- hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
+- HARD_PHY_LINKRATE);
+- phy->maximum_linkrate = hard_phy_linkrate & 0xf;
+- phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
+ phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
+
+ /* Check for SATA dev */
+@@ -1864,7 +1854,6 @@ static void phy_set_linkrate_v3_hw(struc
+ sas_phy->phy->maximum_linkrate = max;
+ sas_phy->phy->minimum_linkrate = min;
+
+- min -= SAS_LINK_RATE_1_5_GBPS;
+ max -= SAS_LINK_RATE_1_5_GBPS;
+
+ for (i = 0; i <= max; i++)
diff --git a/patches.drivers/scsi-hisi_sas-fix-the-issue-of-setting-linkrate-register.patch b/patches.drivers/scsi-hisi_sas-fix-the-issue-of-setting-linkrate-register.patch
new file mode 100644
index 0000000000..c10758c638
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-fix-the-issue-of-setting-linkrate-register.patch
@@ -0,0 +1,77 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 7 Mar 2018 20:25:08 +0800
+Subject: scsi: hisi_sas: fix the issue of setting linkrate register
+Git-commit: 0006ce29e87ba357f64ee73e92c8aefc270fd315
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+It is not right to set the register PROG_PHY_LINK_RATE while PHY is still
+enabled. So if we want to change PHY linkrate, we need to disable PHY before
+setting the register PROG_PHY_LINK_RATE, and then start-up PHY. This patch
+is to fix this issue.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 5 +++--
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 5 +++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 5 +++--
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 38bbda938bc1..2eb89806c512 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -881,10 +881,11 @@ static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no,
+ prog_phy_link_rate &= ~0xff;
+ prog_phy_link_rate |= rate_mask;
+
++ disable_phy_v1_hw(hisi_hba, phy_no);
++ msleep(100);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
+ prog_phy_link_rate);
+-
+- phy_hard_reset_v1_hw(hisi_hba, phy_no);
++ start_phy_v1_hw(hisi_hba, phy_no);
+ }
+
+ static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 67be346db239..bd1a48a590bc 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1611,10 +1611,11 @@ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,
+ prog_phy_link_rate &= ~0xff;
+ prog_phy_link_rate |= rate_mask;
+
++ disable_phy_v2_hw(hisi_hba, phy_no);
++ msleep(100);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
+ prog_phy_link_rate);
+-
+- phy_hard_reset_v2_hw(hisi_hba, phy_no);
++ start_phy_v2_hw(hisi_hba, phy_no);
+ }
+
+ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 1ee95abda1c5..8da9de7d67e5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1862,10 +1862,11 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
+ prog_phy_link_rate &= ~0xff;
+ prog_phy_link_rate |= rate_mask;
+
++ disable_phy_v3_hw(hisi_hba, phy_no);
++ msleep(100);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
+ prog_phy_link_rate);
+-
+- phy_hard_reset_v3_hw(hisi_hba, phy_no);
++ start_phy_v3_hw(hisi_hba, phy_no);
+ }
+
+ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba)
+
diff --git a/patches.drivers/scsi-hisi_sas-improve-int_chnl_int_v2_hw-consistency-with-v3-hw.patch b/patches.drivers/scsi-hisi_sas-improve-int_chnl_int_v2_hw-consistency-with-v3-hw.patch
new file mode 100644
index 0000000000..71b625268a
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-improve-int_chnl_int_v2_hw-consistency-with-v3-hw.patch
@@ -0,0 +1,92 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:42 +0800
+Subject: scsi: hisi_sas: improve int_chnl_int_v2_hw() consistency with v3 hw
+Git-commit: f64715d2837bee8fcd71f3e13acc7f02c9e9d98a
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Change code format of int_chnl_int_v2_hw() to be consistent with v3 hw to
+reduce an tag indent.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 58 ++++++++++++++++------------------
+ 1 file changed, 28 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 8d6886a452ef..4c4a000c5db0 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2848,40 +2848,38 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
+ HGC_INVLD_DQE_INFO_FB_CH3_OFF) & 0x1ff;
+
+ while (irq_msk) {
+- if (irq_msk & (1 << phy_no)) {
+- u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no,
+- CHL_INT0);
+- u32 irq_value1 = hisi_sas_phy_read32(hisi_hba, phy_no,
+- CHL_INT1);
+- u32 irq_value2 = hisi_sas_phy_read32(hisi_hba, phy_no,
+- CHL_INT2);
+-
+- if (irq_value1) {
+- if (irq_value1 & (CHL_INT1_DMAC_RX_ECC_ERR_MSK |
+- CHL_INT1_DMAC_TX_ECC_ERR_MSK))
+- panic("%s: DMAC RX/TX ecc bad error!\
+- (0x%x)",
+- dev_name(dev), irq_value1);
+-
+- hisi_sas_phy_write32(hisi_hba, phy_no,
+- CHL_INT1, irq_value1);
+- }
++ u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no,
++ CHL_INT0);
++ u32 irq_value1 = hisi_sas_phy_read32(hisi_hba, phy_no,
++ CHL_INT1);
++ u32 irq_value2 = hisi_sas_phy_read32(hisi_hba, phy_no,
++ CHL_INT2);
++
++ if ((irq_msk & (1 << phy_no)) && irq_value1) {
++ if (irq_value1 & (CHL_INT1_DMAC_RX_ECC_ERR_MSK |
++ CHL_INT1_DMAC_TX_ECC_ERR_MSK))
++ panic("%s: DMAC RX/TX ecc bad error!\
++ (0x%x)",
++ dev_name(dev), irq_value1);
+
+- if (irq_value2)
+- hisi_sas_phy_write32(hisi_hba, phy_no,
+- CHL_INT2, irq_value2);
++ hisi_sas_phy_write32(hisi_hba, phy_no,
++ CHL_INT1, irq_value1);
++ }
+
++ if ((irq_msk & (1 << phy_no)) && irq_value2)
++ hisi_sas_phy_write32(hisi_hba, phy_no,
++ CHL_INT2, irq_value2);
+
+- if (irq_value0) {
+- if (irq_value0 & CHL_INT0_SL_RX_BCST_ACK_MSK)
+- phy_bcast_v2_hw(phy_no, hisi_hba);
+
+- hisi_sas_phy_write32(hisi_hba, phy_no,
+- CHL_INT0, irq_value0
+- & (~CHL_INT0_HOTPLUG_TOUT_MSK)
+- & (~CHL_INT0_SL_PHY_ENABLE_MSK)
+- & (~CHL_INT0_NOT_RDY_MSK));
+- }
++ if ((irq_msk & (1 << phy_no)) && irq_value0) {
++ if (irq_value0 & CHL_INT0_SL_RX_BCST_ACK_MSK)
++ phy_bcast_v2_hw(phy_no, hisi_hba);
++
++ hisi_sas_phy_write32(hisi_hba, phy_no,
++ CHL_INT0, irq_value0
++ & (~CHL_INT0_HOTPLUG_TOUT_MSK)
++ & (~CHL_INT0_SL_PHY_ENABLE_MSK)
++ & (~CHL_INT0_NOT_RDY_MSK));
+ }
+ irq_msk &= ~(1 << phy_no);
+ phy_no++;
+
diff --git a/patches.drivers/scsi-hisi_sas-include-tmf-elements-in-struct-hisi_sas_slot.patch b/patches.drivers/scsi-hisi_sas-include-tmf-elements-in-struct-hisi_sas_slot.patch
new file mode 100644
index 0000000000..9a7af9c49d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-include-tmf-elements-in-struct-hisi_sas_slot.patch
@@ -0,0 +1,256 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Mon, 21 May 2018 18:09:21 +0800
+Subject: scsi: hisi_sas: Include TMF elements in struct hisi_sas_slot
+Git-commit: 78bd2b4f6e7c0522cc8bc8ad651f20813ae06f6c
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+In future scenarios we will want to use the TMF struct for more task types
+than SSP.
+
+As such, we can add struct hisi_sas_tmf_task directly into struct
+hisi_sas_slot, and this will mean we can remove the TMF parameters from the
+task prep functions.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 14 +++++++-------
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 15 +++++++--------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 12 ++++++------
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 10 +++++-----
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 +++++-----
+ 5 files changed, 30 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 8ce6abb48867..60bd652534fe 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -179,6 +179,11 @@ struct hisi_sas_device {
+ u8 dev_status;
+ };
+
++struct hisi_sas_tmf_task {
++ u8 tmf;
++ u16 tag_of_task_to_be_managed;
++};
++
+ struct hisi_sas_slot {
+ struct list_head entry;
+ struct list_head delivery;
+@@ -199,11 +204,7 @@ struct hisi_sas_slot {
+ struct work_struct abort_slot;
+ struct timer_list internal_abort_timer;
+ bool is_internal;
+-};
+-
+-struct hisi_sas_tmf_task {
+- u8 tmf;
+- u16 tag_of_task_to_be_managed;
++ struct hisi_sas_tmf_task *tmf;
+ };
+
+ struct hisi_sas_hw {
+@@ -217,8 +218,7 @@ struct hisi_sas_hw {
+ int (*get_free_slot)(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq);
+ void (*start_delivery)(struct hisi_sas_dq *dq);
+ void (*prep_ssp)(struct hisi_hba *hisi_hba,
+- struct hisi_sas_slot *slot, int is_tmf,
+- struct hisi_sas_tmf_task *tmf);
++ struct hisi_sas_slot *slot);
+ void (*prep_smp)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot);
+ void (*prep_stp)(struct hisi_hba *hisi_hba,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 5bc522c35690..4e8046ecf477 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -266,10 +266,9 @@ static void hisi_sas_task_prep_smp(struct hisi_hba *hisi_hba,
+ }
+
+ static void hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba,
+- struct hisi_sas_slot *slot, int is_tmf,
+- struct hisi_sas_tmf_task *tmf)
++ struct hisi_sas_slot *slot)
+ {
+- hisi_hba->hw->prep_ssp(hisi_hba, slot, is_tmf, tmf);
++ hisi_hba->hw->prep_ssp(hisi_hba, slot);
+ }
+
+ static void hisi_sas_task_prep_ata(struct hisi_hba *hisi_hba,
+@@ -322,7 +321,7 @@ static void hisi_sas_slot_abort(struct work_struct *work)
+
+ static int hisi_sas_task_prep(struct sas_task *task,
+ struct hisi_sas_dq **dq_pointer,
+- int is_tmf, struct hisi_sas_tmf_task *tmf,
++ bool is_tmf, struct hisi_sas_tmf_task *tmf,
+ int *pass)
+ {
+ struct domain_device *device = task->dev;
+@@ -461,8 +460,8 @@ static int hisi_sas_task_prep(struct sas_task *task,
+ slot->cmd_hdr = &cmd_hdr_base[dlvry_queue_slot];
+ slot->task = task;
+ slot->port = port;
+- if (is_tmf)
+- slot->is_internal = true;
++ slot->tmf = tmf;
++ slot->is_internal = is_tmf;
+ task->lldd_task = slot;
+ INIT_WORK(&slot->abort_slot, hisi_sas_slot_abort);
+
+@@ -475,7 +474,7 @@ static int hisi_sas_task_prep(struct sas_task *task,
+ hisi_sas_task_prep_smp(hisi_hba, slot);
+ break;
+ case SAS_PROTOCOL_SSP:
+- hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf);
++ hisi_sas_task_prep_ssp(hisi_hba, slot);
+ break;
+ case SAS_PROTOCOL_SATA:
+ case SAS_PROTOCOL_STP:
+@@ -527,7 +526,7 @@ static int hisi_sas_task_prep(struct sas_task *task,
+ }
+
+ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
+- int is_tmf, struct hisi_sas_tmf_task *tmf)
++ bool is_tmf, struct hisi_sas_tmf_task *tmf)
+ {
+ u32 rc;
+ u32 pass = 0;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 8d5d8575d939..05609ac1b31d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -986,8 +986,7 @@ static void prep_smp_v1_hw(struct hisi_hba *hisi_hba,
+ }
+
+ static void prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
+- struct hisi_sas_slot *slot, int is_tmf,
+- struct hisi_sas_tmf_task *tmf)
++ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+@@ -996,7 +995,8 @@ static void prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_port *port = slot->port;
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+- int has_data = 0, priority = is_tmf;
++ struct hisi_sas_tmf_task *tmf = slot->tmf;
++ int has_data = 0, priority = !!tmf;
+ u8 *buf_cmd, fburst = 0;
+ u32 dw1, dw2;
+
+@@ -1010,7 +1010,7 @@ static void prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
+
+ dw1 = 1 << CMD_HDR_VERIFY_DTL_OFF;
+
+- if (is_tmf) {
++ if (tmf) {
+ dw1 |= 3 << CMD_HDR_SSP_FRAME_TYPE_OFF;
+ } else {
+ switch (scsi_cmnd->sc_data_direction) {
+@@ -1031,7 +1031,7 @@ static void prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
+ dw1 |= sas_dev->device_id << CMD_HDR_DEVICE_ID_OFF;
+ hdr->dw1 = cpu_to_le32(dw1);
+
+- if (is_tmf) {
++ if (tmf) {
+ dw2 = ((sizeof(struct ssp_tmf_iu) +
+ sizeof(struct ssp_frame_hdr)+3)/4) <<
+ CMD_HDR_CFL_OFF;
+@@ -1062,7 +1062,7 @@ static void prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
+ hdr->dw2 = cpu_to_le32(dw2);
+
+ memcpy(buf_cmd, &task->ssp_task.LUN, 8);
+- if (!is_tmf) {
++ if (!tmf) {
+ buf_cmd[9] = fburst | task->ssp_task.task_attr |
+ (task->ssp_task.task_prio << 3);
+ memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 18dbaffc9988..fafb3f1835be 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1745,8 +1745,7 @@ static void prep_smp_v2_hw(struct hisi_hba *hisi_hba,
+ }
+
+ static void prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
+- struct hisi_sas_slot *slot, int is_tmf,
+- struct hisi_sas_tmf_task *tmf)
++ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+@@ -1755,7 +1754,8 @@ static void prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_port *port = slot->port;
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+- int has_data = 0, priority = is_tmf;
++ struct hisi_sas_tmf_task *tmf = slot->tmf;
++ int has_data = 0, priority = !!tmf;
+ u8 *buf_cmd;
+ u32 dw1 = 0, dw2 = 0;
+
+@@ -1766,7 +1766,7 @@ static void prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
+ (1 << CMD_HDR_CMD_OFF)); /* ssp */
+
+ dw1 = 1 << CMD_HDR_VDTL_OFF;
+- if (is_tmf) {
++ if (tmf) {
+ dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF;
+ dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF;
+ } else {
+@@ -1809,7 +1809,7 @@ static void prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
+ sizeof(struct ssp_frame_hdr);
+
+ memcpy(buf_cmd, &task->ssp_task.LUN, 8);
+- if (!is_tmf) {
++ if (!tmf) {
+ buf_cmd[9] = task->ssp_task.task_attr |
+ (task->ssp_task.task_prio << 3);
+ memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index dd5f542bbc45..8c996aa42528 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -911,8 +911,7 @@ static void prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba,
+ }
+
+ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+- struct hisi_sas_slot *slot, int is_tmf,
+- struct hisi_sas_tmf_task *tmf)
++ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+@@ -921,7 +920,8 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_port *port = slot->port;
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+- int has_data = 0, priority = is_tmf;
++ struct hisi_sas_tmf_task *tmf = slot->tmf;
++ int has_data = 0, priority = !!tmf;
+ u8 *buf_cmd;
+ u32 dw1 = 0, dw2 = 0;
+
+@@ -932,7 +932,7 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ (1 << CMD_HDR_CMD_OFF)); /* ssp */
+
+ dw1 = 1 << CMD_HDR_VDTL_OFF;
+- if (is_tmf) {
++ if (tmf) {
+ dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF;
+ dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF;
+ } else {
+@@ -974,7 +974,7 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ sizeof(struct ssp_frame_hdr);
+
+ memcpy(buf_cmd, &task->ssp_task.LUN, 8);
+- if (!is_tmf) {
++ if (!tmf) {
+ buf_cmd[9] = ssp_task->task_attr | (ssp_task->task_prio << 3);
+ memcpy(buf_cmd + 12, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
+ } else {
+
diff --git a/patches.drivers/scsi-hisi_sas-increase-timer-expire-of-internal-abort-task.patch b/patches.drivers/scsi-hisi_sas-increase-timer-expire-of-internal-abort-task.patch
new file mode 100644
index 0000000000..26dafefa9d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-increase-timer-expire-of-internal-abort-task.patch
@@ -0,0 +1,44 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 7 Mar 2018 20:25:09 +0800
+Subject: scsi: hisi_sas: increase timer expire of internal abort task
+Git-commit: bb9abc4af5449d2a72cda876be950988e8b2b888
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+The current 110ms expiry time is not long enough for the internal abort
+task.
+
+The reason is that the internal abort task could be blocked in HW if the HW
+is retrying to set up link. The internal abort task will be executed only
+when the retry process finished.
+
+The maximum time is 5s for the retry of setting up link. So, the timer
+expire should be more than 5s. This patch increases it from 110ms to 6s.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -871,6 +871,7 @@ static void hisi_sas_tmf_timedout(unsign
+
+ #define TASK_TIMEOUT 20
+ #define TASK_RETRY 3
++#define INTERNAL_ABORT_TIMEOUT 6
+ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device,
+ void *parameter, u32 para_len,
+ struct hisi_sas_tmf_task *tmf)
+@@ -1576,7 +1577,7 @@ hisi_sas_internal_task_abort(struct hisi
+ task->task_done = hisi_sas_task_done;
+ task->slow_task->timer.data = (unsigned long)task;
+ task->slow_task->timer.function = hisi_sas_tmf_timedout;
+- task->slow_task->timer.expires = jiffies + msecs_to_jiffies(110);
++ task->slow_task->timer.expires = jiffies + INTERNAL_ABORT_TIMEOUT*HZ;
+ add_timer(&task->slow_task->timer);
+
+ res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id,
diff --git a/patches.drivers/scsi-hisi_sas-init-disks-after-controller-reset.patch b/patches.drivers/scsi-hisi_sas-init-disks-after-controller-reset.patch
new file mode 100644
index 0000000000..8e04434fc2
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-init-disks-after-controller-reset.patch
@@ -0,0 +1,79 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Mon, 21 May 2018 18:09:19 +0800
+Subject: scsi: hisi_sas: Init disks after controller reset
+Git-commit: 6175abdeaeaf2602f3e92bd4eca5916e98efe996
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+After the controller is reset, it is possible that the disks attached still
+have outstanding IO to complete.
+
+Thus, when the PHYs come back up after controller reset, it is possible
+that these IOs complete at some unknown point later.
+
+We want to ensure that all IOs are complete after the controller reset so
+that all associated IPTT and other resources can be recycled safely.
+
+To achieve this, re-init the disks by TMF or softreset (in case of ATA
+devices).
+
+If the init fails - maybe because the device was removed or link has not
+come up - then do not release the device resources, but rather rely on SCSI
+EH to handle the timeout for these resources later on.
+
+This patch also does some cleanup to hisi_sas_init_disk(), including
+removing superfluous cases in the switch statement.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 664aaf7f5147..dc67bd7c7ab0 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1259,6 +1259,23 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state,
+ }
+ }
+
++static void hisi_sas_reset_init_all_devices(struct hisi_hba *hisi_hba)
++{
++ struct hisi_sas_device *sas_dev;
++ struct domain_device *device;
++ int i;
++
++ for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
++ sas_dev = &hisi_hba->devices[i];
++ device = sas_dev->sas_device;
++
++ if ((sas_dev->dev_type == SAS_PHY_UNUSED) || !device)
++ continue;
++
++ hisi_sas_init_device(device);
++ }
++}
++
+ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ {
+ struct device *dev = hisi_hba->dev;
+@@ -1287,7 +1304,6 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ scsi_unblock_requests(shost);
+ goto out;
+ }
+- hisi_sas_release_tasks(hisi_hba);
+
+ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+
+@@ -1295,6 +1311,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ hisi_hba->hw->phys_init(hisi_hba);
+ msleep(1000);
+ hisi_sas_refresh_port_id(hisi_hba);
++ hisi_sas_reset_init_all_devices(hisi_hba);
+ scsi_unblock_requests(shost);
+
+ state = hisi_hba->hw->get_phys_state(hisi_hba);
+
diff --git a/patches.drivers/scsi-hisi_sas-initialize-dq-spinlock-before-use.patch b/patches.drivers/scsi-hisi_sas-initialize-dq-spinlock-before-use.patch
new file mode 100644
index 0000000000..36c894c024
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-initialize-dq-spinlock-before-use.patch
@@ -0,0 +1,32 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:32 +0800
+Subject: scsi: hisi_sas: initialize dq spinlock before use
+Git-commit: 39bade0c9fb11e04945a5749e01e65a376e4eb02
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+It is required to initialize the dq spinlock before use, which was not being
+done, so fix it. This issue can be detected when CONFIG_DEBUG_SPINLOCK is
+enabled.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 5f503cb09508..359ec52fc2fb 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1657,6 +1657,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
+ cq->hisi_hba = hisi_hba;
+
+ /* Delivery queue structure */
++ spin_lock_init(&dq->lock);
+ dq->id = i;
+ dq->hisi_hba = hisi_hba;
+
+
diff --git a/patches.drivers/scsi-hisi_sas-introduce-hisi_sas_phy_set_linkrate.patch b/patches.drivers/scsi-hisi_sas-introduce-hisi_sas_phy_set_linkrate.patch
new file mode 100644
index 0000000000..eb9a166471
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-introduce-hisi_sas_phy_set_linkrate.patch
@@ -0,0 +1,191 @@
+From: John Garry <john.garry@huawei.com>
+Date: Mon, 21 May 2018 18:09:13 +0800
+Subject: scsi: hisi_sas: Introduce hisi_sas_phy_set_linkrate()
+Git-commit: 757db2dae2c79b1f713043fcc13542683963fa82
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+There is much common code and functionality between the HW versions to set
+the PHY linkrate.
+
+As such, this patch factors out the common code into a generic function
+hisi_sas_phy_set_linkrate().
+
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 29 +++++++++++++++++++++++++++-
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 35 ++++------------------------------
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 21 ++------------------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 21 ++------------------
+ 4 files changed, 36 insertions(+), 70 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 6d3796553272..66388741e73c 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -866,6 +866,33 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags)
+ return hisi_sas_task_exec(task, gfp_flags, 0, NULL);
+ }
+
++static void hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
++ struct sas_phy_linkrates *r)
++{
++ struct sas_phy_linkrates _r;
++
++ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
++ struct asd_sas_phy *sas_phy = &phy->sas_phy;
++ enum sas_linkrate min, max;
++
++ if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
++ max = sas_phy->phy->maximum_linkrate;
++ min = r->minimum_linkrate;
++ } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
++ max = r->maximum_linkrate;
++ min = sas_phy->phy->minimum_linkrate;
++ } else
++ return;
++
++ _r.maximum_linkrate = max;
++ _r.minimum_linkrate = min;
++
++ hisi_hba->hw->phy_disable(hisi_hba, phy_no);
++ msleep(100);
++ hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r);
++ hisi_hba->hw->phy_start(hisi_hba, phy_no);
++}
++
+ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
+ void *funcdata)
+ {
+@@ -889,7 +916,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
+ break;
+
+ case PHY_FUNC_SET_LINK_RATE:
+- hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, funcdata);
++ hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata);
+ break;
+ case PHY_FUNC_GET_EVENTS:
+ if (hisi_hba->hw->get_events) {
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index abe175fddb86..8fa79d0968a6 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -855,39 +855,12 @@ static enum sas_linkrate phy_get_max_linkrate_v1_hw(void)
+ static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no,
+ struct sas_phy_linkrates *r)
+ {
+- u32 prog_phy_link_rate =
+- hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE);
+- struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+- struct asd_sas_phy *sas_phy = &phy->sas_phy;
+- int i;
+- enum sas_linkrate min, max;
+- u32 rate_mask = 0;
+-
+- if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+- max = sas_phy->phy->maximum_linkrate;
+- min = r->minimum_linkrate;
+- } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+- max = r->maximum_linkrate;
+- min = sas_phy->phy->minimum_linkrate;
+- } else
+- return;
+-
+- sas_phy->phy->maximum_linkrate = max;
+- sas_phy->phy->minimum_linkrate = min;
+-
+- max -= SAS_LINK_RATE_1_5_GBPS;
++ enum sas_linkrate max = r->maximum_linkrate;
++ u32 prog_phy_link_rate = 0x800;
+
+- for (i = 0; i <= max; i++)
+- rate_mask |= 1 << (i * 2);
+-
+- prog_phy_link_rate &= ~0xff;
+- prog_phy_link_rate |= rate_mask;
+-
+- disable_phy_v1_hw(hisi_hba, phy_no);
+- msleep(100);
++ prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
+- prog_phy_link_rate);
+- start_phy_v1_hw(hisi_hba, phy_no);
++ prog_phy_link_rate);
+ }
+
+ static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 911bb76a4d0a..fb0e966a44a8 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1600,29 +1600,12 @@ static enum sas_linkrate phy_get_max_linkrate_v2_hw(void)
+ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,
+ struct sas_phy_linkrates *r)
+ {
+- struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+- struct asd_sas_phy *sas_phy = &phy->sas_phy;
+- enum sas_linkrate min, max;
++ enum sas_linkrate max = r->maximum_linkrate;
+ u32 prog_phy_link_rate = 0x800;
+
+- if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+- max = sas_phy->phy->maximum_linkrate;
+- min = r->minimum_linkrate;
+- } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+- max = r->maximum_linkrate;
+- min = sas_phy->phy->minimum_linkrate;
+- } else
+- return;
+-
+- sas_phy->phy->maximum_linkrate = max;
+- sas_phy->phy->minimum_linkrate = min;
+ prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
+-
+- disable_phy_v2_hw(hisi_hba, phy_no);
+- msleep(100);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
+- prog_phy_link_rate);
+- start_phy_v2_hw(hisi_hba, phy_no);
++ prog_phy_link_rate);
+ }
+
+ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index c013673ee8ac..0a80a39eccdd 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1879,29 +1879,12 @@ static int hisi_sas_v3_init(struct hisi_hba *hisi_hba)
+ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
+ struct sas_phy_linkrates *r)
+ {
+- struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+- struct asd_sas_phy *sas_phy = &phy->sas_phy;
+- enum sas_linkrate min, max;
++ enum sas_linkrate max = r->maximum_linkrate;
+ u32 prog_phy_link_rate = 0x800;
+
+- if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+- max = sas_phy->phy->maximum_linkrate;
+- min = r->minimum_linkrate;
+- } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+- max = r->maximum_linkrate;
+- min = sas_phy->phy->minimum_linkrate;
+- } else
+- return;
+-
+- sas_phy->phy->maximum_linkrate = max;
+- sas_phy->phy->minimum_linkrate = min;
+ prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
+-
+- disable_phy_v3_hw(hisi_hba, phy_no);
+- msleep(100);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
+- prog_phy_link_rate);
+- start_phy_v3_hw(hisi_hba, phy_no);
++ prog_phy_link_rate);
+ }
+
+ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba)
+
diff --git a/patches.drivers/scsi-hisi_sas-judge-result-of-internal-abort.patch b/patches.drivers/scsi-hisi_sas-judge-result-of-internal-abort.patch
new file mode 100644
index 0000000000..a85c1c3306
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-judge-result-of-internal-abort.patch
@@ -0,0 +1,137 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:46 +0800
+Subject: scsi: hisi_sas: judge result of internal abort
+Git-commit: 813709f2e1e07fa872c05f43801a05828d33a70a
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Normally, hardware should ensure that internal abort timeout will never
+happen. If happen, it would be an SoC failure. What's more, HW will not
+process any other commands if an internal abort hasn't return CQ, and they
+will time out also.
+
+So, we should judge the result of internal abort in SCSI EH, if it is failed,
+we should give up to do TMF/softreset and return failure to the upper layer
+directly.
+
+This patch do following things to achieve this:
+
+1. When internal abort timeout happened, we set return value to -EIO in
+ hisi_sas_internal_task_abort().
+
+2. If prep_abort() is not support, let hisi_sas_internal_task_abort() return
+ TMF_RESP_FUNC_FAILED.
+
+3. If hisi_sas_internal_task_abort() return an negative number, it can be
+ thought that it not executed properly or internal abort timeout. Then we
+ won't do behind TMF or softreset, and return failure directly.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 38 ++++++++++++++++++++++++++++-------
+ 1 file changed, 31 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 7446a39f9442..1b9c48c99968 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1184,6 +1184,11 @@ static int hisi_sas_abort_task(struct sas_task *task)
+
+ rc2 = hisi_sas_internal_task_abort(hisi_hba, device,
+ HISI_SAS_INT_ABT_CMD, tag);
++ if (rc2 < 0) {
++ dev_err(dev, "abort task: internal abort (%d)\n", rc2);
++ return TMF_RESP_FUNC_FAILED;
++ }
++
+ /*
+ * If the TMF finds that the IO is not in the device and also
+ * the internal abort does not succeed, then it is safe to
+@@ -1201,8 +1206,12 @@ static int hisi_sas_abort_task(struct sas_task *task)
+ } else if (task->task_proto & SAS_PROTOCOL_SATA ||
+ task->task_proto & SAS_PROTOCOL_STP) {
+ if (task->dev->dev_type == SAS_SATA_DEV) {
+- hisi_sas_internal_task_abort(hisi_hba, device,
+- HISI_SAS_INT_ABT_DEV, 0);
++ rc = hisi_sas_internal_task_abort(hisi_hba, device,
++ HISI_SAS_INT_ABT_DEV, 0);
++ if (rc < 0) {
++ dev_err(dev, "abort task: internal abort failed\n");
++ goto out;
++ }
+ hisi_sas_dereg_device(hisi_hba, device);
+ rc = hisi_sas_softreset_ata_disk(device);
+ }
+@@ -1213,7 +1222,8 @@ static int hisi_sas_abort_task(struct sas_task *task)
+
+ rc = hisi_sas_internal_task_abort(hisi_hba, device,
+ HISI_SAS_INT_ABT_CMD, tag);
+- if (rc == TMF_RESP_FUNC_FAILED && task->lldd_task) {
++ if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) &&
++ task->lldd_task) {
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_do_release_task(hisi_hba, task, slot);
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+@@ -1263,15 +1273,20 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
+ {
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+- unsigned long flags;
++ struct device *dev = hisi_hba->dev;
+ int rc = TMF_RESP_FUNC_FAILED;
++ unsigned long flags;
+
+ if (sas_dev->dev_status != HISI_SAS_DEV_EH)
+ return TMF_RESP_FUNC_FAILED;
+ sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
+
+- hisi_sas_internal_task_abort(hisi_hba, device,
++ rc = hisi_sas_internal_task_abort(hisi_hba, device,
+ HISI_SAS_INT_ABT_DEV, 0);
++ if (rc < 0) {
++ dev_err(dev, "I_T nexus reset: internal abort (%d)\n", rc);
++ return TMF_RESP_FUNC_FAILED;
++ }
+ hisi_sas_dereg_device(hisi_hba, device);
+
+ rc = hisi_sas_debug_I_T_nexus_reset(device);
+@@ -1299,8 +1314,10 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun)
+ /* Clear internal IO and then hardreset */
+ rc = hisi_sas_internal_task_abort(hisi_hba, device,
+ HISI_SAS_INT_ABT_DEV, 0);
+- if (rc == TMF_RESP_FUNC_FAILED)
++ if (rc < 0) {
++ dev_err(dev, "lu_reset: internal abort failed\n");
+ goto out;
++ }
+ hisi_sas_dereg_device(hisi_hba, device);
+
+ phy = sas_get_local_phy(device);
+@@ -1497,8 +1514,14 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
+ struct device *dev = hisi_hba->dev;
+ int res;
+
++ /*
++ * The interface is not realized means this HW don't support internal
++ * abort, or don't need to do internal abort. Then here, we return
++ * TMF_RESP_FUNC_FAILED and let other steps go on, which depends that
++ * the internal abort has been executed and returned CQ.
++ */
+ if (!hisi_hba->hw->prep_abort)
+- return -EOPNOTSUPP;
++ return TMF_RESP_FUNC_FAILED;
+
+ task = sas_alloc_slow_task(GFP_KERNEL);
+ if (!task)
+@@ -1530,6 +1553,7 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
+ if (slot)
+ slot->task = NULL;
+ dev_err(dev, "internal task abort: timeout and not done.\n");
++ res = -EIO;
+ goto exit;
+ } else
+ dev_err(dev, "internal task abort: timeout.\n");
+
diff --git a/patches.drivers/scsi-hisi_sas-make-local-symbol-host_attrs-static.patch b/patches.drivers/scsi-hisi_sas-make-local-symbol-host_attrs-static.patch
new file mode 100644
index 0000000000..cb6ac05472
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-make-local-symbol-host_attrs-static.patch
@@ -0,0 +1,34 @@
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Thu, 11 Jan 2018 11:13:58 +0000
+Subject: scsi: hisi_sas: make local symbol host_attrs static
+Git-commit: 1e15feacb9d3743ca0b314a6daf8cc59c90b1046
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Fixes the following sparse warning:
+
+drivers/scsi/hisi_sas/hisi_sas_main.c:1691:25: warning:
+ symbol 'host_attrs' was not declared. Should it be static?
+
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Acked-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 360ecefba10a..e3e7285f5eb1 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1688,7 +1688,7 @@ EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets);
+ struct scsi_transport_template *hisi_sas_stt;
+ EXPORT_SYMBOL_GPL(hisi_sas_stt);
+
+-struct device_attribute *host_attrs[] = {
++static struct device_attribute *host_attrs[] = {
+ &dev_attr_phy_event_threshold,
+ NULL,
+ };
+
diff --git a/patches.drivers/scsi-hisi_sas-make-return-type-of-prep-functions-void.patch b/patches.drivers/scsi-hisi_sas-make-return-type-of-prep-functions-void.patch
new file mode 100644
index 0000000000..1c0c860b4d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-make-return-type-of-prep-functions-void.patch
@@ -0,0 +1,532 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 9 May 2018 23:10:46 +0800
+Subject: scsi: hisi_sas: make return type of prep functions void
+Git-commit: a2b3820bddfbffcfbf0e8170e77de65d8b8def98
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Since the task prep functions now should not fail, adjust the return
+types to void.
+
+In addition, some checks in the task prep functions are relocated to the
+main module; this is specifically the check for the number of elements
+in an sg list exceeded the HW SGE limit.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 8 ++---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 45 +++++++++++++--------------------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 28 ++++----------------
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 45 ++++++++-------------------------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 43 ++++++++-----------------------
+ 5 files changed, 51 insertions(+), 118 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -215,14 +215,14 @@ struct hisi_sas_hw {
+ void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no);
+ int (*get_free_slot)(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq);
+ void (*start_delivery)(struct hisi_sas_dq *dq);
+- int (*prep_ssp)(struct hisi_hba *hisi_hba,
++ void (*prep_ssp)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot, int is_tmf,
+ struct hisi_sas_tmf_task *tmf);
+- int (*prep_smp)(struct hisi_hba *hisi_hba,
++ void (*prep_smp)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot);
+- int (*prep_stp)(struct hisi_hba *hisi_hba,
++ void (*prep_stp)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot);
+- int (*prep_abort)(struct hisi_hba *hisi_hba,
++ void (*prep_abort)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot,
+ int device_id, int abort_flag, int tag_to_abort);
+ int (*slot_complete)(struct hisi_hba *hisi_hba,
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -243,30 +243,30 @@ void hisi_sas_slot_task_free(struct hisi
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free);
+
+-static int hisi_sas_task_prep_smp(struct hisi_hba *hisi_hba,
++static void hisi_sas_task_prep_smp(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot)
+ {
+- return hisi_hba->hw->prep_smp(hisi_hba, slot);
++ hisi_hba->hw->prep_smp(hisi_hba, slot);
+ }
+
+-static int hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba,
++static void hisi_sas_task_prep_ssp(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot, int is_tmf,
+ struct hisi_sas_tmf_task *tmf)
+ {
+- return hisi_hba->hw->prep_ssp(hisi_hba, slot, is_tmf, tmf);
++ hisi_hba->hw->prep_ssp(hisi_hba, slot, is_tmf, tmf);
+ }
+
+-static int hisi_sas_task_prep_ata(struct hisi_hba *hisi_hba,
++static void hisi_sas_task_prep_ata(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot)
+ {
+- return hisi_hba->hw->prep_stp(hisi_hba, slot);
++ hisi_hba->hw->prep_stp(hisi_hba, slot);
+ }
+
+-static int hisi_sas_task_prep_abort(struct hisi_hba *hisi_hba,
++static void hisi_sas_task_prep_abort(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot,
+ int device_id, int abort_flag, int tag_to_abort)
+ {
+- return hisi_hba->hw->prep_abort(hisi_hba, slot,
++ hisi_hba->hw->prep_abort(hisi_hba, slot,
+ device_id, abort_flag, tag_to_abort);
+ }
+
+@@ -395,6 +395,13 @@ static int hisi_sas_task_prep(struct sas
+ } else
+ n_elem = task->num_scatter;
+
++ if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
++ dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
++ n_elem);
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ if (hisi_hba->hw->slot_index_alloc)
+ rc = hisi_hba->hw->slot_index_alloc(hisi_hba, &slot_idx,
+@@ -439,28 +446,22 @@ static int hisi_sas_task_prep(struct sas
+
+ switch (task->task_proto) {
+ case SAS_PROTOCOL_SMP:
+- rc = hisi_sas_task_prep_smp(hisi_hba, slot);
++ hisi_sas_task_prep_smp(hisi_hba, slot);
+ break;
+ case SAS_PROTOCOL_SSP:
+- rc = hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf);
++ hisi_sas_task_prep_ssp(hisi_hba, slot, is_tmf, tmf);
+ break;
+ case SAS_PROTOCOL_SATA:
+ case SAS_PROTOCOL_STP:
+ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+- rc = hisi_sas_task_prep_ata(hisi_hba, slot);
++ hisi_sas_task_prep_ata(hisi_hba, slot);
+ break;
+ default:
+ dev_err(dev, "task prep: unknown/unsupported proto (0x%x)\n",
+ task->task_proto);
+- rc = -EINVAL;
+ break;
+ }
+
+- if (rc) {
+- dev_err(dev, "task prep: rc = 0x%x\n", rc);
+- goto err_out_buf;
+- }
+-
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ list_add_tail(&slot->entry, &sas_dev->list);
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+@@ -473,9 +474,6 @@ static int hisi_sas_task_prep(struct sas
+
+ return 0;
+
+-err_out_buf:
+- dma_pool_free(hisi_hba->buffer_pool, slot->buf,
+- slot->buf_dma);
+ err_out_slot_buf:
+ /* Nothing to be done */
+ err_out_tag:
+@@ -1555,10 +1553,8 @@ hisi_sas_internal_abort_task_exec(struct
+ memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ);
+ memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ);
+
+- rc = hisi_sas_task_prep_abort(hisi_hba, slot, device_id,
++ hisi_sas_task_prep_abort(hisi_hba, slot, device_id,
+ abort_flag, task_tag);
+- if (rc)
+- goto err_out_buf;
+
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ list_add_tail(&slot->entry, &sas_dev->list);
+@@ -1575,9 +1571,6 @@ hisi_sas_internal_abort_task_exec(struct
+
+ return 0;
+
+-err_out_buf:
+- dma_pool_free(hisi_hba->buffer_pool, slot->buf,
+- slot->buf_dma);
+ err_out_tag:
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -935,23 +935,16 @@ static void start_delivery_v1_hw(struct
+ dq->wr_point);
+ }
+
+-static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba,
++static void prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot,
+ struct hisi_sas_cmd_hdr *hdr,
+ struct scatterlist *scatter,
+ int n_elem)
+ {
+ struct hisi_sas_sge_page *sge_page = hisi_sas_sge_addr_mem(slot);
+- struct device *dev = hisi_hba->dev;
+ struct scatterlist *sg;
+ int i;
+
+- if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
+- dev_err(dev, "prd err: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
+- n_elem);
+- return -EINVAL;
+- }
+-
+ for_each_sg(scatter, sg, n_elem, i) {
+ struct hisi_sas_sge *entry = &sge_page->sge[i];
+
+@@ -964,11 +957,9 @@ static int prep_prd_sge_v1_hw(struct his
+ hdr->prd_table_addr = cpu_to_le64(hisi_sas_sge_addr_dma(slot));
+
+ hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF);
+-
+- return 0;
+ }
+
+-static int prep_smp_v1_hw(struct hisi_hba *hisi_hba,
++static void prep_smp_v1_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+@@ -1004,11 +995,9 @@ static int prep_smp_v1_hw(struct hisi_hb
+
+ hdr->cmd_table_addr = cpu_to_le64(req_dma_addr);
+ hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));
+-
+- return 0;
+ }
+
+-static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
++static void prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot, int is_tmf,
+ struct hisi_sas_tmf_task *tmf)
+ {
+@@ -1019,7 +1008,7 @@ static int prep_ssp_v1_hw(struct hisi_hb
+ struct hisi_sas_port *port = slot->port;
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+- int has_data = 0, rc, priority = is_tmf;
++ int has_data = 0, priority = is_tmf;
+ u8 *buf_cmd, fburst = 0;
+ u32 dw1, dw2;
+
+@@ -1068,12 +1057,9 @@ static int prep_ssp_v1_hw(struct hisi_hb
+
+ hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF);
+
+- if (has_data) {
+- rc = prep_prd_sge_v1_hw(hisi_hba, slot, hdr, task->scatter,
++ if (has_data)
++ prep_prd_sge_v1_hw(hisi_hba, slot, hdr, task->scatter,
+ slot->n_elem);
+- if (rc)
+- return rc;
+- }
+
+ hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
+ hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));
+@@ -1107,8 +1093,6 @@ static int prep_ssp_v1_hw(struct hisi_hb
+ break;
+ }
+ }
+-
+- return 0;
+ }
+
+ /* by default, task resp is complete */
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1683,23 +1683,16 @@ static void start_delivery_v2_hw(struct
+ dq->wr_point);
+ }
+
+-static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,
++static void prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot,
+ struct hisi_sas_cmd_hdr *hdr,
+ struct scatterlist *scatter,
+ int n_elem)
+ {
+ struct hisi_sas_sge_page *sge_page = hisi_sas_sge_addr_mem(slot);
+- struct device *dev = hisi_hba->dev;
+ struct scatterlist *sg;
+ int i;
+
+- if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
+- dev_err(dev, "prd err: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
+- n_elem);
+- return -EINVAL;
+- }
+-
+ for_each_sg(scatter, sg, n_elem, i) {
+ struct hisi_sas_sge *entry = &sge_page->sge[i];
+
+@@ -1712,11 +1705,9 @@ static int prep_prd_sge_v2_hw(struct his
+ hdr->prd_table_addr = cpu_to_le64(hisi_sas_sge_addr_dma(slot));
+
+ hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF);
+-
+- return 0;
+ }
+
+-static int prep_smp_v2_hw(struct hisi_hba *hisi_hba,
++static void prep_smp_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+@@ -1753,11 +1744,9 @@ static int prep_smp_v2_hw(struct hisi_hb
+
+ hdr->cmd_table_addr = cpu_to_le64(req_dma_addr);
+ hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));
+-
+- return 0;
+ }
+
+-static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
++static void prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot, int is_tmf,
+ struct hisi_sas_tmf_task *tmf)
+ {
+@@ -1768,7 +1757,7 @@ static int prep_ssp_v2_hw(struct hisi_hb
+ struct hisi_sas_port *port = slot->port;
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+- int has_data = 0, rc, priority = is_tmf;
++ int has_data = 0, priority = is_tmf;
+ u8 *buf_cmd;
+ u32 dw1 = 0, dw2 = 0;
+
+@@ -1810,12 +1799,9 @@ static int prep_ssp_v2_hw(struct hisi_hb
+
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+- if (has_data) {
+- rc = prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,
++ if (has_data)
++ prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,
+ slot->n_elem);
+- if (rc)
+- return rc;
+- }
+
+ hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
+ hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));
+@@ -1844,8 +1830,6 @@ static int prep_ssp_v2_hw(struct hisi_hb
+ break;
+ }
+ }
+-
+- return 0;
+ }
+
+ #define TRANS_TX_ERR 0
+@@ -2520,7 +2504,7 @@ out:
+ return sts;
+ }
+
+-static int prep_ata_v2_hw(struct hisi_hba *hisi_hba,
++static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+@@ -2531,7 +2515,7 @@ static int prep_ata_v2_hw(struct hisi_hb
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
+ u8 *buf_cmd;
+- int has_data = 0, rc = 0, hdr_tag = 0;
++ int has_data = 0, hdr_tag = 0;
+ u32 dw1 = 0, dw2 = 0;
+
+ /* create header */
+@@ -2579,12 +2563,9 @@ static int prep_ata_v2_hw(struct hisi_hb
+ /* dw3 */
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+- if (has_data) {
+- rc = prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,
++ if (has_data)
++ prep_prd_sge_v2_hw(hisi_hba, slot, hdr, task->scatter,
+ slot->n_elem);
+- if (rc)
+- return rc;
+- }
+
+ hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
+ hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));
+@@ -2596,8 +2577,6 @@ static int prep_ata_v2_hw(struct hisi_hb
+ task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
+ /* fill in command FIS */
+ memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
+-
+- return 0;
+ }
+
+ static void hisi_sas_internal_abort_quirk_timeout(unsigned long data)
+@@ -2634,7 +2613,7 @@ static void hisi_sas_internal_abort_quir
+ }
+ }
+
+-static int prep_abort_v2_hw(struct hisi_hba *hisi_hba,
++static void prep_abort_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot,
+ int device_id, int abort_flag, int tag_to_abort)
+ {
+@@ -2663,8 +2642,6 @@ static int prep_abort_v2_hw(struct hisi_
+ /* dw7 */
+ hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF);
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+-
+- return 0;
+ }
+
+ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -859,23 +859,16 @@ static void start_delivery_v3_hw(struct
+ dq->wr_point);
+ }
+
+-static int prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba,
++static void prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot,
+ struct hisi_sas_cmd_hdr *hdr,
+ struct scatterlist *scatter,
+ int n_elem)
+ {
+ struct hisi_sas_sge_page *sge_page = hisi_sas_sge_addr_mem(slot);
+- struct device *dev = hisi_hba->dev;
+ struct scatterlist *sg;
+ int i;
+
+- if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
+- dev_err(dev, "prd err: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
+- n_elem);
+- return -EINVAL;
+- }
+-
+ for_each_sg(scatter, sg, n_elem, i) {
+ struct hisi_sas_sge *entry = &sge_page->sge[i];
+
+@@ -888,11 +881,9 @@ static int prep_prd_sge_v3_hw(struct his
+ hdr->prd_table_addr = cpu_to_le64(hisi_sas_sge_addr_dma(slot));
+
+ hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF);
+-
+- return 0;
+ }
+
+-static int prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
++static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot, int is_tmf,
+ struct hisi_sas_tmf_task *tmf)
+ {
+@@ -903,7 +894,7 @@ static int prep_ssp_v3_hw(struct hisi_hb
+ struct hisi_sas_port *port = slot->port;
+ struct sas_ssp_task *ssp_task = &task->ssp_task;
+ struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
+- int has_data = 0, rc, priority = is_tmf;
++ int has_data = 0, priority = is_tmf;
+ u8 *buf_cmd;
+ u32 dw1 = 0, dw2 = 0;
+
+@@ -944,12 +935,9 @@ static int prep_ssp_v3_hw(struct hisi_hb
+ hdr->dw2 = cpu_to_le32(dw2);
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+- if (has_data) {
+- rc = prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter,
++ if (has_data)
++ prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter,
+ slot->n_elem);
+- if (rc)
+- return rc;
+- }
+
+ hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
+ hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));
+@@ -976,11 +964,9 @@ static int prep_ssp_v3_hw(struct hisi_hb
+ break;
+ }
+ }
+-
+- return 0;
+ }
+
+-static int prep_smp_v3_hw(struct hisi_hba *hisi_hba,
++static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+@@ -1018,10 +1004,9 @@ static int prep_smp_v3_hw(struct hisi_hb
+ hdr->cmd_table_addr = cpu_to_le64(req_dma_addr);
+ hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));
+
+- return 0;
+ }
+
+-static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,
++static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot)
+ {
+ struct sas_task *task = slot->task;
+@@ -1032,7 +1017,7 @@ static int prep_ata_v3_hw(struct hisi_hb
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
+ u8 *buf_cmd;
+- int has_data = 0, rc = 0, hdr_tag = 0;
++ int has_data = 0, hdr_tag = 0;
+ u32 dw1 = 0, dw2 = 0;
+
+ hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF);
+@@ -1081,12 +1066,9 @@ static int prep_ata_v3_hw(struct hisi_hb
+ /* dw3 */
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+- if (has_data) {
+- rc = prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter,
++ if (has_data)
++ prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter,
+ slot->n_elem);
+- if (rc)
+- return rc;
+- }
+
+ hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
+ hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));
+@@ -1098,11 +1080,9 @@ static int prep_ata_v3_hw(struct hisi_hb
+ task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
+ /* fill in command FIS */
+ memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
+-
+- return 0;
+ }
+
+-static int prep_abort_v3_hw(struct hisi_hba *hisi_hba,
++static void prep_abort_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_slot *slot,
+ int device_id, int abort_flag, int tag_to_abort)
+ {
+@@ -1127,7 +1107,6 @@ static int prep_abort_v3_hw(struct hisi_
+ hdr->dw7 = cpu_to_le32(tag_to_abort << CMD_HDR_ABORT_IPTT_OFF);
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+- return 0;
+ }
+
+ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
diff --git a/patches.drivers/scsi-hisi_sas-make-sas-address-of-sata-disks-unique.patch b/patches.drivers/scsi-hisi_sas-make-sas-address-of-sata-disks-unique.patch
new file mode 100644
index 0000000000..ca57d65c9e
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-make-sas-address-of-sata-disks-unique.patch
@@ -0,0 +1,31 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 24 Mar 2018 00:05:08 +0800
+Subject: scsi: hisi_sas: make SAS address of SATA disks unique
+Git-commit: 8b8d66531555006a18d1532546dadbea8d16df95
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+When directly connected with SATA disks in different SAS cores, fill SAS
+address with scsi_host's id to make it's fake SAS address unique.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index f89fb9a49ea9..89b9505c0654 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3295,6 +3295,7 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p)
+ sas_phy->oob_mode = SATA_OOB_MODE;
+ /* Make up some unique SAS address */
+ attached_sas_addr[0] = 0x50;
++ attached_sas_addr[6] = hisi_hba->shost->host_no;
+ attached_sas_addr[7] = phy_no;
+ memcpy(sas_phy->attached_sas_addr, attached_sas_addr, SAS_ADDR_SIZE);
+ memcpy(sas_phy->frame_rcvd, fis, sizeof(struct dev_to_host_fis));
+
diff --git a/patches.drivers/scsi-hisi_sas-mark-phy-as-in-reset-for-nexus-reset.patch b/patches.drivers/scsi-hisi_sas-mark-phy-as-in-reset-for-nexus-reset.patch
new file mode 100644
index 0000000000..ac7847a3b5
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-mark-phy-as-in-reset-for-nexus-reset.patch
@@ -0,0 +1,202 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 21 May 2018 18:09:25 +0800
+Subject: scsi: hisi_sas: Mark PHY as in reset for nexus reset
+Git-commit: 3e1fb1b8abf0c862a7f5d39cb3354a1fd5e9f96a
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+When issuing a nexus reset for directly attached device, we want to ignore
+the PHY down events so libsas will not deform and reform the port.
+
+In the case that the attached SAS changes for the reset, libsas will deform
+and form a port.
+
+For scenario that the PHY does not come up after a timeout period, then
+report the PHY down to libsas.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 5 +++-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 40 +++++++++++++++++++++++++++++----
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 8 ++++++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 14 +++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 +++++
+ 5 files changed, 69 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -137,11 +137,14 @@ struct hisi_sas_phy {
+ struct asd_sas_phy sas_phy;
+ struct sas_identify identify;
+ struct timer_list timer;
++ struct completion *reset_completion;
++ spinlock_t lock;
+ u64 port_id; /* from hw */
+ u64 frame_rcvd_size;
+ u8 frame_rcvd[32];
+ u8 phy_attached;
+- u8 reserved[3];
++ u8 in_reset;
++ u8 reserved[2];
+ u32 phy_type;
+ enum sas_linkrate minimum_linkrate;
+ enum sas_linkrate maximum_linkrate;
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1530,12 +1530,39 @@ static int hisi_sas_clear_aca(struct dom
+
+ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
+ {
+- struct sas_phy *phy = sas_get_local_phy(device);
++ struct sas_phy *local_phy = sas_get_local_phy(device);
+ int rc, reset_type = (device->dev_type == SAS_SATA_DEV ||
+ (device->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
+- rc = sas_phy_reset(phy, reset_type);
+- sas_put_local_phy(phy);
+- msleep(2000);
++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
++ struct sas_ha_struct *sas_ha = &hisi_hba->sha;
++ struct asd_sas_phy *sas_phy = sas_ha->sas_phy[local_phy->number];
++ struct hisi_sas_phy *phy = container_of(sas_phy,
++ struct hisi_sas_phy, sas_phy);
++ DECLARE_COMPLETION_ONSTACK(phyreset);
++
++ if (scsi_is_sas_phy_local(local_phy)) {
++ phy->in_reset = 1;
++ phy->reset_completion = &phyreset;
++ }
++
++ rc = sas_phy_reset(local_phy, reset_type);
++ sas_put_local_phy(local_phy);
++
++ if (scsi_is_sas_phy_local(local_phy)) {
++ int ret = wait_for_completion_timeout(&phyreset, 2 * HZ);
++ unsigned long flags;
++
++ spin_lock_irqsave(&phy->lock, flags);
++ phy->reset_completion = NULL;
++ phy->in_reset = 0;
++ spin_unlock_irqrestore(&phy->lock, flags);
++
++ /* report PHY down if timed out */
++ if (!ret)
++ hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
++ } else
++ msleep(2000);
++
+ return rc;
+ }
+
+@@ -1885,6 +1912,7 @@ void hisi_sas_phy_down(struct hisi_hba *
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ struct sas_ha_struct *sas_ha = &hisi_hba->sha;
++ struct device *dev = hisi_hba->dev;
+
+ if (rdy) {
+ /* Phy down but ready */
+@@ -1893,6 +1921,10 @@ void hisi_sas_phy_down(struct hisi_hba *
+ } else {
+ struct hisi_sas_port *port = phy->port;
+
++ if (phy->in_reset) {
++ dev_info(dev, "ignore flutter phy%d down\n", phy_no);
++ return;
++ }
+ /* Phy down and not ready */
+ sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL);
+ sas_phy_disconnected(sas_phy);
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1373,6 +1373,7 @@ static irqreturn_t int_phyup_v1_hw(int i
+ u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd;
+ struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd;
+ irqreturn_t res = IRQ_HANDLED;
++ unsigned long flags;
+
+ irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2);
+ if (!(irq_value & CHL_INT2_SL_PHY_ENA_MSK)) {
+@@ -1426,6 +1427,13 @@ static irqreturn_t int_phyup_v1_hw(int i
+ SAS_PROTOCOL_SMP;
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+
++ spin_lock_irqsave(&phy->lock, flags);
++ if (phy->reset_completion) {
++ phy->in_reset = 0;
++ complete(phy->reset_completion);
++ }
++ spin_unlock_irqrestore(&phy->lock, flags);
++
+ end:
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
+ CHL_INT2_SL_PHY_ENA_MSK);
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2663,6 +2663,7 @@ static int phy_up_v2_hw(int phy_no, stru
+ struct device *dev = hisi_hba->dev;
+ u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd;
+ struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd;
++ unsigned long flags;
+
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
+
+@@ -2715,6 +2716,12 @@ static int phy_up_v2_hw(int phy_no, stru
+ set_link_timer_quirk(hisi_hba);
+ }
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
++ spin_lock_irqsave(&phy->lock, flags);
++ if (phy->reset_completion) {
++ phy->in_reset = 0;
++ complete(phy->reset_completion);
++ }
++ spin_unlock_irqrestore(&phy->lock, flags);
+
+ end:
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+@@ -3203,6 +3210,7 @@ static irqreturn_t sata_int_v2_hw(int ir
+ u32 ent_tmp, ent_msk, ent_int, port_id, link_rate, hard_phy_linkrate;
+ irqreturn_t res = IRQ_HANDLED;
+ u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};
++ unsigned long flags;
+ int phy_no, offset;
+
+ phy_no = sas_phy->id;
+@@ -3277,6 +3285,12 @@ static irqreturn_t sata_int_v2_hw(int ir
+ phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+
++ spin_lock_irqsave(&phy->lock, flags);
++ if (phy->reset_completion) {
++ phy->in_reset = 0;
++ complete(phy->reset_completion);
++ }
++ spin_unlock_irqrestore(&phy->lock, flags);
+ end:
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC1 + offset, ent_tmp);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset, ent_msk);
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1143,6 +1143,7 @@ static irqreturn_t phy_up_v3_hw(int phy_
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ struct device *dev = hisi_hba->dev;
++ unsigned long flags;
+
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
+
+@@ -1211,6 +1212,12 @@ static irqreturn_t phy_up_v3_hw(int phy_
+ phy->phy_attached = 1;
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+ res = IRQ_HANDLED;
++ spin_lock_irqsave(&phy->lock, flags);
++ if (phy->reset_completion) {
++ phy->in_reset = 0;
++ complete(phy->reset_completion);
++ }
++ spin_unlock_irqrestore(&phy->lock, flags);
+ end:
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+ CHL_INT0_SL_PHY_ENABLE_MSK);
diff --git a/patches.drivers/scsi-hisi_sas-modify-hisi_sas_dev_gone-for-reset.patch b/patches.drivers/scsi-hisi_sas-modify-hisi_sas_dev_gone-for-reset.patch
new file mode 100644
index 0000000000..e0ab457915
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-modify-hisi_sas_dev_gone-for-reset.patch
@@ -0,0 +1,54 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:37 +0800
+Subject: scsi: hisi_sas: modify hisi_sas_dev_gone() for reset
+Git-commit: f8e45ec226e2c00c1da9cf156ea59a159e9b4ea6
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Do a couple of changes for when HISI_SAS_RESET_BIT is set for HBA:
+
+ - Clearing ITCT is not necessary
+
+ - Remove internal abort as it will fail during reset
+
+Flag sas_dev->dev_type is kept as SAS_PHY_UNUSED.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 64d51a839187..e4b30922a75d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -738,17 +738,19 @@ static void hisi_sas_dev_gone(struct domain_device *device)
+ dev_info(dev, "found dev[%d:%x] is gone\n",
+ sas_dev->device_id, sas_dev->dev_type);
+
+- hisi_sas_internal_task_abort(hisi_hba, device,
++ if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) {
++ hisi_sas_internal_task_abort(hisi_hba, device,
+ HISI_SAS_INT_ABT_DEV, 0);
+
+- hisi_sas_dereg_device(hisi_hba, device);
++ hisi_sas_dereg_device(hisi_hba, device);
++
++ hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
++ device->lldd_dev = NULL;
++ memset(sas_dev, 0, sizeof(*sas_dev));
++ }
+
+- hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
+ if (hisi_hba->hw->free_device)
+ hisi_hba->hw->free_device(sas_dev);
+-
+- device->lldd_dev = NULL;
+- memset(sas_dev, 0, sizeof(*sas_dev));
+ sas_dev->dev_type = SAS_PHY_UNUSED;
+ }
+
+
diff --git a/patches.drivers/scsi-hisi_sas-modify-some-register-config-for-hip08.patch b/patches.drivers/scsi-hisi_sas-modify-some-register-config-for-hip08.patch
new file mode 100644
index 0000000000..cf29b4ecd9
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-modify-some-register-config-for-hip08.patch
@@ -0,0 +1,81 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 7 Mar 2018 20:25:13 +0800
+Subject: scsi: hisi_sas: modify some register config for hip08
+Git-commit: 15c38e31c47c0f2cd7e959054258714991a6a2d6
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+Do some modifications for register configuring for hip08.
+
+In future, to reduce kernel churn with patches to modify registers, any
+registers which may change between board models (mostly PHY/SERDES related)
+should be set in ACPI reset handler.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 4023fcbc3f04..5ce5ef2caabe 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -172,6 +172,7 @@
+ #define CHL_INT1_MSK (PORT_BASE + 0x1c4)
+ #define CHL_INT2_MSK (PORT_BASE + 0x1c8)
+ #define CHL_INT_COAL_EN (PORT_BASE + 0x1d0)
++#define SAS_RX_TRAIN_TIMER (PORT_BASE + 0x2a4)
+ #define PHY_CTRL_RDY_MSK (PORT_BASE + 0x2b0)
+ #define PHYCTRL_NOT_RDY_MSK (PORT_BASE + 0x2b4)
+ #define PHYCTRL_DWS_RESET_MSK (PORT_BASE + 0x2b8)
+@@ -184,6 +185,8 @@
+ #define DMA_RX_STATUS (PORT_BASE + 0x2e8)
+ #define DMA_RX_STATUS_BUSY_OFF 0
+ #define DMA_RX_STATUS_BUSY_MSK (0x1 << DMA_RX_STATUS_BUSY_OFF)
++
++#define COARSETUNE_TIME (PORT_BASE + 0x304)
+ #define ERR_CNT_DWS_LOST (PORT_BASE + 0x380)
+ #define ERR_CNT_RESET_PROB (PORT_BASE + 0x384)
+ #define ERR_CNT_INVLD_DW (PORT_BASE + 0x390)
+@@ -417,10 +420,10 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0);
+
+ hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);
+- hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE, 0x30000);
+
+ for (i = 0; i < hisi_hba->n_phy; i++) {
+- hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x801);
++ hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855);
++ hisi_sas_phy_write32(hisi_hba, i, SAS_RX_TRAIN_TIMER, 0x13e80);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
+@@ -432,17 +435,13 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
+ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0);
+ hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0);
+- hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x0);
+- hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, 0x199b4fa);
+- hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG,
+- 0xa03e8);
+- hisi_sas_phy_write32(hisi_hba, i, SAS_STP_CON_TIMER_CFG,
+- 0xa03e8);
+- hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER,
+- 0x7f7a120);
+- hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER,
+- 0x2a0a80);
++ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1);
++ hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120);
++
++ /* used for 12G negotiate */
++ hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e);
+ }
++
+ for (i = 0; i < hisi_hba->queue_count; i++) {
+ /* Delivery queue */
+ hisi_sas_write32(hisi_hba,
+
diff --git a/patches.drivers/scsi-hisi_sas-optimise-port-id-refresh-function.patch b/patches.drivers/scsi-hisi_sas-optimise-port-id-refresh-function.patch
new file mode 100644
index 0000000000..d9bf86b49b
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-optimise-port-id-refresh-function.patch
@@ -0,0 +1,115 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:35 +0800
+Subject: scsi: hisi_sas: optimise port id refresh function
+Git-commit: a669bdbf4939ac72eff6b3ae33f771a1ef28448c
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Currently refreshing the PHY port id after reset is done in the rescan
+topology function, which is quite late in the reset process. It could be moved
+earlier in the process, as the port id can be refreshed once the PHYs become
+ready.
+
+In addition to this, we should set the hisi_sas_dev port id to 0xff (invalid
+port id) if all PHYs of this port remain down for the same device.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 48 ++++++++++++++++++++++-------------
+ 1 file changed, 30 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 6446ce23465a..326ecb24bb20 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -990,27 +990,42 @@ static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device,
+ sizeof(ssp_task), tmf);
+ }
+
+-static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba,
+- struct asd_sas_port *sas_port, enum sas_linkrate linkrate)
++static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)
+ {
+- struct hisi_sas_device *sas_dev;
+- struct domain_device *device;
++ u32 state = hisi_hba->hw->get_phys_state(hisi_hba);
+ int i;
+
+ for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
+- sas_dev = &hisi_hba->devices[i];
+- device = sas_dev->sas_device;
++ struct hisi_sas_device *sas_dev = &hisi_hba->devices[i];
++ struct domain_device *device = sas_dev->sas_device;
++ struct asd_sas_port *sas_port;
++ struct hisi_sas_port *port;
++ struct hisi_sas_phy *phy = NULL;
++ struct asd_sas_phy *sas_phy;
++
+ if ((sas_dev->dev_type == SAS_PHY_UNUSED)
+- || !device || (device->port != sas_port))
++ || !device || !device->port)
+ continue;
+
+- hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
++ sas_port = device->port;
++ port = to_hisi_sas_port(sas_port);
++
++ list_for_each_entry(sas_phy, &sas_port->phy_list, port_phy_el)
++ if (state & BIT(sas_phy->id)) {
++ phy = sas_phy->lldd_phy;
++ break;
++ }
++
++ if (phy) {
++ port->id = phy->port_id;
+
+- /* Update linkrate of directly attached device. */
+- if (!device->parent)
+- device->linkrate = linkrate;
++ /* Update linkrate of directly attached device. */
++ if (!device->parent)
++ device->linkrate = phy->sas_phy.linkrate;
+
+- hisi_hba->hw->setup_itct(hisi_hba, sas_dev);
++ hisi_hba->hw->setup_itct(hisi_hba, sas_dev);
++ } else
++ port->id = 0xff;
+ }
+ }
+
+@@ -1025,21 +1040,17 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state,
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ struct asd_sas_port *sas_port = sas_phy->port;
+- struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
+ bool do_port_check = !!(_sas_port != sas_port);
+
+ if (!sas_phy->phy->enabled)
+ continue;
+
+ /* Report PHY state change to libsas */
+- if (state & (1 << phy_no)) {
+- if (do_port_check && sas_port) {
++ if (state & BIT(phy_no)) {
++ if (do_port_check && sas_port && sas_port->port_dev) {
+ struct domain_device *dev = sas_port->port_dev;
+
+ _sas_port = sas_port;
+- port->id = phy->port_id;
+- hisi_sas_refresh_port_id(hisi_hba,
+- sas_port, sas_phy->linkrate);
+
+ if (DEV_IS_EXPANDER(dev->dev_type))
+ sas_ha->notify_port_event(sas_phy,
+@@ -1088,6 +1099,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ /* Init and wait for PHYs to come up and all libsas event finished. */
+ hisi_hba->hw->phys_init(hisi_hba);
+ msleep(1000);
++ hisi_sas_refresh_port_id(hisi_hba);
+ drain_workqueue(hisi_hba->wq);
+ drain_workqueue(shost->work_q);
+
+
diff --git a/patches.drivers/scsi-hisi_sas-optimise-the-usage-of-dq-locking.patch b/patches.drivers/scsi-hisi_sas-optimise-the-usage-of-dq-locking.patch
new file mode 100644
index 0000000000..b73a8c21c6
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-optimise-the-usage-of-dq-locking.patch
@@ -0,0 +1,78 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 2 May 2018 23:56:24 +0800
+Subject: scsi: hisi_sas: optimise the usage of DQ locking
+Git-commit: 24cf43612d4d851e660ac85f36cf389650c5a3ba
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+In the DQ tasklet processing it is not necessary to take the DQ lock, as
+there is no contention between adding slots to the CQ and removing slots
+from the matching DQ.
+
+In addition, since we run each DQ in a separate tasklet context, there
+would be no possible contention between DQ processing running for the
+same queue in parallel.
+
+It is still necessary to take hisi_hba lock when free'ing slots.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 3 ---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 ---
+ 2 files changed, 6 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index a5abde855cb2..384e4ef50b24 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3151,14 +3151,12 @@ static void cq_tasklet_v2_hw(unsigned long val)
+ struct hisi_sas_complete_v2_hdr *complete_queue;
+ u32 rd_point = cq->rd_point, wr_point, dev_id;
+ int queue = cq->id;
+- struct hisi_sas_dq *dq = &hisi_hba->dq[queue];
+
+ if (unlikely(hisi_hba->reject_stp_links_msk))
+ phys_try_accept_stp_links_v2_hw(hisi_hba);
+
+ complete_queue = hisi_hba->complete_hdr[queue];
+
+- spin_lock(&dq->lock);
+ wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR +
+ (0x14 * queue));
+
+@@ -3208,7 +3206,6 @@ static void cq_tasklet_v2_hw(unsigned long val)
+ /* update rd_point */
+ cq->rd_point = rd_point;
+ hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point);
+- spin_unlock(&dq->lock);
+ }
+
+ static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 33735a7082b6..afc1242abdcf 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1721,11 +1721,9 @@ static void cq_tasklet_v3_hw(unsigned long val)
+ struct hisi_sas_complete_v3_hdr *complete_queue;
+ u32 rd_point = cq->rd_point, wr_point;
+ int queue = cq->id;
+- struct hisi_sas_dq *dq = &hisi_hba->dq[queue];
+
+ complete_queue = hisi_hba->complete_hdr[queue];
+
+- spin_lock(&dq->lock);
+ wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR +
+ (0x14 * queue));
+
+@@ -1752,7 +1750,6 @@ static void cq_tasklet_v3_hw(unsigned long val)
+ /* update rd_point */
+ cq->rd_point = rd_point;
+ hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point);
+- spin_unlock(&dq->lock);
+ }
+
+ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p)
+
diff --git a/patches.drivers/scsi-hisi_sas-print-device-id-for-errors.patch b/patches.drivers/scsi-hisi_sas-print-device-id-for-errors.patch
new file mode 100644
index 0000000000..495b1e371d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-print-device-id-for-errors.patch
@@ -0,0 +1,54 @@
+From: John Garry <john.garry@huawei.com>
+Date: Sat, 24 Mar 2018 00:05:14 +0800
+Subject: scsi: hisi_sas: print device id for errors
+Git-commit: 381ed6c081ae423b03d82ce1a0bb79bbec2b033e
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+When we find an erroneous slot completion, to help aid debugging add the
+device index to the current debug log.
+
+Signed-off-by: John Garry <john.garry@huawei.com>
+Reviewed-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 ++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index bed6afb324a1..a5abde855cb2 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2459,10 +2459,10 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+ slot_err_v2_hw(hisi_hba, task, slot, 2);
+
+ if (ts->stat != SAS_DATA_UNDERRUN)
+- dev_info(dev, "erroneous completion iptt=%d task=%p "
++ dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d "
+ "CQ hdr: 0x%x 0x%x 0x%x 0x%x "
+ "Error info: 0x%x 0x%x 0x%x 0x%x\n",
+- slot->idx, task,
++ slot->idx, task, sas_dev->device_id,
+ complete_hdr->dw0, complete_hdr->dw1,
+ complete_hdr->act, complete_hdr->dw3,
+ error_info[0], error_info[1],
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index aa52d5e424f7..760724ae4d6f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1641,10 +1641,10 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
+
+ slot_err_v3_hw(hisi_hba, task, slot);
+ if (ts->stat != SAS_DATA_UNDERRUN)
+- dev_info(dev, "erroneous completion iptt=%d task=%p "
++ dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d "
+ "CQ hdr: 0x%x 0x%x 0x%x 0x%x "
+ "Error info: 0x%x 0x%x 0x%x 0x%x\n",
+- slot->idx, task,
++ slot->idx, task, sas_dev->device_id,
+ complete_hdr->dw0, complete_hdr->dw1,
+ complete_hdr->act, complete_hdr->dw3,
+ error_info[0], error_info[1],
+
diff --git a/patches.drivers/scsi-hisi_sas-re-add-the-lldd_port_deformed.patch b/patches.drivers/scsi-hisi_sas-re-add-the-lldd_port_deformed.patch
new file mode 100644
index 0000000000..278b616826
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-re-add-the-lldd_port_deformed.patch
@@ -0,0 +1,47 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 9 Dec 2017 01:16:49 +0800
+Subject: scsi: hisi_sas: re-add the lldd_port_deformed()
+Git-commit: 336bd78bdabf39dbcee6b41f9628c6e51d1c25b0
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+In function sas_suspend_devices(), it requires callback lldd_port_deformed
+callback to be implemented if lldd_port_deformed is implemented.
+
+So add a stub for lldd_port_deformed.
+
+Callback lldd_port_deformed was not required as the port deformation is done
+elsewhere in the LLDD.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 9bd98e5be78e..ad122378b84a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1613,6 +1613,10 @@ static void hisi_sas_port_formed(struct asd_sas_phy *sas_phy)
+ hisi_sas_port_notify_formed(sas_phy);
+ }
+
++static void hisi_sas_port_deformed(struct asd_sas_phy *sas_phy)
++{
++}
++
+ static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy)
+ {
+ phy->phy_attached = 0;
+@@ -1703,6 +1707,7 @@ static struct sas_domain_function_template hisi_sas_transport_ops = {
+ .lldd_query_task = hisi_sas_query_task,
+ .lldd_clear_nexus_ha = hisi_sas_clear_nexus_ha,
+ .lldd_port_formed = hisi_sas_port_formed,
++ .lldd_port_deformed = hisi_sas_port_deformed,
+ };
+
+ void hisi_sas_init_mem(struct hisi_hba *hisi_hba)
+
diff --git a/patches.drivers/scsi-hisi_sas-relocate-clearing-itct-and-freeing-device.patch b/patches.drivers/scsi-hisi_sas-relocate-clearing-itct-and-freeing-device.patch
new file mode 100644
index 0000000000..55af7f9f1a
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-relocate-clearing-itct-and-freeing-device.patch
@@ -0,0 +1,161 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:34 +0800
+Subject: scsi: hisi_sas: relocate clearing ITCT and freeing device
+Git-commit: 0258141aaab3007949ba0e67c3d28436354429bb
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+In certain scenarios we may just want to clear the ITCT for a device, and not
+free other resources like the SATA bitmap using in v2 hw.
+
+To facilitate this, this patch relocates the code of clearing ITCT from
+free_device() to a new hw interface clear_itct(). Then for some hw, we should
+not realise free_device() if there's nothing left to do for it.
+
+[mkp: typo]
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 3 ++-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++--
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 ++--
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 16 +++++++++++-----
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 ++--
+ 5 files changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 83357b0367d8..b2534caed45a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -205,8 +205,9 @@ struct hisi_sas_hw {
+ void (*phy_set_linkrate)(struct hisi_hba *hisi_hba, int phy_no,
+ struct sas_phy_linkrates *linkrates);
+ enum sas_linkrate (*phy_get_max_linkrate)(void);
+- void (*free_device)(struct hisi_hba *hisi_hba,
++ void (*clear_itct)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *dev);
++ void (*free_device)(struct hisi_sas_device *sas_dev);
+ int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id);
+ void (*dereg_device)(struct hisi_hba *hisi_hba,
+ struct domain_device *device);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index d8425303eadd..6446ce23465a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -743,7 +743,10 @@ static void hisi_sas_dev_gone(struct domain_device *device)
+
+ hisi_sas_dereg_device(hisi_hba, device);
+
+- hisi_hba->hw->free_device(hisi_hba, sas_dev);
++ hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
++ if (hisi_hba->hw->free_device)
++ hisi_hba->hw->free_device(sas_dev);
++
+ device->lldd_dev = NULL;
+ memset(sas_dev, 0, sizeof(*sas_dev));
+ sas_dev->dev_type = SAS_PHY_UNUSED;
+@@ -1001,7 +1004,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba,
+ || !device || (device->port != sas_port))
+ continue;
+
+- hisi_hba->hw->free_device(hisi_hba, sas_dev);
++ hisi_hba->hw->clear_itct(hisi_hba, sas_dev);
+
+ /* Update linkrate of directly attached device. */
+ if (!device->parent)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index dc6eca8d6afd..8cb9061e616f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -544,7 +544,7 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba,
+ (0xff00ULL << ITCT_HDR_REJ_OPEN_TL_OFF));
+ }
+
+-static void free_device_v1_hw(struct hisi_hba *hisi_hba,
++static void clear_itct_v1_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *sas_dev)
+ {
+ u64 dev_id = sas_dev->device_id;
+@@ -1850,7 +1850,7 @@ static const struct hisi_sas_hw hisi_sas_v1_hw = {
+ .hw_init = hisi_sas_v1_init,
+ .setup_itct = setup_itct_v1_hw,
+ .sl_notify = sl_notify_v1_hw,
+- .free_device = free_device_v1_hw,
++ .clear_itct = clear_itct_v1_hw,
+ .prep_smp = prep_smp_v1_hw,
+ .prep_ssp = prep_ssp_v1_hw,
+ .get_free_slot = get_free_slot_v1_hw,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 5d3467fd728d..cd9cd8468829 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -952,7 +952,7 @@ static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,
+ (0x1ULL << ITCT_HDR_RTOLT_OFF));
+ }
+
+-static void free_device_v2_hw(struct hisi_hba *hisi_hba,
++static void clear_itct_v2_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *sas_dev)
+ {
+ DECLARE_COMPLETION_ONSTACK(completion);
+@@ -963,10 +963,6 @@ static void free_device_v2_hw(struct hisi_hba *hisi_hba,
+
+ sas_dev->completion = &completion;
+
+- /* SoC bug workaround */
+- if (dev_is_sata(sas_dev->sas_device))
+- clear_bit(sas_dev->sata_idx, hisi_hba->sata_dev_bitmap);
+-
+ /* clear the itct interrupt state */
+ if (ENT_INT_SRC3_ITC_INT_MSK & reg_val)
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
+@@ -981,6 +977,15 @@ static void free_device_v2_hw(struct hisi_hba *hisi_hba,
+ }
+ }
+
++static void free_device_v2_hw(struct hisi_sas_device *sas_dev)
++{
++ struct hisi_hba *hisi_hba = sas_dev->hisi_hba;
++
++ /* SoC bug workaround */
++ if (dev_is_sata(sas_dev->sas_device))
++ clear_bit(sas_dev->sata_idx, hisi_hba->sata_dev_bitmap);
++}
++
+ static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
+ {
+ int i, reset_val;
+@@ -3415,6 +3420,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
+ .alloc_dev = alloc_dev_quirk_v2_hw,
+ .sl_notify = sl_notify_v2_hw,
+ .get_wideport_bitmap = get_wideport_bitmap_v2_hw,
++ .clear_itct = clear_itct_v2_hw,
+ .free_device = free_device_v2_hw,
+ .prep_smp = prep_smp_v2_hw,
+ .prep_ssp = prep_ssp_v2_hw,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 19b1f2ffec17..44f07bc37177 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -588,7 +588,7 @@ static void setup_itct_v3_hw(struct hisi_hba *hisi_hba,
+ (0x1ULL << ITCT_HDR_RTOLT_OFF));
+ }
+
+-static void free_device_v3_hw(struct hisi_hba *hisi_hba,
++static void clear_itct_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *sas_dev)
+ {
+ DECLARE_COMPLETION_ONSTACK(completion);
+@@ -1951,7 +1951,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
+ .max_command_entries = HISI_SAS_COMMAND_ENTRIES_V3_HW,
+ .get_wideport_bitmap = get_wideport_bitmap_v3_hw,
+ .complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr),
+- .free_device = free_device_v3_hw,
++ .clear_itct = clear_itct_v3_hw,
+ .sl_notify = sl_notify_v3_hw,
+ .prep_ssp = prep_ssp_v3_hw,
+ .prep_smp = prep_smp_v3_hw,
+
diff --git a/patches.drivers/scsi-hisi_sas-relocate-smp-sg-map.patch b/patches.drivers/scsi-hisi_sas-relocate-smp-sg-map.patch
new file mode 100644
index 0000000000..c36ba0a924
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-relocate-smp-sg-map.patch
@@ -0,0 +1,309 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 9 May 2018 23:10:45 +0800
+Subject: scsi: hisi_sas: relocate smp sg map
+Git-commit: 7eee4b921822addfb67c2ced5772f003bb083520
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Currently we use DQ lock to protect delivery of DQ entry one by one.
+
+To optimise to allow more than one slot to be built for a single DQ in
+parallel, we need to remove the DQ lock when preparing slots, prior to
+delivery.
+
+To achieve this, we rearrange the slot build order to ensure that once
+we allocate a slot for a task, we do cannot fail to deliver the task.
+
+In this patch, we rearrange the slot building for SMP tasks to ensure
+that sg mapping part (which can fail) happens before we allocate the
+slot in the DQ.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 56 ++++++++++++++++++++++++++--------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 33 ++------------------
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 35 ++-------------------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 33 ++------------------
+ 4 files changed, 51 insertions(+), 106 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index ff5b8d7de1d1..0ce7c717b201 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -319,7 +319,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ struct hisi_sas_cmd_hdr *cmd_hdr_base;
+ struct asd_sas_port *sas_port = device->port;
+ struct device *dev = hisi_hba->dev;
+- int dlvry_queue_slot, dlvry_queue, n_elem = 0, rc, slot_idx;
++ int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
++ int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
+ unsigned long flags;
+
+ if (!sas_port) {
+@@ -358,6 +359,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ }
+
+ if (!sas_protocol_ata(task->task_proto)) {
++ unsigned int req_len, resp_len;
++
+ if (task->num_scatter) {
+ n_elem = dma_map_sg(dev, task->scatter,
+ task->num_scatter, task->data_dir);
+@@ -365,6 +368,29 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ rc = -ENOMEM;
+ goto prep_out;
+ }
++ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
++ n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
++ 1, DMA_TO_DEVICE);
++ if (!n_elem_req) {
++ rc = -ENOMEM;
++ goto prep_out;
++ }
++ req_len = sg_dma_len(&task->smp_task.smp_req);
++ if (req_len & 0x3) {
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++ n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
++ 1, DMA_FROM_DEVICE);
++ if (!n_elem_req) {
++ rc = -ENOMEM;
++ goto err_out_dma_unmap;
++ }
++ resp_len = sg_dma_len(&task->smp_task.smp_resp);
++ if (resp_len & 0x3) {
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
+ }
+ } else
+ n_elem = task->num_scatter;
+@@ -375,11 +401,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ device);
+ else
+ rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
+- if (rc) {
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- goto err_out;
+- }
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ if (rc)
++ goto err_out_dma_unmap;
+
+ rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
+ if (rc)
+@@ -458,14 +482,22 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+-err_out:
+- dev_err(dev, "task prep: failed[%d]!\n", rc);
+- if (!sas_protocol_ata(task->task_proto))
+- if (n_elem)
+- dma_unmap_sg(dev, task->scatter,
+- task->num_scatter,
+- task->data_dir);
++err_out_dma_unmap:
++ if (!sas_protocol_ata(task->task_proto)) {
++ if (task->num_scatter) {
++ dma_unmap_sg(dev, task->scatter, task->num_scatter,
++ task->data_dir);
++ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
++ if (n_elem_req)
++ dma_unmap_sg(dev, &task->smp_task.smp_req,
++ 1, DMA_TO_DEVICE);
++ if (n_elem_resp)
++ dma_unmap_sg(dev, &task->smp_task.smp_resp,
++ 1, DMA_FROM_DEVICE);
++ }
++ }
+ prep_out:
++ dev_err(dev, "task prep: failed[%d]!\n", rc);
+ return rc;
+ }
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 84a0ccc4daf5..3769d70c9861 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -974,38 +974,17 @@ static int prep_smp_v1_hw(struct hisi_hba *hisi_hba,
+ struct sas_task *task = slot->task;
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+ struct domain_device *device = task->dev;
+- struct device *dev = hisi_hba->dev;
+ struct hisi_sas_port *port = slot->port;
+- struct scatterlist *sg_req, *sg_resp;
++ struct scatterlist *sg_req;
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ dma_addr_t req_dma_addr;
+- unsigned int req_len, resp_len;
+- int elem, rc;
++ unsigned int req_len;
+
+- /*
+- * DMA-map SMP request, response buffers
+- */
+ /* req */
+ sg_req = &task->smp_task.smp_req;
+- elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE);
+- if (!elem)
+- return -ENOMEM;
+ req_len = sg_dma_len(sg_req);
+ req_dma_addr = sg_dma_address(sg_req);
+
+- /* resp */
+- sg_resp = &task->smp_task.smp_resp;
+- elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE);
+- if (!elem) {
+- rc = -ENOMEM;
+- goto err_out_req;
+- }
+- resp_len = sg_dma_len(sg_resp);
+- if ((req_len & 0x3) || (resp_len & 0x3)) {
+- rc = -EINVAL;
+- goto err_out_resp;
+- }
+-
+ /* create header */
+ /* dw0 */
+ hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) |
+@@ -1027,14 +1006,6 @@ static int prep_smp_v1_hw(struct hisi_hba *hisi_hba,
+ hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));
+
+ return 0;
+-
+-err_out_resp:
+- dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1,
+- DMA_FROM_DEVICE);
+-err_out_req:
+- dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1,
+- DMA_TO_DEVICE);
+- return rc;
+ }
+
+ static int prep_ssp_v1_hw(struct hisi_hba *hisi_hba,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 9e687319b8bc..ac0a0b2c72c5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1721,37 +1721,16 @@ static int prep_smp_v2_hw(struct hisi_hba *hisi_hba,
+ struct sas_task *task = slot->task;
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+ struct domain_device *device = task->dev;
+- struct device *dev = hisi_hba->dev;
+ struct hisi_sas_port *port = slot->port;
+- struct scatterlist *sg_req, *sg_resp;
++ struct scatterlist *sg_req;
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ dma_addr_t req_dma_addr;
+- unsigned int req_len, resp_len;
+- int elem, rc;
++ unsigned int req_len;
+
+- /*
+- * DMA-map SMP request, response buffers
+- */
+ /* req */
+ sg_req = &task->smp_task.smp_req;
+- elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE);
+- if (!elem)
+- return -ENOMEM;
+- req_len = sg_dma_len(sg_req);
+ req_dma_addr = sg_dma_address(sg_req);
+-
+- /* resp */
+- sg_resp = &task->smp_task.smp_resp;
+- elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE);
+- if (!elem) {
+- rc = -ENOMEM;
+- goto err_out_req;
+- }
+- resp_len = sg_dma_len(sg_resp);
+- if ((req_len & 0x3) || (resp_len & 0x3)) {
+- rc = -EINVAL;
+- goto err_out_resp;
+- }
++ req_len = sg_dma_len(&task->smp_task.smp_req);
+
+ /* create header */
+ /* dw0 */
+@@ -1775,14 +1754,6 @@ static int prep_smp_v2_hw(struct hisi_hba *hisi_hba,
+ hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));
+
+ return 0;
+-
+-err_out_resp:
+- dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1,
+- DMA_FROM_DEVICE);
+-err_out_req:
+- dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1,
+- DMA_TO_DEVICE);
+- return rc;
+ }
+
+ static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 492c3beea3d5..cea5354c184f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -986,38 +986,17 @@ static int prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ struct sas_task *task = slot->task;
+ struct hisi_sas_cmd_hdr *hdr = slot->cmd_hdr;
+ struct domain_device *device = task->dev;
+- struct device *dev = hisi_hba->dev;
+ struct hisi_sas_port *port = slot->port;
+- struct scatterlist *sg_req, *sg_resp;
++ struct scatterlist *sg_req;
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ dma_addr_t req_dma_addr;
+- unsigned int req_len, resp_len;
+- int elem, rc;
++ unsigned int req_len;
+
+- /*
+- * DMA-map SMP request, response buffers
+- */
+ /* req */
+ sg_req = &task->smp_task.smp_req;
+- elem = dma_map_sg(dev, sg_req, 1, DMA_TO_DEVICE);
+- if (!elem)
+- return -ENOMEM;
+ req_len = sg_dma_len(sg_req);
+ req_dma_addr = sg_dma_address(sg_req);
+
+- /* resp */
+- sg_resp = &task->smp_task.smp_resp;
+- elem = dma_map_sg(dev, sg_resp, 1, DMA_FROM_DEVICE);
+- if (!elem) {
+- rc = -ENOMEM;
+- goto err_out_req;
+- }
+- resp_len = sg_dma_len(sg_resp);
+- if ((req_len & 0x3) || (resp_len & 0x3)) {
+- rc = -EINVAL;
+- goto err_out_resp;
+- }
+-
+ /* create header */
+ /* dw0 */
+ hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) |
+@@ -1040,14 +1019,6 @@ static int prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));
+
+ return 0;
+-
+-err_out_resp:
+- dma_unmap_sg(dev, &slot->task->smp_task.smp_resp, 1,
+- DMA_FROM_DEVICE);
+-err_out_req:
+- dma_unmap_sg(dev, &slot->task->smp_task.smp_req, 1,
+- DMA_TO_DEVICE);
+- return rc;
+ }
+
+ static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+
diff --git a/patches.drivers/scsi-hisi_sas-remove-depends-on-has_dma-in-case-of-platform-dependency.patch b/patches.drivers/scsi-hisi_sas-remove-depends-on-has_dma-in-case-of-platform-dependency.patch
new file mode 100644
index 0000000000..28d4992b75
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-remove-depends-on-has_dma-in-case-of-platform-dependency.patch
@@ -0,0 +1,42 @@
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+Date: Fri, 16 Mar 2018 14:51:50 +0100
+Subject: scsi: hisi_sas: Remove depends on HAS_DMA in case of platform
+ dependency
+Git-commit: 3565a3d01e14c33d29512ca8129365cbe38df809
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+Remove dependencies on HAS_DMA where a Kconfig symbol depends on another
+symbol that implies HAS_DMA, and, optionally, on "|| COMPILE_TEST". In
+most cases this other symbol is an architecture or platform specific
+symbol, or PCI.
+
+Generic symbols and drivers without platform dependencies keep their
+dependencies on HAS_DMA, to prevent compiling subsystems or drivers that
+cannot work anyway.
+
+This simplifies the dependencies, and allows to improve compile-testing.
+
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Acked-by: Robin Murphy <robin.murphy@arm.com>
+Acked-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig
+index d42f29a5eb65..57183fce70fb 100644
+--- a/drivers/scsi/hisi_sas/Kconfig
++++ b/drivers/scsi/hisi_sas/Kconfig
+@@ -1,6 +1,6 @@
+ config SCSI_HISI_SAS
+ tristate "HiSilicon SAS"
+- depends on HAS_DMA && HAS_IOMEM
++ depends on HAS_IOMEM
+ depends on ARM64 || COMPILE_TEST
+ select SCSI_SAS_LIBSAS
+ select BLK_DEV_INTEGRITY
+
diff --git a/patches.drivers/scsi-hisi_sas-remove-redundant-handling-to-event95-for-v3.patch b/patches.drivers/scsi-hisi_sas-remove-redundant-handling-to-event95-for-v3.patch
new file mode 100644
index 0000000000..a2c3d42b0a
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-remove-redundant-handling-to-event95-for-v3.patch
@@ -0,0 +1,49 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 2 May 2018 23:56:32 +0800
+Subject: scsi: hisi_sas: remove redundant handling to event95 for v3
+Git-commit: bf081d5da4fa3a0d0ef640868de1b9f644f633e0
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+Event95 is used for DFX purpose. The relevant bit for this interrupt in
+the ENT_INT_SRC_MSK3 register has been disabled, so remove the
+processing.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 026faeee5ead..d6e705ff9dad 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1331,14 +1331,9 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+ {
+ struct hisi_hba *hisi_hba = p;
+ struct device *dev = hisi_hba->dev;
+- u32 ent_msk, ent_tmp, irq_msk;
++ u32 irq_msk;
+ int phy_no = 0;
+
+- ent_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK3);
+- ent_tmp = ent_msk;
+- ent_msk |= ENT_INT_SRC_MSK3_ENT95_MSK_MSK;
+- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, ent_msk);
+-
+ irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS)
+ & 0xeeeeeeee;
+
+@@ -1415,8 +1410,6 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+ phy_no++;
+ }
+
+- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, ent_tmp);
+-
+ return IRQ_HANDLED;
+ }
+
+
diff --git a/patches.drivers/scsi-hisi_sas-remove-some-unneeded-structure-members.patch b/patches.drivers/scsi-hisi_sas-remove-some-unneeded-structure-members.patch
new file mode 100644
index 0000000000..d5e7fa2874
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-remove-some-unneeded-structure-members.patch
@@ -0,0 +1,104 @@
+From: John Garry <john.garry@huawei.com>
+Date: Sat, 24 Mar 2018 00:05:15 +0800
+Subject: scsi: hisi_sas: remove some unneeded structure members
+Git-commit: c90a0bea4f645d561b87becd2bd99f7934402510
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+This patch removes unneeded structure elements:
+
+- hisi_sas_phy.dev_sas_addr: only ever written
+ - Also remove associated function which writes it,
+ hisi_sas_init_add().
+
+- hisi_sas_device.attached_phy: only ever written
+ - Also remove code to set it in hisi_sas_dev_found()
+
+Signed-off-by: John Garry <john.garry@huawei.com>
+Reviewed-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 3 ---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 17 +----------------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 --
+ 3 files changed, 1 insertion(+), 21 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -138,7 +138,6 @@ struct hisi_sas_phy {
+ struct sas_identify identify;
+ struct timer_list timer;
+ u64 port_id; /* from hw */
+- u64 dev_sas_addr;
+ u64 frame_rcvd_size;
+ u8 frame_rcvd[32];
+ u8 phy_attached;
+@@ -175,7 +174,6 @@ struct hisi_sas_device {
+ struct completion *completion;
+ struct hisi_sas_dq *dq;
+ struct list_head list;
+- u64 attached_phy;
+ enum sas_device_type dev_type;
+ int device_id;
+ int sata_idx;
+@@ -441,7 +439,6 @@ extern struct scsi_transport_template *h
+ extern struct scsi_host_template *hisi_sas_sht;
+
+ extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba);
+-extern void hisi_sas_init_add(struct hisi_hba *hisi_hba);
+ extern int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost);
+ extern void hisi_sas_free(struct hisi_hba *hisi_hba);
+ extern u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis,
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -577,10 +577,8 @@ static int hisi_sas_dev_found(struct dom
+ for (phy_no = 0; phy_no < phy_num; phy_no++) {
+ phy = &parent_dev->ex_dev.ex_phy[phy_no];
+ if (SAS_ADDR(phy->attached_sas_addr) ==
+- SAS_ADDR(device->sas_addr)) {
+- sas_dev->attached_phy = phy_no;
++ SAS_ADDR(device->sas_addr))
+ break;
+- }
+ }
+
+ if (phy_no == phy_num) {
+@@ -2081,17 +2079,6 @@ err_out:
+ return NULL;
+ }
+
+-void hisi_sas_init_add(struct hisi_hba *hisi_hba)
+-{
+- int i;
+-
+- for (i = 0; i < hisi_hba->n_phy; i++)
+- memcpy(&hisi_hba->phy[i].dev_sas_addr,
+- hisi_hba->sas_addr,
+- SAS_ADDR_SIZE);
+-}
+-EXPORT_SYMBOL_GPL(hisi_sas_init_add);
+-
+ int hisi_sas_probe(struct platform_device *pdev,
+ const struct hisi_sas_hw *hw)
+ {
+@@ -2145,8 +2132,6 @@ int hisi_sas_probe(struct platform_devic
+ sha->sas_port[i] = &hisi_hba->port[i].sas_port;
+ }
+
+- hisi_sas_init_add(hisi_hba);
+-
+ rc = scsi_add_host(shost, &pdev->dev);
+ if (rc)
+ goto err_out_ha;
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2134,8 +2134,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ sha->sas_port[i] = &hisi_hba->port[i].sas_port;
+ }
+
+- hisi_sas_init_add(hisi_hba);
+-
+ rc = scsi_add_host(shost, dev);
+ if (rc)
+ goto err_out_ha;
diff --git a/patches.drivers/scsi-hisi_sas-remove-unused-variable-hisi_sas_devices-running_req.patch b/patches.drivers/scsi-hisi_sas-remove-unused-variable-hisi_sas_devices-running_req.patch
new file mode 100644
index 0000000000..bbc087c246
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-remove-unused-variable-hisi_sas_devices-running_req.patch
@@ -0,0 +1,89 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 7 Mar 2018 20:25:10 +0800
+Subject: scsi: hisi_sas: remove unused variable hisi_sas_devices.running_req
+Git-commit: 36996a1e6dff4e5835faeb00ba920ccb9a07aa52
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+The structure element hisi_sas_devices.running_req to count how many
+commands are active is in effect only ever written in the code, so remove
+it.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 9 ---------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 3 ---
+ 3 files changed, 13 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index e7fd2877c19c..d1153e8e846b 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -175,7 +175,6 @@ struct hisi_sas_device {
+ struct hisi_sas_dq *dq;
+ struct list_head list;
+ u64 attached_phy;
+- atomic64_t running_req;
+ enum sas_device_type dev_type;
+ int device_id;
+ int sata_idx;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 9ff87902d67a..88ad8d42ef6f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -200,8 +200,6 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
+
+ if (task) {
+ struct device *dev = hisi_hba->dev;
+- struct domain_device *device = task->dev;
+- struct hisi_sas_device *sas_dev = device->lldd_dev;
+
+ if (!task->lldd_task)
+ return;
+@@ -213,9 +211,6 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
+ dma_unmap_sg(dev, task->scatter,
+ task->num_scatter,
+ task->data_dir);
+-
+- if (sas_dev)
+- atomic64_dec(&sas_dev->running_req);
+ }
+
+ if (slot->buf)
+@@ -431,8 +426,6 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+ dq->slot_prep = slot;
+-
+- atomic64_inc(&sas_dev->running_req);
+ ++(*pass);
+
+ return 0;
+@@ -1517,8 +1510,6 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
+
+ dq->slot_prep = slot;
+
+- atomic64_inc(&sas_dev->running_req);
+-
+ /* send abort command to the chip */
+ hisi_hba->hw->start_delivery(dq);
+ spin_unlock_irqrestore(&dq->lock, flags_dq);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+index 2eb89806c512..8dd0e6a6ff8a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1407,9 +1407,6 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba,
+ }
+
+ out:
+- if (sas_dev)
+- atomic64_dec(&sas_dev->running_req);
+-
+ hisi_sas_slot_task_free(hisi_hba, task, slot);
+ sts = ts->stat;
+
+
diff --git a/patches.drivers/scsi-hisi_sas-reset-disks-when-discovered.patch b/patches.drivers/scsi-hisi_sas-reset-disks-when-discovered.patch
new file mode 100644
index 0000000000..0a32230b1d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-reset-disks-when-discovered.patch
@@ -0,0 +1,111 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 21 May 2018 18:09:17 +0800
+Subject: scsi: hisi_sas: Reset disks when discovered
+Git-commit: d5a60dfdb364bd1fa59c2c11be54be80f6990a3d
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+When a disk is discovered, it may be in an error state, or there may be
+residual commands remaining in the disk.
+
+To ensure any disk is in good state after discovery, reset via TMF (for SAS
+disk) or softreset (for a SATA disk).
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 50 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 49 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index a7e4c6e77068..c8e647a65b30 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -24,6 +24,9 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
+ static int hisi_sas_softreset_ata_disk(struct domain_device *device);
+ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
+ void *funcdata);
++static void hisi_sas_release_task(struct hisi_hba *hisi_hba,
++ struct domain_device *device);
++static void hisi_sas_dev_gone(struct domain_device *device);
+
+ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+ {
+@@ -624,12 +627,49 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
+ return sas_dev;
+ }
+
++#define HISI_SAS_SRST_ATA_DISK_CNT 3
++static int hisi_sas_init_device(struct domain_device *device)
++{
++ int rc = TMF_RESP_FUNC_COMPLETE;
++ struct scsi_lun lun;
++ struct hisi_sas_tmf_task tmf_task;
++ int retry = HISI_SAS_SRST_ATA_DISK_CNT;
++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
++
++ switch (device->dev_type) {
++ case SAS_END_DEVICE:
++ int_to_scsilun(0, &lun);
++
++ tmf_task.tmf = TMF_CLEAR_TASK_SET;
++ rc = hisi_sas_debug_issue_ssp_tmf(device, lun.scsi_lun,
++ &tmf_task);
++ if (rc == TMF_RESP_FUNC_COMPLETE)
++ hisi_sas_release_task(hisi_hba, device);
++ break;
++ case SAS_SATA_DEV:
++ case SAS_SATA_PM:
++ case SAS_SATA_PM_PORT:
++ case SAS_SATA_PENDING:
++ while (retry-- > 0) {
++ rc = hisi_sas_softreset_ata_disk(device);
++ if (!rc)
++ break;
++ }
++ break;
++ default:
++ break;
++ }
++
++ return rc;
++}
++
+ static int hisi_sas_dev_found(struct domain_device *device)
+ {
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct domain_device *parent_dev = device->parent;
+ struct hisi_sas_device *sas_dev;
+ struct device *dev = hisi_hba->dev;
++ int rc;
+
+ if (hisi_hba->hw->alloc_dev)
+ sas_dev = hisi_hba->hw->alloc_dev(device);
+@@ -661,14 +701,22 @@ static int hisi_sas_dev_found(struct domain_device *device)
+ "dev:%016llx at ex:%016llx\n",
+ SAS_ADDR(device->sas_addr),
+ SAS_ADDR(parent_dev->sas_addr));
+- return -EINVAL;
++ rc = -EINVAL;
++ goto err_out;
+ }
+ }
+
+ dev_info(dev, "dev[%d:%x] found\n",
+ sas_dev->device_id, sas_dev->dev_type);
+
++ rc = hisi_sas_init_device(device);
++ if (rc)
++ goto err_out;
+ return 0;
++
++err_out:
++ hisi_sas_dev_gone(device);
++ return rc;
+ }
+
+ static int hisi_sas_slave_configure(struct scsi_device *sdev)
+
diff --git a/patches.drivers/scsi-hisi_sas-some-optimizations-of-host-controller-reset.patch b/patches.drivers/scsi-hisi_sas-some-optimizations-of-host-controller-reset.patch
new file mode 100644
index 0000000000..43e2bba786
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-some-optimizations-of-host-controller-reset.patch
@@ -0,0 +1,77 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:36 +0800
+Subject: scsi: hisi_sas: some optimizations of host controller reset
+Git-commit: fb51e7a8d38484687337f16636c5be9528e00fed
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+This patch do following optimizations to host controller reset:
+
+1. Unblock scsi requests before rescanning topology, as SCSI command need be
+ used if new device is found during rescanning topology.
+
+2. Remove drain_workqueue(hisi_hba->wq) and drain_workqueue(shost->work_q), as
+ there is no need to ensure that all PHYs event are done before exiting host
+ reset.
+
+3. Improve message print level of host reset. Host reset is an important and
+ very few occurrence event. We should know its progress even when not
+ debugging.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 326ecb24bb20..64d51a839187 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1061,8 +1061,6 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state,
+ hisi_sas_phy_down(hisi_hba, phy_no, 0);
+
+ }
+-
+- drain_workqueue(hisi_hba->shost->work_q);
+ }
+
+ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+@@ -1079,7 +1077,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
+ return -1;
+
+- dev_dbg(dev, "controller resetting...\n");
++ dev_info(dev, "controller resetting...\n");
+ old_state = hisi_hba->hw->get_phys_state(hisi_hba);
+
+ scsi_block_requests(shost);
+@@ -1088,6 +1086,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ if (rc) {
+ dev_warn(dev, "controller reset failed (%d)\n", rc);
+ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
++ scsi_unblock_requests(shost);
+ goto out;
+ }
+ spin_lock_irqsave(&hisi_hba->lock, flags);
+@@ -1100,15 +1099,13 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ hisi_hba->hw->phys_init(hisi_hba);
+ msleep(1000);
+ hisi_sas_refresh_port_id(hisi_hba);
+- drain_workqueue(hisi_hba->wq);
+- drain_workqueue(shost->work_q);
++ scsi_unblock_requests(shost);
+
+ state = hisi_hba->hw->get_phys_state(hisi_hba);
+ hisi_sas_rescan_topology(hisi_hba, old_state, state);
+- dev_dbg(dev, "controller reset complete\n");
++ dev_info(dev, "controller reset complete\n");
+
+ out:
+- scsi_unblock_requests(shost);
+ clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
+
+ return rc;
+
diff --git a/patches.drivers/scsi-hisi_sas-stop-controller-timer-for-reset.patch b/patches.drivers/scsi-hisi_sas-stop-controller-timer-for-reset.patch
new file mode 100644
index 0000000000..3d64529e3c
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-stop-controller-timer-for-reset.patch
@@ -0,0 +1,33 @@
+From: John Garry <john.garry@huawei.com>
+Date: Wed, 2 May 2018 23:56:29 +0800
+Subject: scsi: hisi_sas: stop controller timer for reset
+Git-commit: 6f7c32d6057cad05cf057b14c910659a8d06c975
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+We should only have the timer enabled after PHY up after controller
+reset, so disable prior to reset.
+
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 24416bb66027..1f27f847b8b4 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1130,6 +1130,9 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ old_state = hisi_hba->hw->get_phys_state(hisi_hba);
+
+ scsi_block_requests(shost);
++ if (timer_pending(&hisi_hba->timer))
++ del_timer_sync(&hisi_hba->timer);
++
+ set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+ rc = hisi_hba->hw->soft_reset(hisi_hba);
+ if (rc) {
+
diff --git a/patches.drivers/scsi-hisi_sas-support-the-property-of-signal-attenuation-for-v2-hw.patch b/patches.drivers/scsi-hisi_sas-support-the-property-of-signal-attenuation-for-v2-hw.patch
new file mode 100644
index 0000000000..d74732833d
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-support-the-property-of-signal-attenuation-for-v2-hw.patch
@@ -0,0 +1,93 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 7 Mar 2018 20:25:06 +0800
+Subject: scsi: hisi_sas: support the property of signal attenuation for v2 hw
+Git-commit: 67c2bf23314170a17f2aefec4f0aaa4881b72181
+Patch-mainline: v4.17-rc1
+References: FATE#326253
+
+The register SAS_PHY_CTRL is configured according to signal quality. The
+signal quality is calculated by signal attenuation of hardware physical
+link. It may be different for different PCB layout.
+
+So, in order to give better support to new board, this patch add support to
+reading the devicetree property, "hisilicon,signal-attenuation". Of course,
+we still keep an default value in driver to adapt old board.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 39 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 4ccb61e2ae5c..42b3fd6a9936 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -406,6 +406,17 @@ struct hisi_sas_err_record_v2 {
+ __le32 dma_rx_err_type;
+ };
+
++struct signal_attenuation_s {
++ u32 de_emphasis;
++ u32 preshoot;
++ u32 boost;
++};
++
++struct sig_atten_lu_s {
++ const struct signal_attenuation_s *att;
++ u32 sas_phy_ctrl;
++};
++
+ static const struct hisi_sas_hw_error one_bit_ecc_errors[] = {
+ {
+ .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF),
+@@ -1130,9 +1141,16 @@ static void phys_try_accept_stp_links_v2_hw(struct hisi_hba *hisi_hba)
+ }
+ }
+
++static const struct signal_attenuation_s x6000 = {9200, 0, 10476};
++static const struct sig_atten_lu_s sig_atten_lu[] = {
++ { &x6000, 0x3016a68 },
++};
++
+ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
+ {
+ struct device *dev = hisi_hba->dev;
++ u32 sas_phy_ctrl = 0x30b9908;
++ u32 signal[3];
+ int i;
+
+ /* Global registers init */
+@@ -1176,9 +1194,28 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 1);
+ hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);
+
++ /* Get sas_phy_ctrl value to deal with TX FFE issue. */
++ if (!device_property_read_u32_array(dev, "hisilicon,signal-attenuation",
++ signal, ARRAY_SIZE(signal))) {
++ for (i = 0; i < ARRAY_SIZE(sig_atten_lu); i++) {
++ const struct sig_atten_lu_s *lookup = &sig_atten_lu[i];
++ const struct signal_attenuation_s *att = lookup->att;
++
++ if ((signal[0] == att->de_emphasis) &&
++ (signal[1] == att->preshoot) &&
++ (signal[2] == att->boost)) {
++ sas_phy_ctrl = lookup->sas_phy_ctrl;
++ break;
++ }
++ }
++
++ if (i == ARRAY_SIZE(sig_atten_lu))
++ dev_warn(dev, "unknown signal attenuation values, using default PHY ctrl config\n");
++ }
++
+ for (i = 0; i < hisi_hba->n_phy; i++) {
+ hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855);
+- hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, 0x30b9908);
++ hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, sas_phy_ctrl);
+ hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d);
+ hisi_sas_phy_write32(hisi_hba, i, SL_CONTROL, 0x0);
+ hisi_sas_phy_write32(hisi_hba, i, TXID_AUTO, 0x2);
+
diff --git a/patches.drivers/scsi-hisi_sas-terminate-stp-reject-quickly-for-v2-hw.patch b/patches.drivers/scsi-hisi_sas-terminate-stp-reject-quickly-for-v2-hw.patch
new file mode 100644
index 0000000000..90337c5882
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-terminate-stp-reject-quickly-for-v2-hw.patch
@@ -0,0 +1,127 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Mon, 21 May 2018 18:09:23 +0800
+Subject: scsi: hisi_sas: Terminate STP reject quickly for v2 hw
+Git-commit: 31709548d2aca9861a72e2890d62fc87c52199de
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+For v2 hw, STP link from target is rejected after host reset because of a
+SoC bug. The STP reject will be terminated after we have sent IO from each
+PHY of a port.
+
+This is not an problem before, as we don't need to setup STP link from
+target immediately after host reset. But now, it is. Because we want to
+send soft-reset immediately after host reset.
+
+In order to terminate STP reject quickly, this patch send ATA reset command
+through each PHY of a port. Notes: ATA reset command don't need target's
+response.
+
+Besides, we do abort dev for each device before terminating STP reject.
+This is a quirk of v2 hw.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 78 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 78 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 4e8046ecf477..cd55849bcd07 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1275,6 +1275,81 @@ static void hisi_sas_reset_init_all_devices(struct hisi_hba *hisi_hba)
+ }
+ }
+
++static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba,
++ struct asd_sas_port *sas_port,
++ struct domain_device *device)
++{
++ struct hisi_sas_tmf_task tmf_task = { .force_phy = 1 };
++ struct ata_port *ap = device->sata_dev.ap;
++ struct device *dev = hisi_hba->dev;
++ int s = sizeof(struct host_to_dev_fis);
++ int rc = TMF_RESP_FUNC_FAILED;
++ struct asd_sas_phy *sas_phy;
++ struct ata_link *link;
++ u8 fis[20] = {0};
++ u32 state;
++
++ state = hisi_hba->hw->get_phys_state(hisi_hba);
++ list_for_each_entry(sas_phy, &sas_port->phy_list, port_phy_el) {
++ if (!(state & BIT(sas_phy->id)))
++ continue;
++
++ ata_for_each_link(link, ap, EDGE) {
++ int pmp = sata_srst_pmp(link);
++
++ tmf_task.phy_id = sas_phy->id;
++ hisi_sas_fill_ata_reset_cmd(link->device, 1, pmp, fis);
++ rc = hisi_sas_exec_internal_tmf_task(device, fis, s,
++ &tmf_task);
++ if (rc != TMF_RESP_FUNC_COMPLETE) {
++ dev_err(dev, "phy%d ata reset failed rc=%d\n",
++ sas_phy->id, rc);
++ break;
++ }
++ }
++ }
++}
++
++static void hisi_sas_terminate_stp_reject(struct hisi_hba *hisi_hba)
++{
++ struct device *dev = hisi_hba->dev;
++ int port_no, rc, i;
++
++ for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
++ struct hisi_sas_device *sas_dev = &hisi_hba->devices[i];
++ struct domain_device *device = sas_dev->sas_device;
++
++ if ((sas_dev->dev_type == SAS_PHY_UNUSED) || !device)
++ continue;
++
++ rc = hisi_sas_internal_task_abort(hisi_hba, device,
++ HISI_SAS_INT_ABT_DEV, 0);
++ if (rc < 0)
++ dev_err(dev, "STP reject: abort dev failed %d\n", rc);
++ }
++
++ for (port_no = 0; port_no < hisi_hba->n_phy; port_no++) {
++ struct hisi_sas_port *port = &hisi_hba->port[port_no];
++ struct asd_sas_port *sas_port = &port->sas_port;
++ struct domain_device *port_dev = sas_port->port_dev;
++ struct domain_device *device;
++
++ if (!port_dev || !DEV_IS_EXPANDER(port_dev->dev_type))
++ continue;
++
++ /* Try to find a SATA device */
++ list_for_each_entry(device, &sas_port->dev_list,
++ dev_list_node) {
++ if (dev_is_sata(device)) {
++ hisi_sas_send_ata_reset_each_phy(hisi_hba,
++ sas_port,
++ device);
++ break;
++ }
++ }
++ }
++}
++
+ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ {
+ struct device *dev = hisi_hba->dev;
+@@ -1312,6 +1387,9 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ hisi_hba->hw->phys_init(hisi_hba);
+ msleep(1000);
+ hisi_sas_refresh_port_id(hisi_hba);
++
++ if (hisi_hba->reject_stp_links_msk)
++ hisi_sas_terminate_stp_reject(hisi_hba);
+ hisi_sas_reset_init_all_devices(hisi_hba);
+ scsi_unblock_requests(shost);
+
+
diff --git a/patches.drivers/scsi-hisi_sas-try-wait-commands-before-before-controller-reset.patch b/patches.drivers/scsi-hisi_sas-try-wait-commands-before-before-controller-reset.patch
new file mode 100644
index 0000000000..61c72b701e
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-try-wait-commands-before-before-controller-reset.patch
@@ -0,0 +1,148 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Mon, 21 May 2018 18:09:20 +0800
+Subject: scsi: hisi_sas: Try wait commands before before controller reset
+Git-commit: a865ae14ff62797f14b760b2063b90c81d27d178
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+We may reset the controller in many scenarios, such as SCSI EH and HW
+errors. There should be no IO which returns from target when SCSI EH is
+active. But for other scenarios, there may be. It is not necessary to make
+such IOs fail.
+
+This patch adds an function of trying to wait for any commands, or IO, to
+complete before host reset. If no more CQ returned from host controller in
+100ms, we assume no more IO can return, and then stop waiting. We wait 5s
+at most.
+
+The HW has a register CQE_SEND_CNT to indicate the total number of CQs that
+has been reported to driver. We can use this register and it is reliable to
+resd this register in such scenarios that require host reset.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 2 ++
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 ++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 19 +++++++++++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 20 ++++++++++++++++++++
+ 4 files changed, 43 insertions(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 37c9a6246dc8..8ce6abb48867 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -246,6 +246,8 @@ struct hisi_sas_hw {
+ u32 (*get_phys_state)(struct hisi_hba *hisi_hba);
+ int (*write_gpio)(struct hisi_hba *hisi_hba, u8 reg_type,
+ u8 reg_index, u8 reg_count, u8 *write_data);
++ void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba,
++ int delay_ms, int timeout_ms);
+ int max_command_entries;
+ int complete_hdr_size;
+ struct scsi_host_template *sht;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index dc67bd7c7ab0..5bc522c35690 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1293,6 +1293,8 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ old_state = hisi_hba->hw->get_phys_state(hisi_hba);
+
+ scsi_block_requests(shost);
++ hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000);
++
+ if (timer_pending(&hisi_hba->timer))
+ del_timer_sync(&hisi_hba->timer);
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 8def327c4f46..18dbaffc9988 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -144,6 +144,7 @@
+ #define SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF 19
+ #define SAS_ECC_INTR_MSK 0x1ec
+ #define HGC_ERR_STAT_EN 0x238
++#define CQE_SEND_CNT 0x248
+ #define DLVRY_Q_0_BASE_ADDR_LO 0x260
+ #define DLVRY_Q_0_BASE_ADDR_HI 0x264
+ #define DLVRY_Q_0_DEPTH 0x268
+@@ -3501,6 +3502,23 @@ static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type,
+ return 0;
+ }
+
++static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba,
++ int delay_ms, int timeout_ms)
++{
++ struct device *dev = hisi_hba->dev;
++ int entries, entries_old = 0, time;
++
++ for (time = 0; time < timeout_ms; time += delay_ms) {
++ entries = hisi_sas_read32(hisi_hba, CQE_SEND_CNT);
++ if (entries == entries_old)
++ break;
++
++ entries_old = entries;
++ msleep(delay_ms);
++ }
++
++ dev_dbg(dev, "wait commands complete %dms\n", time);
++}
+
+ static struct scsi_host_template sht_v2_hw = {
+ .name = DRV_NAME,
+@@ -3552,6 +3570,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
+ .soft_reset = soft_reset_v2_hw,
+ .get_phys_state = get_phys_state_v2_hw,
+ .write_gpio = write_gpio_v2_hw,
++ .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v2_hw,
+ .sht = &sht_v2_hw,
+ };
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 13d21349d1ba..dd5f542bbc45 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -92,6 +92,7 @@
+ #define SAS_ECC_INTR 0x1e8
+ #define SAS_ECC_INTR_MSK 0x1ec
+ #define HGC_ERR_STAT_EN 0x238
++#define CQE_SEND_CNT 0x248
+ #define DLVRY_Q_0_BASE_ADDR_LO 0x260
+ #define DLVRY_Q_0_BASE_ADDR_HI 0x264
+ #define DLVRY_Q_0_DEPTH 0x268
+@@ -2015,6 +2016,24 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type,
+ return 0;
+ }
+
++static void wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba,
++ int delay_ms, int timeout_ms)
++{
++ struct device *dev = hisi_hba->dev;
++ int entries, entries_old = 0, time;
++
++ for (time = 0; time < timeout_ms; time += delay_ms) {
++ entries = hisi_sas_read32(hisi_hba, CQE_SEND_CNT);
++ if (entries == entries_old)
++ break;
++
++ entries_old = entries;
++ msleep(delay_ms);
++ }
++
++ dev_dbg(dev, "wait commands complete %dms\n", time);
++}
++
+ static struct scsi_host_template sht_v3_hw = {
+ .name = DRV_NAME,
+ .module = THIS_MODULE,
+@@ -2063,6 +2082,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
+ .get_phys_state = get_phys_state_v3_hw,
+ .get_events = phy_get_events_v3_hw,
+ .write_gpio = write_gpio_v3_hw,
++ .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw,
+ };
+
+ static struct Scsi_Host *
+
diff --git a/patches.drivers/scsi-hisi_sas-update-phy-linkrate-after-a-controller-reset.patch b/patches.drivers/scsi-hisi_sas-update-phy-linkrate-after-a-controller-reset.patch
new file mode 100644
index 0000000000..04f2a1efaa
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-update-phy-linkrate-after-a-controller-reset.patch
@@ -0,0 +1,181 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 2 May 2018 23:56:30 +0800
+Subject: scsi: hisi_sas: update PHY linkrate after a controller reset
+Git-commit: c2c1d9ded0a2c06df300e244220708f5c1f1db77
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+After the controller is reset, we currently may not honour the PHY max
+linkrate set via sysfs, in that after a reset we always revert to max
+linkrate of 12Gbps, ignoring the value set via sysfs.
+
+This patch modifies to policy to set the programmed PHY linkrate,
+honouring the max linkrate programmed via sysfs.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 +
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 16 ++++++++++++++++
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 31 ++++++++++++++++++-------------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 31 ++++++++++++++++++-------------
+ 4 files changed, 53 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 04a40c427a20..44105389f2df 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -463,4 +463,5 @@ extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba);
+ extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
+ enum hisi_sas_phy_event event);
+ extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba);
++extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max);
+ #endif
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 1f27f847b8b4..ff5b8d7de1d1 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -135,6 +135,22 @@ int hisi_sas_get_ncq_tag(struct sas_task *task, u32 *tag)
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_get_ncq_tag);
+
++/*
++ * This function assumes linkrate mask fits in 8 bits, which it
++ * does for all HW versions supported.
++ */
++u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max)
++{
++ u16 rate = 0;
++ int i;
++
++ max -= SAS_LINK_RATE_1_5_GBPS;
++ for (i = 0; i <= max; i++)
++ rate |= 1 << (i * 2);
++ return rate;
++}
++EXPORT_SYMBOL_GPL(hisi_sas_get_prog_phy_linkrate_mask);
++
+ static struct hisi_hba *dev_to_hisi_hba(struct domain_device *device)
+ {
+ return device->port->ha->lldd_ha;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 6dda6eb50918..9e687319b8bc 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -1216,7 +1216,22 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
+ }
+
+ for (i = 0; i < hisi_hba->n_phy; i++) {
+- hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855);
++ struct hisi_sas_phy *phy = &hisi_hba->phy[i];
++ struct asd_sas_phy *sas_phy = &phy->sas_phy;
++ u32 prog_phy_link_rate = 0x800;
++
++ if (!sas_phy->phy || (sas_phy->phy->maximum_linkrate <
++ SAS_LINK_RATE_1_5_GBPS)) {
++ prog_phy_link_rate = 0x855;
++ } else {
++ enum sas_linkrate max = sas_phy->phy->maximum_linkrate;
++
++ prog_phy_link_rate =
++ hisi_sas_get_prog_phy_linkrate_mask(max) |
++ 0x800;
++ }
++ hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE,
++ prog_phy_link_rate);
+ hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, sas_phy_ctrl);
+ hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d);
+ hisi_sas_phy_write32(hisi_hba, i, SL_CONTROL, 0x0);
+@@ -1585,13 +1600,10 @@ static enum sas_linkrate phy_get_max_linkrate_v2_hw(void)
+ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,
+ struct sas_phy_linkrates *r)
+ {
+- u32 prog_phy_link_rate =
+- hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE);
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+- int i;
+ enum sas_linkrate min, max;
+- u32 rate_mask = 0;
++ u32 prog_phy_link_rate = 0x800;
+
+ if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+ max = sas_phy->phy->maximum_linkrate;
+@@ -1604,14 +1616,7 @@ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no,
+
+ sas_phy->phy->maximum_linkrate = max;
+ sas_phy->phy->minimum_linkrate = min;
+-
+- max -= SAS_LINK_RATE_1_5_GBPS;
+-
+- for (i = 0; i <= max; i++)
+- rate_mask |= 1 << (i * 2);
+-
+- prog_phy_link_rate &= ~0xff;
+- prog_phy_link_rate |= rate_mask;
++ prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
+
+ disable_phy_v2_hw(hisi_hba, phy_no);
+ msleep(100);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 5c0d9683630b..ffa3cea5ca8f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -429,7 +429,22 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);
+
+ for (i = 0; i < hisi_hba->n_phy; i++) {
+- hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855);
++ struct hisi_sas_phy *phy = &hisi_hba->phy[i];
++ struct asd_sas_phy *sas_phy = &phy->sas_phy;
++ u32 prog_phy_link_rate = 0x800;
++
++ if (!sas_phy->phy || (sas_phy->phy->maximum_linkrate <
++ SAS_LINK_RATE_1_5_GBPS)) {
++ prog_phy_link_rate = 0x855;
++ } else {
++ enum sas_linkrate max = sas_phy->phy->maximum_linkrate;
++
++ prog_phy_link_rate =
++ hisi_sas_get_prog_phy_linkrate_mask(max) |
++ 0x800;
++ }
++ hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE,
++ prog_phy_link_rate);
+ hisi_sas_phy_write32(hisi_hba, i, SAS_RX_TRAIN_TIMER, 0x13e80);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
+@@ -1869,13 +1884,10 @@ static int hisi_sas_v3_init(struct hisi_hba *hisi_hba)
+ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
+ struct sas_phy_linkrates *r)
+ {
+- u32 prog_phy_link_rate =
+- hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE);
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+- int i;
+ enum sas_linkrate min, max;
+- u32 rate_mask = 0;
++ u32 prog_phy_link_rate = 0x800;
+
+ if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+ max = sas_phy->phy->maximum_linkrate;
+@@ -1888,14 +1900,7 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
+
+ sas_phy->phy->maximum_linkrate = max;
+ sas_phy->phy->minimum_linkrate = min;
+-
+- max -= SAS_LINK_RATE_1_5_GBPS;
+-
+- for (i = 0; i <= max; i++)
+- rate_mask |= 1 << (i * 2);
+-
+- prog_phy_link_rate &= ~0xff;
+- prog_phy_link_rate |= rate_mask;
++ prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
+
+ disable_phy_v3_hw(hisi_hba, phy_no);
+ msleep(100);
+
diff --git a/patches.drivers/scsi-hisi_sas-update-ras-feature-for-later-revision-of-v3-hw.patch b/patches.drivers/scsi-hisi_sas-update-ras-feature-for-later-revision-of-v3-hw.patch
new file mode 100644
index 0000000000..ef34ab6448
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-update-ras-feature-for-later-revision-of-v3-hw.patch
@@ -0,0 +1,158 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 24 Mar 2018 00:05:09 +0800
+Subject: scsi: hisi_sas: update RAS feature for later revision of v3 HW
+Git-commit: 61573630918bf29a1974e08ef5d4b8889fb9dd7f
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+There is an modification for later revision of v3 hw. More HW errors are
+reported through RAS interrupt. These errors were originally reported
+only through MSI.
+
+When report to RAS, some combinations are done to port AXI errors and
+FIFO OMIT errors. For example, each port has 4 AXI errors, and they are
+combined to one when report to RAS.
+
+This patch does two things:
+
+1. Enable RAS interrupt of these errors and handle them in PCI
+ error handlers.
+
+2. Disable MSI interrupts of these errors for this later revision hw.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 60 ++++++++++++++++++++++++++++++++--
+ 1 file changed, 58 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 6f3e5ba6b472..df5414a0bdd9 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -216,6 +216,9 @@
+ #define SAS_RAS_INTR1 (RAS_BASE + 0x04)
+ #define SAS_RAS_INTR0_MASK (RAS_BASE + 0x08)
+ #define SAS_RAS_INTR1_MASK (RAS_BASE + 0x0c)
++#define CFG_SAS_RAS_INTR_MASK (RAS_BASE + 0x1c)
++#define SAS_RAS_INTR2 (RAS_BASE + 0x20)
++#define SAS_RAS_INTR2_MASK (RAS_BASE + 0x24)
+
+ /* HW dma structures */
+ /* Delivery queue header */
+@@ -392,6 +395,7 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
+
+ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ {
++ struct pci_dev *pdev = hisi_hba->pci_dev;
+ int i;
+
+ /* Global registers init */
+@@ -409,7 +413,10 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe);
+- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff);
++ if (pdev->revision >= 0x21)
++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7fff);
++ else
++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff);
+ hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0);
+ hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0);
+ hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0);
+@@ -428,7 +435,12 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
+ hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
+- hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xff87ffff);
++ if (pdev->revision >= 0x21)
++ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK,
++ 0xffffffff);
++ else
++ hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK,
++ 0xff87ffff);
+ hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe);
+ hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
+ hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
+@@ -503,6 +515,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
+ /* RAS registers init */
+ hisi_sas_write32(hisi_hba, SAS_RAS_INTR0_MASK, 0x0);
+ hisi_sas_write32(hisi_hba, SAS_RAS_INTR1_MASK, 0x0);
++ hisi_sas_write32(hisi_hba, SAS_RAS_INTR2_MASK, 0x0);
++ hisi_sas_write32(hisi_hba, CFG_SAS_RAS_INTR_MASK, 0x0);
+ }
+
+ static void config_phy_opt_mode_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+@@ -1319,6 +1333,13 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+ CHL_INT1);
+ u32 irq_value2 = hisi_sas_phy_read32(hisi_hba, phy_no,
+ CHL_INT2);
++ u32 irq_msk1 = hisi_sas_phy_read32(hisi_hba, phy_no,
++ CHL_INT1_MSK);
++ u32 irq_msk2 = hisi_sas_phy_read32(hisi_hba, phy_no,
++ CHL_INT2_MSK);
++
++ irq_value1 &= ~irq_msk1;
++ irq_value2 &= ~irq_msk2;
+
+ if ((irq_msk & (4 << (phy_no * 4))) &&
+ irq_value1) {
+@@ -1448,6 +1469,7 @@ static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p)
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, irq_msk | 0x1df00);
+
+ irq_value = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
++ irq_value &= ~irq_msk;
+
+ for (i = 0; i < ARRAY_SIZE(fatal_axi_error); i++) {
+ const struct hisi_sas_hw_error *error = &fatal_axi_error[i];
+@@ -2222,6 +2244,29 @@ static const struct hisi_sas_hw_error sas_ras_intr1_nfe[] = {
+ { .irq_msk = BIT(31), .msg = "DMAC7_RX_POISON" },
+ };
+
++static const struct hisi_sas_hw_error sas_ras_intr2_nfe[] = {
++ { .irq_msk = BIT(0), .msg = "DMAC0_AXI_BUS_ERR" },
++ { .irq_msk = BIT(1), .msg = "DMAC1_AXI_BUS_ERR" },
++ { .irq_msk = BIT(2), .msg = "DMAC2_AXI_BUS_ERR" },
++ { .irq_msk = BIT(3), .msg = "DMAC3_AXI_BUS_ERR" },
++ { .irq_msk = BIT(4), .msg = "DMAC4_AXI_BUS_ERR" },
++ { .irq_msk = BIT(5), .msg = "DMAC5_AXI_BUS_ERR" },
++ { .irq_msk = BIT(6), .msg = "DMAC6_AXI_BUS_ERR" },
++ { .irq_msk = BIT(7), .msg = "DMAC7_AXI_BUS_ERR" },
++ { .irq_msk = BIT(8), .msg = "DMAC0_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(9), .msg = "DMAC1_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(10), .msg = "DMAC2_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(11), .msg = "DMAC3_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(12), .msg = "DMAC4_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(13), .msg = "DMAC5_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(14), .msg = "DMAC6_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(15), .msg = "DMAC7_FIFO_OMIT_ERR" },
++ { .irq_msk = BIT(16), .msg = "HGC_RLSE_SLOT_UNMATCH" },
++ { .irq_msk = BIT(17), .msg = "HGC_LM_ADD_FCH_LIST_ERR" },
++ { .irq_msk = BIT(18), .msg = "HGC_AXI_BUS_ERR" },
++ { .irq_msk = BIT(19), .msg = "HGC_FIFO_OMIT_ERR" },
++};
++
+ static bool process_non_fatal_error_v3_hw(struct hisi_hba *hisi_hba)
+ {
+ struct device *dev = hisi_hba->dev;
+@@ -2252,6 +2297,17 @@ static bool process_non_fatal_error_v3_hw(struct hisi_hba *hisi_hba)
+ }
+ hisi_sas_write32(hisi_hba, SAS_RAS_INTR1, irq_value);
+
++ irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR2);
++ for (i = 0; i < ARRAY_SIZE(sas_ras_intr2_nfe); i++) {
++ ras_error = &sas_ras_intr2_nfe[i];
++ if (ras_error->irq_msk & irq_value) {
++ dev_warn(dev, "SAS_RAS_INTR2: %s(irq_value=0x%x) found.\n",
++ ras_error->msg, irq_value);
++ need_reset = true;
++ }
++ }
++ hisi_sas_write32(hisi_hba, SAS_RAS_INTR2, irq_value);
++
+ return need_reset;
+ }
+
+
diff --git a/patches.drivers/scsi-hisi_sas-use-an-general-way-to-delay-phy-work.patch b/patches.drivers/scsi-hisi_sas-use-an-general-way-to-delay-phy-work.patch
new file mode 100644
index 0000000000..01a66f7c85
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-use-an-general-way-to-delay-phy-work.patch
@@ -0,0 +1,142 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Sat, 9 Dec 2017 01:16:44 +0800
+Subject: scsi: hisi_sas: use an general way to delay PHY work
+Git-commit: e537b62b0796042e1ab66657c4dab662d19e9f0b
+Patch-mainline: v4.16-rc1
+References: FATE#326253
+
+Use an general way to do delay work for a PHY. Then it will be easier to add
+new delayed work for a PHY in future.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 9 ++++++++-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 22 ++++++++++++++++++++--
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 ++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 5 files changed, 32 insertions(+), 7 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -124,13 +124,18 @@ enum hisi_sas_bit_err_type {
+ HISI_SAS_ERR_MULTI_BIT_ECC = 0x1,
+ };
+
++enum hisi_sas_phy_event {
++ HISI_PHYE_PHY_UP = 0U,
++ HISI_PHYES_NUM,
++};
++
+ struct hisi_sas_phy {
++ struct work_struct works[HISI_PHYES_NUM];
+ struct hisi_hba *hisi_hba;
+ struct hisi_sas_port *port;
+ struct asd_sas_phy sas_phy;
+ struct sas_identify identify;
+ struct timer_list timer;
+- struct work_struct phyup_ws;
+ u64 port_id; /* from hw */
+ u64 dev_sas_addr;
+ u64 frame_rcvd_size;
+@@ -454,4 +459,6 @@ extern void hisi_sas_init_mem(struct his
+ extern void hisi_sas_rst_work_handler(struct work_struct *work);
+ extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);
+ extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba);
++extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
++ enum hisi_sas_phy_event event);
+ #endif
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -622,7 +622,7 @@ static int hisi_sas_scan_finished(struct
+ static void hisi_sas_phyup_work(struct work_struct *work)
+ {
+ struct hisi_sas_phy *phy =
+- container_of(work, struct hisi_sas_phy, phyup_ws);
++ container_of(work, typeof(*phy), works[HISI_PHYE_PHY_UP]);
+ struct hisi_hba *hisi_hba = phy->hisi_hba;
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ int phy_no = sas_phy->id;
+@@ -631,10 +631,27 @@ static void hisi_sas_phyup_work(struct w
+ hisi_sas_bytes_dmaed(hisi_hba, phy_no);
+ }
+
++static const work_func_t hisi_sas_phye_fns[HISI_PHYES_NUM] = {
++ [HISI_PHYE_PHY_UP] = hisi_sas_phyup_work,
++};
++
++bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
++ enum hisi_sas_phy_event event)
++{
++ struct hisi_hba *hisi_hba = phy->hisi_hba;
++
++ if (WARN_ON(event >= HISI_PHYES_NUM))
++ return false;
++
++ return queue_work(hisi_hba->wq, &phy->works[event]);
++}
++EXPORT_SYMBOL_GPL(hisi_sas_notify_phy_event);
++
+ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no)
+ {
+ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+ struct asd_sas_phy *sas_phy = &phy->sas_phy;
++ int i;
+
+ phy->hisi_hba = hisi_hba;
+ phy->port = NULL;
+@@ -653,7 +670,8 @@ static void hisi_sas_phy_init(struct his
+ sas_phy->ha = (struct sas_ha_struct *)hisi_hba->shost->hostdata;
+ sas_phy->lldd_phy = phy;
+
+- INIT_WORK(&phy->phyup_ws, hisi_sas_phyup_work);
++ for (i = 0; i < HISI_PHYES_NUM; i++)
++ INIT_WORK(&phy->works[i], hisi_sas_phye_fns[i]);
+ }
+
+ static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy)
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1482,7 +1482,7 @@ static irqreturn_t int_phyup_v1_hw(int i
+ else if (phy->identify.device_type != SAS_PHY_UNUSED)
+ phy->identify.target_port_protocols =
+ SAS_PROTOCOL_SMP;
+- queue_work(hisi_hba->wq, &phy->phyup_ws);
++ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+
+ end:
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2710,7 +2710,7 @@ static int phy_up_v2_hw(int phy_no, stru
+ if (!timer_pending(&hisi_hba->timer))
+ set_link_timer_quirk(hisi_hba);
+ }
+- queue_work(hisi_hba->wq, &phy->phyup_ws);
++ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+
+ end:
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+@@ -3264,7 +3264,7 @@ static irqreturn_t sata_int_v2_hw(int ir
+ phy->identify.device_type = SAS_SATA_DEV;
+ phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);
+ phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
+- queue_work(hisi_hba->wq, &phy->phyup_ws);
++ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+
+ end:
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC1 + offset, ent_tmp);
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1192,7 +1192,7 @@ static int phy_up_v3_hw(int phy_no, stru
+
+ phy->port_id = port_id;
+ phy->phy_attached = 1;
+- queue_work(hisi_hba->wq, &phy->phyup_ws);
++ hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP);
+
+ end:
+ hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
diff --git a/patches.drivers/scsi-hisi_sas-use-device-lock-to-protect-slot-alloc-free.patch b/patches.drivers/scsi-hisi_sas-use-device-lock-to-protect-slot-alloc-free.patch
new file mode 100644
index 0000000000..151f162f55
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-use-device-lock-to-protect-slot-alloc-free.patch
@@ -0,0 +1,246 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Wed, 9 May 2018 23:10:49 +0800
+Subject: scsi: hisi_sas: Use device lock to protect slot alloc/free
+Git-commit: e85d93b21267fff56110e3a258b9fad8adbfbce3
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+The IPTT of a slot is unique, and we currently use hisi_hba lock to
+protect it.
+
+Now slot is managed on hisi_sas_device.list, so use DQ lock to protect
+for allocating and freeing the slot.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 56 ++++++++++------------------------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 --
+ 2 files changed, 16 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index bf374a795962..a451625b8253 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -214,6 +214,8 @@ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba)
+ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
+ struct hisi_sas_slot *slot)
+ {
++ struct hisi_sas_dq *dq = &hisi_hba->dq[slot->dlvry_queue];
++ unsigned long flags;
+
+ if (task) {
+ struct device *dev = hisi_hba->dev;
+@@ -233,11 +235,15 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
+ if (slot->buf)
+ dma_pool_free(hisi_hba->buffer_pool, slot->buf, slot->buf_dma);
+
++ spin_lock_irqsave(&dq->lock, flags);
+ list_del_init(&slot->entry);
++ spin_unlock_irqrestore(&dq->lock, flags);
+ slot->buf = NULL;
+ slot->task = NULL;
+ slot->port = NULL;
++ spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot->idx);
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
+ /* slot memory is fully zeroed when it is reused */
+ }
+@@ -286,7 +292,6 @@ static void hisi_sas_slot_abort(struct work_struct *work)
+ struct scsi_lun lun;
+ struct device *dev = hisi_hba->dev;
+ int tag = abort_slot->idx;
+- unsigned long flags;
+
+ if (!(task->task_proto & SAS_PROTOCOL_SSP)) {
+ dev_err(dev, "cannot abort slot for non-ssp task\n");
+@@ -300,9 +305,7 @@ static void hisi_sas_slot_abort(struct work_struct *work)
+ hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, &tmf_task);
+ out:
+ /* Do cleanup for this task */
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_task_free(hisi_hba, task, abort_slot);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ if (task->task_done)
+ task->task_done(task);
+ }
+@@ -471,9 +474,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq *dq,
+ break;
+ }
+
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ spin_lock_irqsave(&dq->lock, flags);
+ list_add_tail(&slot->entry, &sas_dev->list);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ spin_unlock_irqrestore(&dq->lock, flags);
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+@@ -1047,7 +1050,6 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct device *dev = hisi_hba->dev;
+ int s = sizeof(struct host_to_dev_fis);
+- unsigned long flags;
+
+ ata_for_each_link(link, ap, EDGE) {
+ int pmp = sata_srst_pmp(link);
+@@ -1072,11 +1074,8 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ dev_err(dev, "ata disk reset failed\n");
+ }
+
+- if (rc == TMF_RESP_FUNC_COMPLETE) {
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ if (rc == TMF_RESP_FUNC_COMPLETE)
+ hisi_sas_release_task(hisi_hba, device);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- }
+
+ return rc;
+ }
+@@ -1173,7 +1172,6 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ struct device *dev = hisi_hba->dev;
+ struct Scsi_Host *shost = hisi_hba->shost;
+ u32 old_state, state;
+- unsigned long flags;
+ int rc;
+
+ if (!hisi_hba->hw->soft_reset)
+@@ -1197,9 +1195,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
+ scsi_unblock_requests(shost);
+ goto out;
+ }
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_release_tasks(hisi_hba);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
+ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+
+@@ -1274,11 +1270,8 @@ static int hisi_sas_abort_task(struct sas_task *task)
+ * will have already been completed
+ */
+ if (rc == TMF_RESP_FUNC_COMPLETE && rc2 != TMF_RESP_FUNC_SUCC) {
+- if (task->lldd_task) {
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ if (task->lldd_task)
+ hisi_sas_do_release_task(hisi_hba, task, slot);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- }
+ }
+ } else if (task->task_proto & SAS_PROTOCOL_SATA ||
+ task->task_proto & SAS_PROTOCOL_STP) {
+@@ -1300,11 +1293,8 @@ static int hisi_sas_abort_task(struct sas_task *task)
+ rc = hisi_sas_internal_task_abort(hisi_hba, device,
+ HISI_SAS_INT_ABT_CMD, tag);
+ if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) &&
+- task->lldd_task) {
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ task->lldd_task)
+ hisi_sas_do_release_task(hisi_hba, task, slot);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- }
+ }
+
+ out:
+@@ -1319,7 +1309,6 @@ static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun)
+ struct device *dev = hisi_hba->dev;
+ struct hisi_sas_tmf_task tmf_task;
+ int rc = TMF_RESP_FUNC_FAILED;
+- unsigned long flags;
+
+ rc = hisi_sas_internal_task_abort(hisi_hba, device,
+ HISI_SAS_INT_ABT_DEV, 0);
+@@ -1332,11 +1321,8 @@ static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun)
+ tmf_task.tmf = TMF_ABORT_TASK_SET;
+ rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task);
+
+- if (rc == TMF_RESP_FUNC_COMPLETE) {
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ if (rc == TMF_RESP_FUNC_COMPLETE)
+ hisi_sas_release_task(hisi_hba, device);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- }
+
+ return rc;
+ }
+@@ -1369,7 +1355,6 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct device *dev = hisi_hba->dev;
+ int rc = TMF_RESP_FUNC_FAILED;
+- unsigned long flags;
+
+ if (sas_dev->dev_status != HISI_SAS_DEV_EH)
+ return TMF_RESP_FUNC_FAILED;
+@@ -1385,11 +1370,9 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
+
+ rc = hisi_sas_debug_I_T_nexus_reset(device);
+
+- if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV)) {
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV))
+ hisi_sas_release_task(hisi_hba, device);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- }
++
+ return rc;
+ }
+
+@@ -1398,7 +1381,6 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun)
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct device *dev = hisi_hba->dev;
+- unsigned long flags;
+ int rc = TMF_RESP_FUNC_FAILED;
+
+ sas_dev->dev_status = HISI_SAS_DEV_EH;
+@@ -1418,11 +1400,8 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun)
+
+ rc = sas_phy_reset(phy, 1);
+
+- if (rc == 0) {
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ if (rc == 0)
+ hisi_sas_release_task(hisi_hba, device);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- }
+ sas_put_local_phy(phy);
+ } else {
+ struct hisi_sas_tmf_task tmf_task = { .tmf = TMF_LU_RESET };
+@@ -1436,11 +1415,8 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun)
+ hisi_sas_dereg_device(hisi_hba, device);
+
+ rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task);
+- if (rc == TMF_RESP_FUNC_COMPLETE) {
+- spin_lock_irqsave(&hisi_hba->lock, flags);
++ if (rc == TMF_RESP_FUNC_COMPLETE)
+ hisi_sas_release_task(hisi_hba, device);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- }
+ }
+ out:
+ if (rc != TMF_RESP_FUNC_COMPLETE)
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 56f1046b244c..c013673ee8ac 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2373,7 +2373,6 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
+ u32 device_state, status;
+ int rc;
+ u32 reg_val;
+- unsigned long flags;
+
+ if (!pdev->pm_cap) {
+ dev_err(dev, "PCI PM not supported\n");
+@@ -2418,9 +2417,7 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, device_state);
+
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_release_tasks(hisi_hba);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
+ sas_suspend_ha(sha);
+ return 0;
+
diff --git a/patches.drivers/scsi-hisi_sas-use-dma_zalloc_coherent.patch b/patches.drivers/scsi-hisi_sas-use-dma_zalloc_coherent.patch
new file mode 100644
index 0000000000..c715c9b760
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-use-dma_zalloc_coherent.patch
@@ -0,0 +1,38 @@
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Sat, 24 Mar 2018 00:05:11 +0800
+Subject: scsi: hisi_sas: use dma_zalloc_coherent()
+Git-commit: 4f4e21b8ff3e706f79e1adb2a475c3f5ee6b57f9
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+This is a warning coming from Coccinelle, and need to use new interface
+dma_zalloc_coherent() instead of dma_alloc_coherent()/memset().
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index a21679574142..9563dfa72181 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1822,13 +1822,11 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
+ goto err_out;
+
+ s = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
+- hisi_hba->itct = dma_alloc_coherent(dev, s, &hisi_hba->itct_dma,
++ hisi_hba->itct = dma_zalloc_coherent(dev, s, &hisi_hba->itct_dma,
+ GFP_KERNEL);
+ if (!hisi_hba->itct)
+ goto err_out;
+
+- memset(hisi_hba->itct, 0, s);
+-
+ hisi_hba->slot_info = devm_kcalloc(dev, max_command_entries,
+ sizeof(struct hisi_sas_slot),
+ GFP_KERNEL);
+
diff --git a/patches.drivers/scsi-hisi_sas-workaround-a-v3-hw-hilink-bug.patch b/patches.drivers/scsi-hisi_sas-workaround-a-v3-hw-hilink-bug.patch
new file mode 100644
index 0000000000..ad547e9e34
--- /dev/null
+++ b/patches.drivers/scsi-hisi_sas-workaround-a-v3-hw-hilink-bug.patch
@@ -0,0 +1,91 @@
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+Date: Wed, 2 May 2018 23:56:34 +0800
+Subject: scsi: hisi_sas: workaround a v3 hw hilink bug
+Git-commit: f70c1251deb5ab17dec70119c03f2428288ebada
+Patch-mainline: v4.18-rc1
+References: FATE#326253
+
+There is an SoC bug of v3 hw development version. When hot- unplugging a
+directly attached disk, the PHY down interrupt may not happen. It is
+very easy to appear on some boards.
+
+When this issue occurs, the controller will receive many invalid dword
+frames, and the "alos" fields of register HILINK_ERR_DFX can indicate
+that disk was unplugged.
+
+As an workaround solution, this patch detects this issue in the channel
+interrupt, and workaround it by following steps:
+
+ - Disable the PHY
+ - Clear error code and interrupt
+ - Enable the PHY
+
+Then the HW will reissue PHY down interrupt.
+
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 25 ++++++++++++++++++++++++-
+ 1 file changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 28bb71e3b093..492c3beea3d5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -106,6 +106,7 @@
+ #define COMPL_Q_0_RD_PTR 0x4f0
+ #define AWQOS_AWCACHE_CFG 0xc84
+ #define ARQOS_ARCACHE_CFG 0xc88
++#define HILINK_ERR_DFX 0xe04
+
+ /* phy registers requiring init */
+ #define PORT_BASE (0x2000)
+@@ -167,6 +168,7 @@
+ #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22
+ #define CHL_INT2 (PORT_BASE + 0x1bc)
+ #define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0
++#define CHL_INT2_RX_INVLD_DW_OFF 30
+ #define CHL_INT2_STP_LINK_TIMEOUT_OFF 31
+ #define CHL_INT0_MSK (PORT_BASE + 0x1c0)
+ #define CHL_INT1_MSK (PORT_BASE + 0x1c4)
+@@ -1345,6 +1347,7 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+ {
+ struct hisi_hba *hisi_hba = p;
+ struct device *dev = hisi_hba->dev;
++ struct pci_dev *pci_dev = hisi_hba->pci_dev;
+ u32 irq_msk;
+ int phy_no = 0;
+
+@@ -1410,8 +1413,28 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+
+ hisi_sas_phy_write32(hisi_hba, phy_no,
+ CHL_INT2, irq_value2);
+- }
+
++ if ((irq_value2 & BIT(CHL_INT2_RX_INVLD_DW_OFF)) &&
++ (pci_dev->revision == 0x20)) {
++ u32 reg_value;
++ int rc;
++
++ rc = hisi_sas_read32_poll_timeout_atomic(
++ HILINK_ERR_DFX, reg_value,
++ !((reg_value >> 8) & BIT(phy_no)),
++ 1000, 10000);
++ if (rc) {
++ disable_phy_v3_hw(hisi_hba, phy_no);
++ hisi_sas_phy_write32(hisi_hba, phy_no,
++ CHL_INT2,
++ BIT(CHL_INT2_RX_INVLD_DW_OFF));
++ hisi_sas_phy_read32(hisi_hba, phy_no,
++ ERR_CNT_INVLD_DW);
++ mdelay(1);
++ enable_phy_v3_hw(hisi_hba, phy_no);
++ }
++ }
++ }
+
+ if (irq_msk & (2 << (phy_no * 4)) && irq_value0) {
+ hisi_sas_phy_write32(hisi_hba, phy_no,
+
diff --git a/patches.drivers/scsi-lpfc-Add-Buffer-overflow-check-when-nvme_info-l.patch b/patches.drivers/scsi-lpfc-Add-Buffer-overflow-check-when-nvme_info-l.patch
new file mode 100644
index 0000000000..8948bcc500
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Add-Buffer-overflow-check-when-nvme_info-l.patch
@@ -0,0 +1,550 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 26 Jun 2018 08:24:22 -0700
+Subject: [PATCH] scsi: lpfc: Add Buffer overflow check, when nvme_info larger
+ than PAGE_SIZE
+References: bsc#1102658
+Git-commit: afff0d2321ea2beb6f4dcd029d4667acf73dec25
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+Patch-mainline: Queued in subsystem maintainer repository
+
+Kernel crashes during fill_read_buffer when nvme_info sysfs file read.
+
+With multiple NVME targets, approx 40, nvme_info may grow larger than
+PAGE_SIZE bytes. snprintf(buf + len, PAGE_SIZE - len, ...) logic is flawed
+as PAGE_SIZE - len can be < 0 and is accepted by snprintf. This results in
+buffer overflow, and is detected with check from dev_attr_show and
+fill_read_buffer.
+
+Change to use scnprintf to a tmp array, before calling strlcat to ensure no
+buffer overflow over PAGE_SIZE bytes.
+
+Message "6314" created as a new message indicating when there is more nvme
+info, but is truncated to fit within PAGE_SIZE bytes.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_attr.c | 432 +++++++++++++++++++++++++-----------------
+ 1 file changed, 257 insertions(+), 175 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
+index fdabba7b0282..0f8ab3ffb010 100644
+--- a/drivers/scsi/lpfc/lpfc_attr.c
++++ b/drivers/scsi/lpfc/lpfc_attr.c
+@@ -64,6 +64,9 @@
+ #define LPFC_MIN_MRQ_POST 512
+ #define LPFC_MAX_MRQ_POST 2048
+
++#define LPFC_MAX_NVME_INFO_TMP_LEN 100
++#define LPFC_NVME_INFO_MORE_STR "\nCould be more info...\n"
++
+ /*
+ * Write key size should be multiple of 4. If write key is changed
+ * make sure that library write key is also changed.
+@@ -158,14 +161,15 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
+ char *statep;
+ int i;
+ int len = 0;
++ char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0};
+
+ if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
+- len += snprintf(buf, PAGE_SIZE, "NVME Disabled\n");
++ len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
+ return len;
+ }
+ if (phba->nvmet_support) {
+ if (!phba->targetport) {
+- len = snprintf(buf, PAGE_SIZE,
++ len = scnprintf(buf, PAGE_SIZE,
+ "NVME Target: x%llx is not allocated\n",
+ wwn_to_u64(vport->fc_portname.u.wwn));
+ return len;
+@@ -175,135 +179,169 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
+ statep = "REGISTERED";
+ else
+ statep = "INIT";
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "NVME Target Enabled State %s\n",
+- statep);
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
+- "NVME Target: lpfc",
+- phba->brd_no,
+- wwn_to_u64(vport->fc_portname.u.wwn),
+- wwn_to_u64(vport->fc_nodename.u.wwn),
+- phba->targetport->port_id);
+-
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "\nNVME Target: Statistics\n");
++ scnprintf(tmp, sizeof(tmp),
++ "NVME Target Enabled State %s\n",
++ statep);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
++ "NVME Target: lpfc",
++ phba->brd_no,
++ wwn_to_u64(vport->fc_portname.u.wwn),
++ wwn_to_u64(vport->fc_nodename.u.wwn),
++ phba->targetport->port_id);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ if (strlcat(buf, "\nNVME Target: Statistics\n", PAGE_SIZE)
++ >= PAGE_SIZE)
++ goto buffer_done;
++
+ tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "LS: Rcv %08x Drop %08x Abort %08x\n",
+- atomic_read(&tgtp->rcv_ls_req_in),
+- atomic_read(&tgtp->rcv_ls_req_drop),
+- atomic_read(&tgtp->xmt_ls_abort));
++ scnprintf(tmp, sizeof(tmp),
++ "LS: Rcv %08x Drop %08x Abort %08x\n",
++ atomic_read(&tgtp->rcv_ls_req_in),
++ atomic_read(&tgtp->rcv_ls_req_drop),
++ atomic_read(&tgtp->xmt_ls_abort));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
+ if (atomic_read(&tgtp->rcv_ls_req_in) !=
+ atomic_read(&tgtp->rcv_ls_req_out)) {
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "Rcv LS: in %08x != out %08x\n",
+- atomic_read(&tgtp->rcv_ls_req_in),
+- atomic_read(&tgtp->rcv_ls_req_out));
++ scnprintf(tmp, sizeof(tmp),
++ "Rcv LS: in %08x != out %08x\n",
++ atomic_read(&tgtp->rcv_ls_req_in),
++ atomic_read(&tgtp->rcv_ls_req_out));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+ }
+
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "LS: Xmt %08x Drop %08x Cmpl %08x\n",
+- atomic_read(&tgtp->xmt_ls_rsp),
+- atomic_read(&tgtp->xmt_ls_drop),
+- atomic_read(&tgtp->xmt_ls_rsp_cmpl));
+-
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "LS: RSP Abort %08x xb %08x Err %08x\n",
+- atomic_read(&tgtp->xmt_ls_rsp_aborted),
+- atomic_read(&tgtp->xmt_ls_rsp_xb_set),
+- atomic_read(&tgtp->xmt_ls_rsp_error));
+-
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "FCP: Rcv %08x Defer %08x Release %08x "
+- "Drop %08x\n",
+- atomic_read(&tgtp->rcv_fcp_cmd_in),
+- atomic_read(&tgtp->rcv_fcp_cmd_defer),
+- atomic_read(&tgtp->xmt_fcp_release),
+- atomic_read(&tgtp->rcv_fcp_cmd_drop));
++ scnprintf(tmp, sizeof(tmp),
++ "LS: Xmt %08x Drop %08x Cmpl %08x\n",
++ atomic_read(&tgtp->xmt_ls_rsp),
++ atomic_read(&tgtp->xmt_ls_drop),
++ atomic_read(&tgtp->xmt_ls_rsp_cmpl));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "LS: RSP Abort %08x xb %08x Err %08x\n",
++ atomic_read(&tgtp->xmt_ls_rsp_aborted),
++ atomic_read(&tgtp->xmt_ls_rsp_xb_set),
++ atomic_read(&tgtp->xmt_ls_rsp_error));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "FCP: Rcv %08x Defer %08x Release %08x "
++ "Drop %08x\n",
++ atomic_read(&tgtp->rcv_fcp_cmd_in),
++ atomic_read(&tgtp->rcv_fcp_cmd_defer),
++ atomic_read(&tgtp->xmt_fcp_release),
++ atomic_read(&tgtp->rcv_fcp_cmd_drop));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+
+ if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
+ atomic_read(&tgtp->rcv_fcp_cmd_out)) {
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "Rcv FCP: in %08x != out %08x\n",
+- atomic_read(&tgtp->rcv_fcp_cmd_in),
+- atomic_read(&tgtp->rcv_fcp_cmd_out));
++ scnprintf(tmp, sizeof(tmp),
++ "Rcv FCP: in %08x != out %08x\n",
++ atomic_read(&tgtp->rcv_fcp_cmd_in),
++ atomic_read(&tgtp->rcv_fcp_cmd_out));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+ }
+
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
+- "drop %08x\n",
+- atomic_read(&tgtp->xmt_fcp_read),
+- atomic_read(&tgtp->xmt_fcp_read_rsp),
+- atomic_read(&tgtp->xmt_fcp_write),
+- atomic_read(&tgtp->xmt_fcp_rsp),
+- atomic_read(&tgtp->xmt_fcp_drop));
+-
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
+- atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
+- atomic_read(&tgtp->xmt_fcp_rsp_error),
+- atomic_read(&tgtp->xmt_fcp_rsp_drop));
+-
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
+- atomic_read(&tgtp->xmt_fcp_rsp_aborted),
+- atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
+- atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
+-
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "ABORT: Xmt %08x Cmpl %08x\n",
+- atomic_read(&tgtp->xmt_fcp_abort),
+- atomic_read(&tgtp->xmt_fcp_abort_cmpl));
+-
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x",
+- atomic_read(&tgtp->xmt_abort_sol),
+- atomic_read(&tgtp->xmt_abort_unsol),
+- atomic_read(&tgtp->xmt_abort_rsp),
+- atomic_read(&tgtp->xmt_abort_rsp_error));
+-
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "DELAY: ctx %08x fod %08x wqfull %08x\n",
+- atomic_read(&tgtp->defer_ctx),
+- atomic_read(&tgtp->defer_fod),
+- atomic_read(&tgtp->defer_wqfull));
++ scnprintf(tmp, sizeof(tmp),
++ "FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
++ "drop %08x\n",
++ atomic_read(&tgtp->xmt_fcp_read),
++ atomic_read(&tgtp->xmt_fcp_read_rsp),
++ atomic_read(&tgtp->xmt_fcp_write),
++ atomic_read(&tgtp->xmt_fcp_rsp),
++ atomic_read(&tgtp->xmt_fcp_drop));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
++ atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
++ atomic_read(&tgtp->xmt_fcp_rsp_error),
++ atomic_read(&tgtp->xmt_fcp_rsp_drop));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
++ atomic_read(&tgtp->xmt_fcp_rsp_aborted),
++ atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
++ atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "ABORT: Xmt %08x Cmpl %08x\n",
++ atomic_read(&tgtp->xmt_fcp_abort),
++ atomic_read(&tgtp->xmt_fcp_abort_cmpl));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
++ atomic_read(&tgtp->xmt_abort_sol),
++ atomic_read(&tgtp->xmt_abort_unsol),
++ atomic_read(&tgtp->xmt_abort_rsp),
++ atomic_read(&tgtp->xmt_abort_rsp_error));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "DELAY: ctx %08x fod %08x wqfull %08x\n",
++ atomic_read(&tgtp->defer_ctx),
++ atomic_read(&tgtp->defer_fod),
++ atomic_read(&tgtp->defer_wqfull));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+
+ /* Calculate outstanding IOs */
+ tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
+ tot += atomic_read(&tgtp->xmt_fcp_release);
+ tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
+
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
+- "CTX Outstanding %08llx\n",
+- phba->sli4_hba.nvmet_xri_cnt,
+- phba->sli4_hba.nvmet_io_wait_cnt,
+- phba->sli4_hba.nvmet_io_wait_total,
+- tot);
+-
+- len += snprintf(buf+len, PAGE_SIZE-len, "\n");
+- return len;
++ scnprintf(tmp, sizeof(tmp),
++ "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
++ "CTX Outstanding %08llx\n\n",
++ phba->sli4_hba.nvmet_xri_cnt,
++ phba->sli4_hba.nvmet_io_wait_cnt,
++ phba->sli4_hba.nvmet_io_wait_total,
++ tot);
++ strlcat(buf, tmp, PAGE_SIZE);
++ goto buffer_done;
+ }
+
+ localport = vport->localport;
+ if (!localport) {
+- len = snprintf(buf, PAGE_SIZE,
++ len = scnprintf(buf, PAGE_SIZE,
+ "NVME Initiator x%llx is not allocated\n",
+ wwn_to_u64(vport->fc_portname.u.wwn));
+ return len;
+ }
+ lport = (struct lpfc_nvme_lport *)localport->private;
+- len = snprintf(buf, PAGE_SIZE, "NVME Initiator Enabled\n");
+-
+- spin_lock_irq(shost->host_lock);
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "XRI Dist lpfc%d Total %d NVME %d SCSI %d ELS %d\n",
+- phba->brd_no,
+- phba->sli4_hba.max_cfg_param.max_xri,
+- phba->sli4_hba.nvme_xri_max,
+- phba->sli4_hba.scsi_xri_max,
+- lpfc_sli4_get_els_iocb_cnt(phba));
++ if (strlcat(buf, "\nNVME Initiator Enabled\n", PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ rcu_read_lock();
++ scnprintf(tmp, sizeof(tmp),
++ "XRI Dist lpfc%d Total %d NVME %d SCSI %d ELS %d\n",
++ phba->brd_no,
++ phba->sli4_hba.max_cfg_param.max_xri,
++ phba->sli4_hba.nvme_xri_max,
++ phba->sli4_hba.scsi_xri_max,
++ lpfc_sli4_get_els_iocb_cnt(phba));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+
+ /* Port state is only one of two values for now. */
+ if (localport->port_id)
+@@ -311,13 +349,15 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
+ else
+ statep = "UNKNOWN ";
+
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
+- "NVME LPORT lpfc",
+- phba->brd_no,
+- wwn_to_u64(vport->fc_portname.u.wwn),
+- wwn_to_u64(vport->fc_nodename.u.wwn),
+- localport->port_id, statep);
++ scnprintf(tmp, sizeof(tmp),
++ "%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
++ "NVME LPORT lpfc",
++ phba->brd_no,
++ wwn_to_u64(vport->fc_portname.u.wwn),
++ wwn_to_u64(vport->fc_nodename.u.wwn),
++ localport->port_id, statep);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+
+ list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+ rport = lpfc_ndlp_get_nrport(ndlp);
+@@ -343,56 +383,77 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
+ }
+
+ /* Tab in to show lport ownership. */
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "NVME RPORT ");
+- if (phba->brd_no >= 10)
+- len += snprintf(buf + len, PAGE_SIZE - len, " ");
+-
+- len += snprintf(buf + len, PAGE_SIZE - len, "WWPN x%llx ",
+- nrport->port_name);
+- len += snprintf(buf + len, PAGE_SIZE - len, "WWNN x%llx ",
+- nrport->node_name);
+- len += snprintf(buf + len, PAGE_SIZE - len, "DID x%06x ",
+- nrport->port_id);
++ if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++ if (phba->brd_no >= 10) {
++ if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++ }
++
++ scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
++ nrport->port_name);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
++ nrport->node_name);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp), "DID x%06x ",
++ nrport->port_id);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+
+ /* An NVME rport can have multiple roles. */
+- if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR)
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "INITIATOR ");
+- if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET)
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "TARGET ");
+- if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY)
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "DISCSRVC ");
++ if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
++ if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++ }
++ if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
++ if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++ }
++ if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
++ if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++ }
+ if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
+ FC_PORT_ROLE_NVME_TARGET |
+- FC_PORT_ROLE_NVME_DISCOVERY))
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "UNKNOWN ROLE x%x",
+- nrport->port_role);
+-
+- len += snprintf(buf + len, PAGE_SIZE - len, "%s ", statep);
+- /* Terminate the string. */
+- len += snprintf(buf + len, PAGE_SIZE - len, "\n");
++ FC_PORT_ROLE_NVME_DISCOVERY)) {
++ scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
++ nrport->port_role);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++ }
++
++ scnprintf(tmp, sizeof(tmp), "%s\n", statep);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+ }
+- spin_unlock_irq(shost->host_lock);
++ rcu_read_unlock();
+
+ if (!lport)
+- return len;
+-
+- len += snprintf(buf + len, PAGE_SIZE - len, "\nNVME Statistics\n");
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "LS: Xmt %010x Cmpl %010x Abort %08x\n",
+- atomic_read(&lport->fc4NvmeLsRequests),
+- atomic_read(&lport->fc4NvmeLsCmpls),
+- atomic_read(&lport->xmt_ls_abort));
+-
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
+- atomic_read(&lport->xmt_ls_err),
+- atomic_read(&lport->cmpl_ls_xb),
+- atomic_read(&lport->cmpl_ls_err));
++ goto buffer_done;
++
++ if (strlcat(buf, "\nNVME Statistics\n", PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "LS: Xmt %010x Cmpl %010x Abort %08x\n",
++ atomic_read(&lport->fc4NvmeLsRequests),
++ atomic_read(&lport->fc4NvmeLsCmpls),
++ atomic_read(&lport->xmt_ls_abort));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
++ atomic_read(&lport->xmt_ls_err),
++ atomic_read(&lport->cmpl_ls_xb),
++ atomic_read(&lport->cmpl_ls_err));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
+
+ totin = 0;
+ totout = 0;
+@@ -405,25 +466,46 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
+ data3 = atomic_read(&cstat->fc4NvmeControlRequests);
+ totout += (data1 + data2 + data3);
+ }
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- "Total FCP Cmpl %016llx Issue %016llx "
+- "OutIO %016llx\n",
+- totin, totout, totout - totin);
+-
+- len += snprintf(buf+len, PAGE_SIZE-len,
+- " abort %08x noxri %08x nondlp %08x qdepth %08x "
+- "wqerr %08x err %08x\n",
+- atomic_read(&lport->xmt_fcp_abort),
+- atomic_read(&lport->xmt_fcp_noxri),
+- atomic_read(&lport->xmt_fcp_bad_ndlp),
+- atomic_read(&lport->xmt_fcp_qdepth),
+- atomic_read(&lport->xmt_fcp_err),
+- atomic_read(&lport->xmt_fcp_wqerr));
+-
+- len += snprintf(buf + len, PAGE_SIZE - len,
+- "FCP CMPL: xb %08x Err %08x\n",
+- atomic_read(&lport->cmpl_fcp_xb),
+- atomic_read(&lport->cmpl_fcp_err));
++ scnprintf(tmp, sizeof(tmp),
++ "Total FCP Cmpl %016llx Issue %016llx "
++ "OutIO %016llx\n",
++ totin, totout, totout - totin);
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "\tabort %08x noxri %08x nondlp %08x qdepth %08x "
++ "wqerr %08x err %08x\n",
++ atomic_read(&lport->xmt_fcp_abort),
++ atomic_read(&lport->xmt_fcp_noxri),
++ atomic_read(&lport->xmt_fcp_bad_ndlp),
++ atomic_read(&lport->xmt_fcp_qdepth),
++ atomic_read(&lport->xmt_fcp_err),
++ atomic_read(&lport->xmt_fcp_wqerr));
++ if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp),
++ "FCP CMPL: xb %08x Err %08x\n",
++ atomic_read(&lport->cmpl_fcp_xb),
++ atomic_read(&lport->cmpl_fcp_err));
++ strlcat(buf, tmp, PAGE_SIZE);
++
++buffer_done:
++ len = strnlen(buf, PAGE_SIZE);
++
++ if (unlikely(len >= (PAGE_SIZE - 1))) {
++ lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
++ "6314 Catching potential buffer "
++ "overflow > PAGE_SIZE = %lu bytes\n",
++ PAGE_SIZE);
++ strlcpy(buf + PAGE_SIZE - 1 -
++ strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1),
++ LPFC_NVME_INFO_MORE_STR,
++ strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1)
++ + 1);
++ }
++
+ return len;
+ }
+
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Correct-LCB-ACCept-payload.patch b/patches.drivers/scsi-lpfc-Correct-LCB-ACCept-payload.patch
new file mode 100644
index 0000000000..2dcddc5f0a
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Correct-LCB-ACCept-payload.patch
@@ -0,0 +1,46 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 31 Jul 2018 17:23:23 -0700
+Subject: [PATCH] scsi: lpfc: Correct LCB ACCept payload
+References: bsc#1102658
+Git-commit: 24bc3119424ac163c2f67e072c956f50e153d034
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+
+After memory allocation for the LCB response frame, the memory wasn't zero
+initialized, and not all fields are set. Thus garbage shows up in the
+payload.
+
+Fix by zeroing the memory at allocation. Also properly set the Capability
+field based on duration support.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_els.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index df655f1284d0..4dda969e947c 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -5662,6 +5662,7 @@ lpfc_els_lcb_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+ lcb_res = (struct fc_lcb_res_frame *)
+ (((struct lpfc_dmabuf *)elsiocb->context2)->virt);
+
++ memset(lcb_res, 0, sizeof(struct fc_lcb_res_frame));
+ icmd = &elsiocb->iocb;
+ icmd->ulpContext = lcb_context->rx_id;
+ icmd->unsli3.rcvsli3.ox_id = lcb_context->ox_id;
+@@ -5670,6 +5671,7 @@ lpfc_els_lcb_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+ *((uint32_t *)(pcmd)) = ELS_CMD_ACC;
+ lcb_res->lcb_sub_command = lcb_context->sub_command;
+ lcb_res->lcb_type = lcb_context->type;
++ lcb_res->capability = lcb_context->capability;
+ lcb_res->lcb_frequency = lcb_context->frequency;
+ lcb_res->lcb_duration = lcb_context->duration;
+ elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-ELS-abort-on-SLI-3-adapters.patch b/patches.drivers/scsi-lpfc-Fix-ELS-abort-on-SLI-3-adapters.patch
new file mode 100644
index 0000000000..b3eb9f9c4d
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-ELS-abort-on-SLI-3-adapters.patch
@@ -0,0 +1,89 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 31 Jul 2018 17:23:18 -0700
+Subject: [PATCH] scsi: lpfc: Fix ELS abort on SLI-3 adapters
+References: bsc#1102658
+Git-commit: faa832e97a0c0d79838c3a6521a473d870217053
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+
+For ABORT_XRI_CN command, firmware identifies XRI to abort by IOTAG and RPI
+combination. For ELS aborts, driver specifies IOTAG correctly but RPI is
+not specified.
+
+Fix by setting RPI in WQE.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_nportdisc.c | 3 +++
+ drivers/scsi/lpfc/lpfc_sli.c | 16 ++++++++++++++--
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
+index 1f0a7d7dbc54..843e765db86d 100644
+--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
+@@ -1062,6 +1062,9 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ {
+ struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
+
++ /* Retrieve RPI from LOGO IOCB. RPI is used for CMD_ABORT_XRI_CN */
++ if (vport->phba->sli_rev == LPFC_SLI_REV3)
++ ndlp->nlp_rpi = cmdiocb->iocb.ulpIoTag;
+ /* software abort outstanding PLOGI */
+ lpfc_els_abort(vport->phba, ndlp);
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 72500dcb13a9..9830bdb6e072 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -10703,6 +10703,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+
+ spin_lock_irq(&phba->hbalock);
+ if (phba->sli_rev < LPFC_SLI_REV4) {
++ if (irsp->ulpCommand == CMD_ABORT_XRI_CX &&
++ irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
++ irsp->un.ulpWord[4] == IOERR_ABORT_REQUESTED) {
++ spin_unlock_irq(&phba->hbalock);
++ goto release_iocb;
++ }
+ if (abort_iotag != 0 &&
+ abort_iotag <= phba->sli.last_iotag)
+ abort_iocb =
+@@ -10724,6 +10730,7 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+
+ spin_unlock_irq(&phba->hbalock);
+ }
++release_iocb:
+ lpfc_sli_release_iocbq(phba, cmdiocb);
+ return;
+ }
+@@ -10780,6 +10787,7 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+ IOCB_t *iabt = NULL;
+ int retval;
+ unsigned long iflags;
++ struct lpfc_nodelist *ndlp;
+
+ lockdep_assert_held(&phba->hbalock);
+
+@@ -10810,9 +10818,13 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ iabt->un.acxri.abortIoTag = cmdiocb->sli4_xritag;
+ iabt->un.acxri.abortContextTag = cmdiocb->iotag;
+- }
+- else
++ } else {
+ iabt->un.acxri.abortIoTag = icmd->ulpIoTag;
++ if (pring->ringno == LPFC_ELS_RING) {
++ ndlp = (struct lpfc_nodelist *)(cmdiocb->context1);
++ iabt->un.acxri.abortContextTag = ndlp->nlp_rpi;
++ }
++ }
+ iabt->ulpLe = 1;
+ iabt->ulpClass = icmd->ulpClass;
+
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-NVME-Target-crash-in-defer-rcv-logic.patch b/patches.drivers/scsi-lpfc-Fix-NVME-Target-crash-in-defer-rcv-logic.patch
new file mode 100644
index 0000000000..184bb0f43e
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-NVME-Target-crash-in-defer-rcv-logic.patch
@@ -0,0 +1,61 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 26 Jun 2018 08:24:28 -0700
+Subject: [PATCH] scsi: lpfc: Fix NVME Target crash in defer rcv logic
+References: bsc#1102658
+Git-commit: 6871e8144f935a1f08e7fc6269c894861ce494aa
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+Patch-mainline: Queued in subsystem maintainer repository
+
+Kernel occasionally crashed with the following
+ops on NVME Target:
+ BUG: unable to handle kernel NULL pointer dereference at 0000000000000058
+ IP: [<ffffffffa042ee50>] lpfc_nvmet_defer_rcv+0x50/0x70 [lpfc]
+
+Callback routine was called for deferred rcv when it should be treated as a
+normal rcv.
+
+Added code in callback routine to detect this condition and log a message,
+then bail.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_nvmet.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
+index ccb35efef1e1..ff994712f58a 100644
+--- a/drivers/scsi/lpfc/lpfc_nvmet.c
++++ b/drivers/scsi/lpfc/lpfc_nvmet.c
+@@ -402,6 +402,7 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf)
+
+ /* Process FCP command */
+ if (rc == 0) {
++ ctxp->rqb_buffer = NULL;
+ atomic_inc(&tgtp->rcv_fcp_cmd_out);
+ nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
+ return;
+@@ -1116,8 +1117,17 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
+ lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n",
+ ctxp->oxid, ctxp->size, smp_processor_id());
+
++ if (!nvmebuf) {
++ lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
++ "6425 Defer rcv: no buffer xri x%x: "
++ "flg %x ste %x\n",
++ ctxp->oxid, ctxp->flag, ctxp->state);
++ return;
++ }
++
+ tgtp = phba->targetport->private;
+- atomic_inc(&tgtp->rcv_fcp_cmd_defer);
++ if (tgtp)
++ atomic_inc(&tgtp->rcv_fcp_cmd_defer);
+
+ /* Free the nvmebuf since a new buffer already replaced it */
+ nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-abort-error-path-for-NVMET.patch b/patches.drivers/scsi-lpfc-Fix-abort-error-path-for-NVMET.patch
new file mode 100644
index 0000000000..5376f7645c
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-abort-error-path-for-NVMET.patch
@@ -0,0 +1,94 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 26 Jun 2018 08:24:25 -0700
+Subject: [PATCH] scsi: lpfc: Fix abort error path for NVMET
+References: bsc#1102658
+Git-commit: 68c9b55deea51151d9da3d45ecc9a5ef72f9dfb1
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+Patch-mainline: Queued in subsystem maintainer repository
+
+rmmod of driver hangs
+
+As driver instances were being unloaded, the NVME target port was unloaded
+first. During the unload, the NVME initiator port sent a heartbeat
+IO. Because of the target port state, that IO was scheduled for an Abort;
+however, that abort subsequently failed. The failure was not cleaned up
+properly and lpfc_sli4_xri_exchange_busy_wait silently hung forever.
+
+Clean failed abort properly and make lpfc_sli4_xri_exchange_busy_wait not
+hangs silently while waiting for aborts to complete.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_init.c | 5 +++++
+ drivers/scsi/lpfc/lpfc_nvmet.c | 15 +++++++++++----
+ 2 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 1f2d8a29b075..64ccfe735252 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -10393,6 +10393,11 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
+ while (!fcp_xri_cmpl || !els_xri_cmpl || !nvme_xri_cmpl ||
+ !nvmet_xri_cmpl) {
+ if (wait_time > LPFC_XRI_EXCH_BUSY_WAIT_TMO) {
++ if (!nvmet_xri_cmpl)
++ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
++ "6424 NVMET XRI exchange busy "
++ "wait time: %d seconds.\n",
++ wait_time/1000);
+ if (!nvme_xri_cmpl)
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "6100 NVME XRI exchange busy "
+diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
+index 7271c9d885dd..102c970a00e6 100644
+--- a/drivers/scsi/lpfc/lpfc_nvmet.c
++++ b/drivers/scsi/lpfc/lpfc_nvmet.c
+@@ -1732,9 +1732,12 @@ lpfc_nvmet_unsol_ls_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+ uint32_t *payload;
+ uint32_t size, oxid, sid, rc;
+
++ fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt);
++ oxid = be16_to_cpu(fc_hdr->fh_ox_id);
++
+ if (!nvmebuf || !phba->targetport) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
+- "6154 LS Drop IO\n");
++ "6154 LS Drop IO x%x\n", oxid);
+ oxid = 0;
+ size = 0;
+ sid = 0;
+@@ -1744,9 +1747,7 @@ lpfc_nvmet_unsol_ls_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+
+ tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
+ payload = (uint32_t *)(nvmebuf->dbuf.virt);
+- fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt);
+ size = bf_get(lpfc_rcqe_length, &nvmebuf->cq_event.cqe.rcqe_cmpl);
+- oxid = be16_to_cpu(fc_hdr->fh_ox_id);
+ sid = sli4_sid_from_fc_hdr(fc_hdr);
+
+ ctxp = kzalloc(sizeof(struct lpfc_nvmet_rcv_ctx), GFP_ATOMIC);
+@@ -3105,11 +3106,17 @@ lpfc_nvmet_unsol_fcp_issue_abort(struct lpfc_hba *phba,
+ }
+
+ aerr:
+- ctxp->flag &= ~LPFC_NVMET_ABORT_OP;
++ spin_lock_irqsave(&ctxp->ctxlock, flags);
++ if (ctxp->flag & LPFC_NVMET_CTX_RLS)
++ list_del(&ctxp->list);
++ ctxp->flag &= ~(LPFC_NVMET_ABORT_OP | LPFC_NVMET_CTX_RLS);
++ spin_unlock_irqrestore(&ctxp->ctxlock, flags);
++
+ atomic_inc(&tgtp->xmt_abort_rsp_error);
+ lpfc_printf_log(phba, KERN_ERR, LOG_NVME_ABTS,
+ "6135 Failed to Issue ABTS for oxid x%x. Status x%x\n",
+ ctxp->oxid, rc);
++ lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf);
+ return 1;
+ }
+
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-driver-crash-when-re-registering-NVME-.patch b/patches.drivers/scsi-lpfc-Fix-driver-crash-when-re-registering-NVME-.patch
new file mode 100644
index 0000000000..672841eede
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-driver-crash-when-re-registering-NVME-.patch
@@ -0,0 +1,109 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 31 Jul 2018 17:23:21 -0700
+Subject: [PATCH] scsi: lpfc: Fix driver crash when re-registering NVME rports.
+References: bsc#1102658
+Git-commit: 93a3922da428ec0752e8b2ab00c42dadbbf805a9
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+
+During remote port loss fault testing, the driver crashed with the
+following trace:
+
+general protection fault: 0000 [#1] SMP
+RIP: ... lpfc_nvme_register_port+0x250/0x480 [lpfc]
+Call Trace:
+ lpfc_nlp_state_cleanup+0x1b3/0x7a0 [lpfc]
+ lpfc_nlp_set_state+0xa6/0x1d0 [lpfc]
+ lpfc_cmpl_prli_prli_issue+0x213/0x440
+ lpfc_disc_state_machine+0x7e/0x1e0 [lpfc]
+ lpfc_cmpl_els_prli+0x18a/0x200 [lpfc]
+ lpfc_sli_sp_handle_rspiocb+0x3b5/0x6f0 [lpfc]
+ lpfc_sli_handle_slow_ring_event_s4+0x161/0x240 [lpfc]
+ lpfc_work_done+0x948/0x14c0 [lpfc]
+ lpfc_do_work+0x16f/0x180 [lpfc]
+ kthread+0xc9/0xe0
+ ret_from_fork+0x55/0x80
+
+After registering a new remoteport, the driver is pulling an ndlp pointer
+from the lpfc rport associated with the private area of a newly registered
+remoteport. The private area is uninitialized, so it's garbage.
+
+Correct by pulling the the lpfc rport pointer from the entering ndlp point,
+then ndlp value from at rport. Note the entering ndlp may be replacing by
+the rport->ndlp due to an address change swap.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_nvme.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
+index 4cc6783b6a9f..32053424d546 100644
+--- a/drivers/scsi/lpfc/lpfc_nvme.c
++++ b/drivers/scsi/lpfc/lpfc_nvme.c
+@@ -2687,7 +2687,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
+ struct lpfc_nvme_rport *oldrport;
+ struct nvme_fc_remote_port *remote_port;
+ struct nvme_fc_port_info rpinfo;
+- struct lpfc_nodelist *prev_ndlp;
++ struct lpfc_nodelist *prev_ndlp = NULL;
+
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NVME_DISC,
+ "6006 Register NVME PORT. DID x%06x nlptype x%x\n",
+@@ -2736,23 +2736,29 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
+ spin_unlock_irq(&vport->phba->hbalock);
+ rport = remote_port->private;
+ if (oldrport) {
++ /* New remoteport record does not guarantee valid
++ * host private memory area.
++ */
++ prev_ndlp = oldrport->ndlp;
+ if (oldrport == remote_port->private) {
+- /* Same remoteport. Just reuse. */
++ /* Same remoteport - ndlp should match.
++ * Just reuse.
++ */
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO,
+ LOG_NVME_DISC,
+ "6014 Rebinding lport to "
+ "remoteport %p wwpn 0x%llx, "
+- "Data: x%x x%x %p x%x x%06x\n",
++ "Data: x%x x%x %p %p x%x x%06x\n",
+ remote_port,
+ remote_port->port_name,
+ remote_port->port_id,
+ remote_port->port_role,
++ prev_ndlp,
+ ndlp,
+ ndlp->nlp_type,
+ ndlp->nlp_DID);
+ return 0;
+ }
+- prev_ndlp = rport->ndlp;
+
+ /* Sever the ndlp<->rport association
+ * before dropping the ndlp ref from
+@@ -2786,13 +2792,13 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
+ lpfc_printf_vlog(vport, KERN_INFO,
+ LOG_NVME_DISC | LOG_NODE,
+ "6022 Binding new rport to "
+- "lport %p Remoteport %p WWNN 0x%llx, "
++ "lport %p Remoteport %p rport %p WWNN 0x%llx, "
+ "Rport WWPN 0x%llx DID "
+- "x%06x Role x%x, ndlp %p\n",
+- lport, remote_port,
++ "x%06x Role x%x, ndlp %p prev_ndlp %p\n",
++ lport, remote_port, rport,
+ rpinfo.node_name, rpinfo.port_name,
+ rpinfo.port_id, rpinfo.port_role,
+- ndlp);
++ ndlp, prev_ndlp);
+ } else {
+ lpfc_printf_vlog(vport, KERN_ERR,
+ LOG_NVME_DISC | LOG_NODE,
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-driver-not-setting-dpp-bits-correctly-.patch b/patches.drivers/scsi-lpfc-Fix-driver-not-setting-dpp-bits-correctly-.patch
new file mode 100644
index 0000000000..2f0895c61d
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-driver-not-setting-dpp-bits-correctly-.patch
@@ -0,0 +1,54 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 26 Jun 2018 08:24:23 -0700
+Subject: [PATCH] scsi: lpfc: Fix driver not setting dpp bits correctly in
+ doorbell word
+References: bsc#1102658
+Git-commit: 5cc167ddb7441013e2b5a5f47bf11af0264bb3e8
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+Patch-mainline: Queued in subsystem maintainer repository
+
+Driver is incorrectly formatting a register on new hardware, using a format
+for an older chip. This can result in non-deterministic behavior.
+
+Ensure driver is not setting "workqueue index" in the WQ doorbell when
+making a non-dpp doorbell write. The field must be zero when non-dpp.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_sli.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index d4510e64856a..a25e38ac64e3 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -145,6 +145,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 *wqe)
+ uint32_t idx;
+ uint32_t i = 0;
+ uint8_t *tmp;
++ u32 if_type;
+
+ /* sanity check on queue memory */
+ if (unlikely(!q))
+@@ -199,8 +200,14 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 *wqe)
+ q->queue_id);
+ } else {
+ bf_set(lpfc_wq_db_list_fm_num_posted, &doorbell, 1);
+- bf_set(lpfc_wq_db_list_fm_index, &doorbell, host_index);
+ bf_set(lpfc_wq_db_list_fm_id, &doorbell, q->queue_id);
++
++ /* Leave bits <23:16> clear for if_type 6 dpp */
++ if_type = bf_get(lpfc_sli_intf_if_type,
++ &q->phba->sli4_hba.sli_intf);
++ if (if_type != LPFC_SLI_INTF_IF_TYPE_6)
++ bf_set(lpfc_wq_db_list_fm_index, &doorbell,
++ host_index);
+ }
+ } else if (q->db_format == LPFC_DB_RING_FORMAT) {
+ bf_set(lpfc_wq_db_ring_fm_num_posted, &doorbell, 1);
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-list-corruption-on-the-completion-queu.patch b/patches.drivers/scsi-lpfc-Fix-list-corruption-on-the-completion-queu.patch
new file mode 100644
index 0000000000..cfa32d11c2
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-list-corruption-on-the-completion-queu.patch
@@ -0,0 +1,143 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 31 Jul 2018 17:23:20 -0700
+Subject: [PATCH] scsi: lpfc: Fix list corruption on the completion queue.
+References: bsc#1102658
+Git-commit: 8931c73bee077f5bc5710afebc0136363970cb2b
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+
+Enabling list_debug showed the drivers txcmplq was suffering list
+corruption. The systems will eventually crash because the iocb free list
+gets crossed linked with the prings txcmplq. Most systems will run for a
+while after the corruption, but will eventually crash when a scsi eh reset
+occurs and the txcmplq is attempted to be flushed. The flush gets stuck in
+an endless loop.
+
+The problem is the abort handler does not hold the sli4 ring lock while
+validating the IO so the IO could complete while the driver is still
+preping the abort. The erroneously generated abort, when it completes, has
+pointers to the original IO that has already completed, and the IO
+manipulation (for the second time) corrupts the list.
+
+Correct by taking the ring lock early in the abort handler so the erroneous
+abort won't be sent if the io has/is completing.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_scsi.c | 44 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 36 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
+index 25ef2b6ccc34..51ce244cf10a 100644
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -4727,7 +4727,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+ struct lpfc_scsi_buf *lpfc_cmd;
+ IOCB_t *cmd, *icmd;
+ int ret = SUCCESS, status = 0;
+- struct lpfc_sli_ring *pring_s4;
++ struct lpfc_sli_ring *pring_s4 = NULL;
+ int ret_val;
+ unsigned long flags;
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
+@@ -4757,8 +4757,25 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+ }
+
+ iocb = &lpfc_cmd->cur_iocbq;
++ if (phba->sli_rev == LPFC_SLI_REV4) {
++ if (!(phba->cfg_fof) ||
++ (!(iocb->iocb_flag & LPFC_IO_FOF))) {
++ pring_s4 =
++ phba->sli4_hba.fcp_wq[iocb->hba_wqidx]->pring;
++ } else {
++ iocb->hba_wqidx = 0;
++ pring_s4 = phba->sli4_hba.oas_wq->pring;
++ }
++ if (!pring_s4) {
++ ret = FAILED;
++ goto out_unlock;
++ }
++ spin_lock(&pring_s4->ring_lock);
++ }
+ /* the command is in process of being cancelled */
+ if (!(iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ)) {
++ if (phba->sli_rev == LPFC_SLI_REV4)
++ spin_unlock(&pring_s4->ring_lock);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "3169 SCSI Layer abort requested I/O has been "
+@@ -4772,6 +4789,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+ * see the completion before the eh fired. Just return SUCCESS.
+ */
+ if (lpfc_cmd->pCmd != cmnd) {
++ if (phba->sli_rev == LPFC_SLI_REV4)
++ spin_unlock(&pring_s4->ring_lock);
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "3170 SCSI Layer abort requested I/O has been "
+ "completed by LLD.\n");
+@@ -4784,6 +4803,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+ if (iocb->iocb_flag & LPFC_DRIVER_ABORTED) {
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "3389 SCSI Layer I/O Abort Request is pending\n");
++ if (phba->sli_rev == LPFC_SLI_REV4)
++ spin_unlock(&pring_s4->ring_lock);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+ goto wait_for_cmpl;
+ }
+@@ -4791,6 +4812,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+ abtsiocb = __lpfc_sli_get_iocbq(phba);
+ if (abtsiocb == NULL) {
+ ret = FAILED;
++ if (phba->sli_rev == LPFC_SLI_REV4)
++ spin_unlock(&pring_s4->ring_lock);
+ goto out_unlock;
+ }
+
+@@ -4828,14 +4851,9 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+
+ abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
+ abtsiocb->vport = vport;
++ lpfc_cmd->waitq = &waitq;
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+- pring_s4 = lpfc_sli4_calc_ring(phba, abtsiocb);
+- if (pring_s4 == NULL) {
+- ret = FAILED;
+- goto out_unlock;
+- }
+ /* Note: both hbalock and ring_lock must be set here */
+- spin_lock(&pring_s4->ring_lock);
+ ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno,
+ abtsiocb, 0);
+ spin_unlock(&pring_s4->ring_lock);
+@@ -4848,6 +4866,17 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+
+
+ if (ret_val == IOCB_ERROR) {
++ if (phba->sli_rev == LPFC_SLI_REV4)
++ spin_lock_irqsave(&pring_s4->ring_lock, flags);
++ else
++ spin_lock_irqsave(&phba->hbalock, flags);
++ /* Indicate the IO is not being aborted by the driver. */
++ iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED;
++ lpfc_cmd->waitq = NULL;
++ if (phba->sli_rev == LPFC_SLI_REV4)
++ spin_unlock_irqrestore(&pring_s4->ring_lock, flags);
++ else
++ spin_unlock_irqrestore(&phba->hbalock, flags);
+ lpfc_sli_release_iocbq(phba, abtsiocb);
+ ret = FAILED;
+ goto out;
+@@ -4858,7 +4887,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+ &phba->sli.sli3_ring[LPFC_FCP_RING], HA_R0RE_REQ);
+
+ wait_for_cmpl:
+- lpfc_cmd->waitq = &waitq;
+ /* Wait for abort to complete */
+ wait_event_timeout(waitq,
+ (lpfc_cmd->pCmd != cmnd),
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-panic-if-driver-unloaded-when-port-is-.patch b/patches.drivers/scsi-lpfc-Fix-panic-if-driver-unloaded-when-port-is-.patch
new file mode 100644
index 0000000000..eee87b09bd
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-panic-if-driver-unloaded-when-port-is-.patch
@@ -0,0 +1,50 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 26 Jun 2018 08:24:24 -0700
+Subject: [PATCH] scsi: lpfc: Fix panic if driver unloaded when port is offline
+References: bsc#1102658
+Git-commit: d580c6137476ab307a66e278cf7dbc666230f714
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+Patch-mainline: Queued in subsystem maintainer repository
+
+System crashes when the lpfc module is unloaded after making the port
+offline
+
+The nvme queue pointers were freed during port offline, but were later
+accessed in pci remove path.
+
+Validate the pointers in pci remove path before accessing them.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_nvme.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
+index 76a5a99605aa..ada5a2aaee82 100644
+--- a/drivers/scsi/lpfc/lpfc_nvme.c
++++ b/drivers/scsi/lpfc/lpfc_nvme.c
+@@ -2970,7 +2970,7 @@ lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba)
+ struct lpfc_sli_ring *pring;
+ u32 i, wait_cnt = 0;
+
+- if (phba->sli_rev < LPFC_SLI_REV4)
++ if (phba->sli_rev < LPFC_SLI_REV4 || !phba->sli4_hba.nvme_wq)
+ return;
+
+ /* Cycle through all NVME rings and make sure all outstanding
+@@ -2979,6 +2979,9 @@ lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba)
+ for (i = 0; i < phba->cfg_nvme_io_channel; i++) {
+ pring = phba->sli4_hba.nvme_wq[i]->pring;
+
++ if (!pring)
++ continue;
++
+ /* Retrieve everything on the txcmplq */
+ while (!list_empty(&pring->txcmplq)) {
+ msleep(LPFC_XRI_EXCH_BUSY_WAIT_T1);
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Fix-sysfs-Speed-value-on-CNA-ports.patch b/patches.drivers/scsi-lpfc-Fix-sysfs-Speed-value-on-CNA-ports.patch
new file mode 100644
index 0000000000..7c3c763e31
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Fix-sysfs-Speed-value-on-CNA-ports.patch
@@ -0,0 +1,52 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 31 Jul 2018 17:23:19 -0700
+Subject: [PATCH] scsi: lpfc: Fix sysfs Speed value on CNA ports
+References: bsc#1102658
+Git-commit: b615a20adf04cf3c8e9293851da3aac54792fb07
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+
+CNA ports were showing speed as "unknown" even if the link is up.
+
+Add speed decoding for FCOE-based adapters.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_attr.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
+index 23a5a298d60e..514513f837a8 100644
+--- a/drivers/scsi/lpfc/lpfc_attr.c
++++ b/drivers/scsi/lpfc/lpfc_attr.c
+@@ -5927,6 +5927,24 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
+ fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+ break;
+ }
++ } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
++ switch (phba->fc_linkspeed) {
++ case LPFC_ASYNC_LINK_SPEED_10GBPS:
++ fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
++ break;
++ case LPFC_ASYNC_LINK_SPEED_25GBPS:
++ fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
++ break;
++ case LPFC_ASYNC_LINK_SPEED_40GBPS:
++ fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
++ break;
++ case LPFC_ASYNC_LINK_SPEED_100GBPS:
++ fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
++ break;
++ default:
++ fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
++ break;
++ }
+ } else
+ fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+
+--
+2.12.3
+
diff --git a/patches.drivers/scsi-lpfc-Limit-tracking-of-tgt-queue-depth-in-fast-.patch b/patches.drivers/scsi-lpfc-Limit-tracking-of-tgt-queue-depth-in-fast-.patch
new file mode 100644
index 0000000000..adcefa11c2
--- /dev/null
+++ b/patches.drivers/scsi-lpfc-Limit-tracking-of-tgt-queue-depth-in-fast-.patch
@@ -0,0 +1,325 @@
+From: James Smart <jsmart2021@gmail.com>
+Date: Tue, 31 Jul 2018 17:23:22 -0700
+Subject: [PATCH] scsi: lpfc: Limit tracking of tgt queue depth in fast path
+References: bsc#1102658
+Git-commit: 2a5b7d626ed2256fd0ef0e799ebc6ef47b7bd283
+Patch-mainline: Queued in subsystem maintainer repository
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+
+Performance is affected when target queue depth is tracked. An atomic
+counter is incremented on the submission path which competes with it being
+decremented on the completion path. In addition, multiple CPUs can
+simultaniously be manipulating this counter for the same ndlp.
+
+Reduce the overhead by only performing the target increment/decrement when
+the target queue depth is less than the overall adapter depth, thus is
+actually meaningful.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/lpfc/lpfc_disc.h | 3 ++
+ drivers/scsi/lpfc/lpfc_nportdisc.c | 6 ----
+ drivers/scsi/lpfc/lpfc_nvme.c | 41 ++++++++++++---------
+ drivers/scsi/lpfc/lpfc_nvme.h | 1 +
+ drivers/scsi/lpfc/lpfc_scsi.c | 74 ++++++++++++++++++++++----------------
+ drivers/scsi/lpfc/lpfc_scsi.h | 2 ++
+ 6 files changed, 74 i