--- /dev/null
+From cb4281528b62207918b1e95827cad7527aa4dbaa Mon Sep 17 00:00:00 2001
+From: Tamizh chelvam <c_traja@qti.qualcomm.com>
+Date: Thu, 2 Feb 2017 08:32:18 +0200
+Subject: ath10k: fix boot failure in UTF mode/testmode
+
+From: Tamizh chelvam <c_traja@qti.qualcomm.com>
+
+commit cb4281528b62207918b1e95827cad7527aa4dbaa upstream.
+
+Rx filter reset and the dynamic tx switch mode (EXT_RESOURCE_CFG)
+configuration are causing the following errors when UTF firmware
+is loaded to the target.
+
+Error message 1:
+[ 598.015629] ath10k_pci 0001:01:00.0: failed to ping firmware: -110
+[ 598.020828] ath10k_pci 0001:01:00.0: failed to reset rx filter: -110
+[ 598.141556] ath10k_pci 0001:01:00.0: failed to start core (testmode): -110
+
+Error message 2:
+[ 668.615839] ath10k_ahb a000000.wifi: failed to send ext resource cfg command : -95
+[ 668.618902] ath10k_ahb a000000.wifi: failed to start core (testmode): -95
+
+Avoiding these configurations while bringing the target in
+testmode is solving the problem.
+
+Signed-off-by: Tamizh chelvam <c_traja@qti.qualcomm.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath10k/core.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -1901,7 +1901,8 @@ int ath10k_core_start(struct ath10k *ar,
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
+ ar->hw->wiphy->fw_version);
+
+- if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map)) {
++ if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map) &&
++ mode == ATH10K_FIRMWARE_MODE_NORMAL) {
+ val = 0;
+ if (ath10k_peer_stats_enabled(ar))
+ val = WMI_10_4_PEER_STATS;
+@@ -1954,10 +1955,13 @@ int ath10k_core_start(struct ath10k *ar,
+ * possible to implicitly make it correct by creating a dummy vdev and
+ * then deleting it.
+ */
+- status = ath10k_core_reset_rx_filter(ar);
+- if (status) {
+- ath10k_err(ar, "failed to reset rx filter: %d\n", status);
+- goto err_hif_stop;
++ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
++ status = ath10k_core_reset_rx_filter(ar);
++ if (status) {
++ ath10k_err(ar,
++ "failed to reset rx filter: %d\n", status);
++ goto err_hif_stop;
++ }
+ }
+
+ /* If firmware indicates Full Rx Reorder support it must be used in a
--- /dev/null
+From a70e1d6fd6b5e1a81fa6171600942bee34f5128f Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 11 Jan 2017 16:32:13 +0200
+Subject: ath5k: drop bogus warning on drv_set_key with unsupported cipher
+
+From: Felix Fietkau <nbd@nbd.name>
+
+commit a70e1d6fd6b5e1a81fa6171600942bee34f5128f upstream.
+
+Simply return -EOPNOTSUPP instead.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath5k/mac80211-ops.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+@@ -502,8 +502,7 @@ ath5k_set_key(struct ieee80211_hw *hw, e
+ break;
+ return -EOPNOTSUPP;
+ default:
+- WARN_ON(1);
+- return -EINVAL;
++ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&ah->lock);
--- /dev/null
+From 3a5e969bb2f6692a256352649355d56d018d6b88 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 2 Feb 2017 10:14:52 +0100
+Subject: ath9k: fix race condition in enabling/disabling IRQs
+
+From: Felix Fietkau <nbd@nbd.name>
+
+commit 3a5e969bb2f6692a256352649355d56d018d6b88 upstream.
+
+The code currently relies on refcounting to disable IRQs from within the
+IRQ handler and re-enabling them again after the tasklet has run.
+
+However, due to race conditions sometimes the IRQ handler might be
+called twice, or the tasklet may not run at all (if interrupted in the
+middle of a reset).
+
+This can cause nasty imbalances in the irq-disable refcount which will
+get the driver permanently stuck until the entire radio has been stopped
+and started again (ath_reset will not recover from this).
+
+Instead of using this fragile logic, change the code to ensure that
+running the irq handler during tasklet processing is safe, and leave the
+refcount untouched.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ath9k.h | 1
+ drivers/net/wireless/ath/ath9k/init.c | 1
+ drivers/net/wireless/ath/ath9k/mac.c | 44 +++++++++++++++++++++++++--------
+ drivers/net/wireless/ath/ath9k/mac.h | 1
+ drivers/net/wireless/ath/ath9k/main.c | 27 ++++++++------------
+ 5 files changed, 48 insertions(+), 26 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -959,6 +959,7 @@ struct ath_softc {
+ struct survey_info *cur_survey;
+ struct survey_info survey[ATH9K_NUM_CHANNELS];
+
++ spinlock_t intr_lock;
+ struct tasklet_struct intr_tq;
+ struct tasklet_struct bcon_tasklet;
+ struct ath_hw *sc_ah;
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -626,6 +626,7 @@ static int ath9k_init_softc(u16 devid, s
+ common->bt_ant_diversity = 1;
+
+ spin_lock_init(&common->cc_lock);
++ spin_lock_init(&sc->intr_lock);
+ spin_lock_init(&sc->sc_serial_rw);
+ spin_lock_init(&sc->sc_pm_lock);
+ spin_lock_init(&sc->chan_lock);
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -805,21 +805,12 @@ void ath9k_hw_disable_interrupts(struct
+ }
+ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+
+-void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+ u32 sync_default = AR_INTR_SYNC_DEFAULT;
+ u32 async_mask;
+
+- if (!(ah->imask & ATH9K_INT_GLOBAL))
+- return;
+-
+- if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
+- ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
+- atomic_read(&ah->intr_ref_cnt));
+- return;
+- }
+-
+ if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
+ AR_SREV_9561(ah))
+ sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+@@ -841,6 +832,39 @@ void ath9k_hw_enable_interrupts(struct a
+ ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+ REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+ }
++
++void ath9k_hw_resume_interrupts(struct ath_hw *ah)
++{
++ struct ath_common *common = ath9k_hw_common(ah);
++
++ if (!(ah->imask & ATH9K_INT_GLOBAL))
++ return;
++
++ if (atomic_read(&ah->intr_ref_cnt) != 0) {
++ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++ atomic_read(&ah->intr_ref_cnt));
++ return;
++ }
++
++ __ath9k_hw_enable_interrupts(ah);
++}
++EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
++
++void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++{
++ struct ath_common *common = ath9k_hw_common(ah);
++
++ if (!(ah->imask & ATH9K_INT_GLOBAL))
++ return;
++
++ if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
++ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++ atomic_read(&ah->intr_ref_cnt));
++ return;
++ }
++
++ __ath9k_hw_enable_interrupts(ah);
++}
+ EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+
+ void ath9k_hw_set_interrupts(struct ath_hw *ah)
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_disable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_kill_interrupts(struct ath_hw *ah);
++void ath9k_hw_resume_interrupts(struct ath_hw *ah);
+
+ void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -373,21 +373,20 @@ void ath9k_tasklet(unsigned long data)
+ struct ath_common *common = ath9k_hw_common(ah);
+ enum ath_reset_type type;
+ unsigned long flags;
+- u32 status = sc->intrstatus;
++ u32 status;
+ u32 rxmask;
+
++ spin_lock_irqsave(&sc->intr_lock, flags);
++ status = sc->intrstatus;
++ sc->intrstatus = 0;
++ spin_unlock_irqrestore(&sc->intr_lock, flags);
++
+ ath9k_ps_wakeup(sc);
+ spin_lock(&sc->sc_pcu_lock);
+
+ if (status & ATH9K_INT_FATAL) {
+ type = RESET_TYPE_FATAL_INT;
+ ath9k_queue_reset(sc, type);
+-
+- /*
+- * Increment the ref. counter here so that
+- * interrupts are enabled in the reset routine.
+- */
+- atomic_inc(&ah->intr_ref_cnt);
+ ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
+ goto out;
+ }
+@@ -403,11 +402,6 @@ void ath9k_tasklet(unsigned long data)
+ type = RESET_TYPE_BB_WATCHDOG;
+ ath9k_queue_reset(sc, type);
+
+- /*
+- * Increment the ref. counter here so that
+- * interrupts are enabled in the reset routine.
+- */
+- atomic_inc(&ah->intr_ref_cnt);
+ ath_dbg(common, RESET,
+ "BB_WATCHDOG: Skipping interrupts\n");
+ goto out;
+@@ -420,7 +414,6 @@ void ath9k_tasklet(unsigned long data)
+ if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
+ type = RESET_TYPE_TX_GTT;
+ ath9k_queue_reset(sc, type);
+- atomic_inc(&ah->intr_ref_cnt);
+ ath_dbg(common, RESET,
+ "GTT: Skipping interrupts\n");
+ goto out;
+@@ -477,7 +470,7 @@ void ath9k_tasklet(unsigned long data)
+ ath9k_btcoex_handle_interrupt(sc, status);
+
+ /* re-enable hardware interrupt */
+- ath9k_hw_enable_interrupts(ah);
++ ath9k_hw_resume_interrupts(ah);
+ out:
+ spin_unlock(&sc->sc_pcu_lock);
+ ath9k_ps_restore(sc);
+@@ -541,7 +534,9 @@ irqreturn_t ath_isr(int irq, void *dev)
+ return IRQ_NONE;
+
+ /* Cache the status */
+- sc->intrstatus = status;
++ spin_lock(&sc->intr_lock);
++ sc->intrstatus |= status;
++ spin_unlock(&sc->intr_lock);
+
+ if (status & SCHED_INTR)
+ sched = true;
+@@ -587,7 +582,7 @@ chip_reset:
+
+ if (sched) {
+ /* turn off every interrupt */
+- ath9k_hw_disable_interrupts(ah);
++ ath9k_hw_kill_interrupts(ah);
+ tasklet_schedule(&sc->intr_tq);
+ }
+
--- /dev/null
+From c9f1e32600816d695f817477d56490bfc2ba43c6 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@googlemail.com>
+Date: Tue, 14 Feb 2017 20:10:30 +0100
+Subject: ath9k: use correct OTP register offsets for the AR9340 and AR9550
+
+From: Christian Lamparter <chunkeey@googlemail.com>
+
+commit c9f1e32600816d695f817477d56490bfc2ba43c6 upstream.
+
+This patch fixes the OTP register definitions for the AR934x and AR9550
+WMAC SoC.
+
+Previously, the ath9k driver was unable to initialize the integrated
+WMAC on an Aerohive AP121:
+
+| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
+| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
+| ath: phy0: Unable to initialize hardware; initialization status: -5
+| ath9k ar934x_wmac: failed to initialize device
+| ath9k: probe of ar934x_wmac failed with error -5
+
+It turns out that the AR9300_OTP_STATUS and AR9300_OTP_DATA
+definitions contain a typo.
+
+Cc: Gabor Juhos <juhosg@openwrt.org>
+Fixes: add295a4afbdf5852d0 "ath9k: use correct OTP register offsets for AR9550"
+Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
+Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+@@ -73,13 +73,13 @@
+ #define AR9300_OTP_BASE \
+ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
+ #define AR9300_OTP_STATUS \
+- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
++ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
+ #define AR9300_OTP_STATUS_TYPE 0x7
+ #define AR9300_OTP_STATUS_VALID 0x4
+ #define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
+ #define AR9300_OTP_STATUS_SM_BUSY 0x1
+ #define AR9300_OTP_READ_DATA \
+- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
++ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
+
+ enum targetPowerHTRates {
+ HT_TARGET_RATE_0_8_16,
--- /dev/null
+From c0bb03924f1a80e7f65900e36c8e6b3dc167c5f8 Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Wed, 7 Dec 2016 01:16:24 -0800
+Subject: Drivers: hv: vmbus: Raise retry/wait limits in vmbus_post_msg()
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit c0bb03924f1a80e7f65900e36c8e6b3dc167c5f8 upstream.
+
+DoS protection conditions were altered in WS2016 and now it's easy to get
+-EAGAIN returned from vmbus_post_msg() (e.g. when we try changing MTU on a
+netvsc device in a loop). All vmbus_post_msg() callers don't retry the
+operation and we usually end up with a non-functional device or crash.
+
+While host's DoS protection conditions are unknown to me my tests show that
+it can take up to 10 seconds before the message is sent so doing udelay()
+is not an option, we really need to sleep. Almost all vmbus_post_msg()
+callers are ready to sleep but there is one special case:
+vmbus_initiate_unload() which can be called from interrupt/NMI context and
+we can't sleep there. I'm also not sure about the lonely
+vmbus_send_tl_connect_request() which has no in-tree users but its external
+users are most likely waiting for the host to reply so sleeping there is
+also appropriate.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/channel.c | 17 +++++++++--------
+ drivers/hv/channel_mgmt.c | 10 ++++++----
+ drivers/hv/connection.c | 17 ++++++++++++-----
+ drivers/hv/hyperv_vmbus.h | 2 +-
+ 4 files changed, 28 insertions(+), 18 deletions(-)
+
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -181,7 +181,7 @@ int vmbus_open(struct vmbus_channel *new
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
+ ret = vmbus_post_msg(open_msg,
+- sizeof(struct vmbus_channel_open_channel));
++ sizeof(struct vmbus_channel_open_channel), true);
+
+ if (ret != 0) {
+ err = ret;
+@@ -233,7 +233,7 @@ int vmbus_send_tl_connect_request(const
+ conn_msg.guest_endpoint_id = *shv_guest_servie_id;
+ conn_msg.host_service_id = *shv_host_servie_id;
+
+- return vmbus_post_msg(&conn_msg, sizeof(conn_msg));
++ return vmbus_post_msg(&conn_msg, sizeof(conn_msg), true);
+ }
+ EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
+
+@@ -419,7 +419,7 @@ int vmbus_establish_gpadl(struct vmbus_c
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
+ ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
+- sizeof(*msginfo));
++ sizeof(*msginfo), true);
+ if (ret != 0)
+ goto cleanup;
+
+@@ -433,8 +433,8 @@ int vmbus_establish_gpadl(struct vmbus_c
+ gpadl_body->gpadl = next_gpadl_handle;
+
+ ret = vmbus_post_msg(gpadl_body,
+- submsginfo->msgsize -
+- sizeof(*submsginfo));
++ submsginfo->msgsize - sizeof(*submsginfo),
++ true);
+ if (ret != 0)
+ goto cleanup;
+
+@@ -485,8 +485,8 @@ int vmbus_teardown_gpadl(struct vmbus_ch
+ list_add_tail(&info->msglistentry,
+ &vmbus_connection.chn_msg_list);
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+- ret = vmbus_post_msg(msg,
+- sizeof(struct vmbus_channel_gpadl_teardown));
++ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown),
++ true);
+
+ if (ret)
+ goto post_msg_err;
+@@ -557,7 +557,8 @@ static int vmbus_close_internal(struct v
+ msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
+ msg->child_relid = channel->offermsg.child_relid;
+
+- ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel));
++ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel),
++ true);
+
+ if (ret) {
+ pr_err("Close failed: close post msg return is %d\n", ret);
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -321,7 +321,8 @@ static void vmbus_release_relid(u32 reli
+ memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
+ msg.child_relid = relid;
+ msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
+- vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
++ vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released),
++ true);
+ }
+
+ void hv_event_tasklet_disable(struct vmbus_channel *channel)
+@@ -728,7 +729,8 @@ void vmbus_initiate_unload(bool crash)
+ init_completion(&vmbus_connection.unload_event);
+ memset(&hdr, 0, sizeof(struct vmbus_channel_message_header));
+ hdr.msgtype = CHANNELMSG_UNLOAD;
+- vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header));
++ vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header),
++ !crash);
+
+ /*
+ * vmbus_initiate_unload() is also called on crash and the crash can be
+@@ -1116,8 +1118,8 @@ int vmbus_request_offers(void)
+ msg->msgtype = CHANNELMSG_REQUESTOFFERS;
+
+
+- ret = vmbus_post_msg(msg,
+- sizeof(struct vmbus_channel_message_header));
++ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header),
++ true);
+ if (ret != 0) {
+ pr_err("Unable to request offers - %d\n", ret);
+
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -110,7 +110,8 @@ static int vmbus_negotiate_version(struc
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
+ ret = vmbus_post_msg(msg,
+- sizeof(struct vmbus_channel_initiate_contact));
++ sizeof(struct vmbus_channel_initiate_contact),
++ true);
+ if (ret != 0) {
+ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
+ list_del(&msginfo->msglistentry);
+@@ -434,7 +435,7 @@ void vmbus_on_event(unsigned long data)
+ /*
+ * vmbus_post_msg - Send a msg on the vmbus's message connection
+ */
+-int vmbus_post_msg(void *buffer, size_t buflen)
++int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep)
+ {
+ union hv_connection_id conn_id;
+ int ret = 0;
+@@ -449,7 +450,7 @@ int vmbus_post_msg(void *buffer, size_t
+ * insufficient resources. Retry the operation a couple of
+ * times before giving up.
+ */
+- while (retries < 20) {
++ while (retries < 100) {
+ ret = hv_post_message(conn_id, 1, buffer, buflen);
+
+ switch (ret) {
+@@ -472,8 +473,14 @@ int vmbus_post_msg(void *buffer, size_t
+ }
+
+ retries++;
+- udelay(usec);
+- if (usec < 2048)
++ if (can_sleep && usec > 1000)
++ msleep(usec / 1000);
++ else if (usec < MAX_UDELAY_MS * 1000)
++ udelay(usec);
++ else
++ mdelay(usec / 1000);
++
++ if (usec < 256000)
+ usec *= 2;
+ }
+ return ret;
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -683,7 +683,7 @@ void vmbus_free_channels(void);
+ int vmbus_connect(void);
+ void vmbus_disconnect(void);
+
+-int vmbus_post_msg(void *buffer, size_t buflen);
++int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep);
+
+ void vmbus_on_event(unsigned long data);
+ void vmbus_on_msg_dpc(unsigned long data);
--- /dev/null
+From 2a7275a3d867b228216886aae35e1f64291180b1 Mon Sep 17 00:00:00 2001
+From: Ley Foon Tan <ley.foon.tan@intel.com>
+Date: Tue, 28 Feb 2017 18:37:16 +0800
+Subject: PCI: altera: Fix TLP_CFG_DW0 for TLP write
+
+From: Ley Foon Tan <ley.foon.tan@intel.com>
+
+commit 2a7275a3d867b228216886aae35e1f64291180b1 upstream.
+
+eb5767122feb ("PCI: altera: Simplify TLB_CFG_DW0 usage") used
+TLP_FMTTYPE_CFGRD* (instead of TLP_FMTTYPE_CFGWR*) for TLP writes, which
+causes writing to configuration space to fail. Fix it by using correct
+FMTTYPE for write operation.
+
+Fixes: eb5767122feb ("PCI: altera: Simplify TLB_CFG_DW0 usage")
+Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pcie-altera.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/host/pcie-altera.c
++++ b/drivers/pci/host/pcie-altera.c
+@@ -57,10 +57,14 @@
+ #define TLP_WRITE_TAG 0x10
+ #define RP_DEVFN 0
+ #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
+-#define TLP_CFG_DW0(pcie, bus) \
++#define TLP_CFGRD_DW0(pcie, bus) \
+ ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGRD0 \
+ : TLP_FMTTYPE_CFGRD1) << 24) | \
+ TLP_PAYLOAD_SIZE)
++#define TLP_CFGWR_DW0(pcie, bus) \
++ ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGWR0 \
++ : TLP_FMTTYPE_CFGWR1) << 24) | \
++ TLP_PAYLOAD_SIZE)
+ #define TLP_CFG_DW1(pcie, tag, be) \
+ (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be))
+ #define TLP_CFG_DW2(bus, devfn, offset) \
+@@ -222,7 +226,7 @@ static int tlp_cfg_dword_read(struct alt
+ {
+ u32 headers[TLP_HDR_SIZE];
+
+- headers[0] = TLP_CFG_DW0(pcie, bus);
++ headers[0] = TLP_CFGRD_DW0(pcie, bus);
+ headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
+ headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+@@ -237,7 +241,7 @@ static int tlp_cfg_dword_write(struct al
+ u32 headers[TLP_HDR_SIZE];
+ int ret;
+
+- headers[0] = TLP_CFG_DW0(pcie, bus);
++ headers[0] = TLP_CFGWR_DW0(pcie, bus);
+ headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
+ headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
--- /dev/null
+From 49f4b08e61547a5ccd2db551d994c4503efe5666 Mon Sep 17 00:00:00 2001
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Date: Thu, 16 Feb 2017 10:22:34 +1100
+Subject: pci/hotplug/pnv-php: Disable MSI and PCI device properly
+
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+
+commit 49f4b08e61547a5ccd2db551d994c4503efe5666 upstream.
+
+pnv_php_disable_irq() can be called in two paths: Bailing path in
+pnv_php_enable_irq() or releasing slot. The MSI (or MSIx) interrupts
+is disabled unconditionally in pnv_php_disable_irq(). It's wrong
+because that might be enabled by drivers other than pnv-php.
+
+This disables MSI (or MSIx) interrupts and the PCI device only if
+it was enabled by pnv-php. In the error path of pnv_php_enable_irq(),
+we rely on the newly added parameter @disable_device. In the path
+of releasing slot, @pnv_php->irq is checked.
+
+Fixes: 360aebd85a4c ("drivers/pci/hotplug: Support surprise hotplug in powernv driver")
+Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/hotplug/pnv_php.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+--- a/drivers/pci/hotplug/pnv_php.c
++++ b/drivers/pci/hotplug/pnv_php.c
+@@ -35,9 +35,11 @@ static void pnv_php_register(struct devi
+ static void pnv_php_unregister_one(struct device_node *dn);
+ static void pnv_php_unregister(struct device_node *dn);
+
+-static void pnv_php_disable_irq(struct pnv_php_slot *php_slot)
++static void pnv_php_disable_irq(struct pnv_php_slot *php_slot,
++ bool disable_device)
+ {
+ struct pci_dev *pdev = php_slot->pdev;
++ int irq = php_slot->irq;
+ u16 ctrl;
+
+ if (php_slot->irq > 0) {
+@@ -56,10 +58,14 @@ static void pnv_php_disable_irq(struct p
+ php_slot->wq = NULL;
+ }
+
+- if (pdev->msix_enabled)
+- pci_disable_msix(pdev);
+- else if (pdev->msi_enabled)
+- pci_disable_msi(pdev);
++ if (disable_device || irq > 0) {
++ if (pdev->msix_enabled)
++ pci_disable_msix(pdev);
++ else if (pdev->msi_enabled)
++ pci_disable_msi(pdev);
++
++ pci_disable_device(pdev);
++ }
+ }
+
+ static void pnv_php_free_slot(struct kref *kref)
+@@ -68,7 +74,7 @@ static void pnv_php_free_slot(struct kre
+ struct pnv_php_slot, kref);
+
+ WARN_ON(!list_empty(&php_slot->children));
+- pnv_php_disable_irq(php_slot);
++ pnv_php_disable_irq(php_slot, false);
+ kfree(php_slot->name);
+ kfree(php_slot);
+ }
+@@ -759,7 +765,7 @@ static void pnv_php_init_irq(struct pnv_
+ php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
+ if (!php_slot->wq) {
+ dev_warn(&pdev->dev, "Cannot alloc workqueue\n");
+- pnv_php_disable_irq(php_slot);
++ pnv_php_disable_irq(php_slot, true);
+ return;
+ }
+
+@@ -772,7 +778,7 @@ static void pnv_php_init_irq(struct pnv_
+ ret = request_irq(irq, pnv_php_interrupt, IRQF_SHARED,
+ php_slot->name, php_slot);
+ if (ret) {
+- pnv_php_disable_irq(php_slot);
++ pnv_php_disable_irq(php_slot, true);
+ dev_warn(&pdev->dev, "Error %d enabling IRQ %d\n", ret, irq);
+ return;
+ }
--- /dev/null
+From 60e2e2fbafdd1285ae1b4ad39ded41603e0c74d0 Mon Sep 17 00:00:00 2001
+From: Dexuan Cui <decui@microsoft.com>
+Date: Fri, 10 Feb 2017 15:18:46 -0600
+Subject: PCI: hv: Fix wslot_to_devfn() to fix warnings on device removal
+
+From: Dexuan Cui <decui@microsoft.com>
+
+commit 60e2e2fbafdd1285ae1b4ad39ded41603e0c74d0 upstream.
+
+The devfn of 00:02.0 is 0x10. devfn_to_wslot(0x10) == 0x2, and
+wslot_to_devfn(0x2) should be 0x10, while it's 0x2 in the current code.
+
+Due to this, hv_eject_device_work() -> pci_get_domain_bus_and_slot()
+returns NULL and pci_stop_and_remove_bus_device() is not called.
+
+Later when the real device driver's .remove() is invoked by
+hv_pci_remove() -> pci_stop_root_bus(), some warnings can be noticed
+because the VM has lost the access to the underlying device at that
+time.
+
+Signed-off-by: Jake Oshins <jakeo@microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Haiyang Zhang <haiyangz@microsoft.com>
+CC: K. Y. Srinivasan <kys@microsoft.com>
+CC: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pci-hyperv.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/host/pci-hyperv.c
++++ b/drivers/pci/host/pci-hyperv.c
+@@ -130,7 +130,8 @@ union pci_version {
+ */
+ union win_slot_encoding {
+ struct {
+- u32 func:8;
++ u32 dev:5;
++ u32 func:3;
+ u32 reserved:24;
+ } bits;
+ u32 slot;
+@@ -483,7 +484,8 @@ static u32 devfn_to_wslot(int devfn)
+ union win_slot_encoding wslot;
+
+ wslot.slot = 0;
+- wslot.bits.func = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
++ wslot.bits.dev = PCI_SLOT(devfn);
++ wslot.bits.func = PCI_FUNC(devfn);
+
+ return wslot.slot;
+ }
+@@ -501,7 +503,7 @@ static int wslot_to_devfn(u32 wslot)
+ union win_slot_encoding slot_no;
+
+ slot_no.slot = wslot;
+- return PCI_DEVFN(0, slot_no.bits.func);
++ return PCI_DEVFN(slot_no.bits.dev, slot_no.bits.func);
+ }
+
+ /*
ext4-return-erofs-if-device-is-r-o-and-journal-replay-is-needed.patch
samples-seccomp-fix-64-bit-comparison-macros.patch
mei-remove-support-for-broken-parallel-read.patch
+ath10k-fix-boot-failure-in-utf-mode-testmode.patch
+ath5k-drop-bogus-warning-on-drv_set_key-with-unsupported-cipher.patch
+ath9k-fix-race-condition-in-enabling-disabling-irqs.patch
+ath9k-use-correct-otp-register-offsets-for-the-ar9340-and-ar9550.patch
+pci-hv-fix-wslot_to_devfn-to-fix-warnings-on-device-removal.patch
+pci-hotplug-pnv-php-disable-msi-and-pci-device-properly.patch
+pci-altera-fix-tlp_cfg_dw0-for-tlp-write.patch
+drivers-hv-vmbus-raise-retry-wait-limits-in-vmbus_post_msg.patch