--- /dev/null
+From f7f154f1246ccc5a0a7e9ce50932627d60a0c878 Mon Sep 17 00:00:00 2001
+From: Rusty Russell <rusty@rustcorp.com.au>
+Date: Tue, 5 Mar 2013 10:07:08 +1030
+Subject: hw_random: make buffer usable in scatterlist.
+
+From: Rusty Russell <rusty@rustcorp.com.au>
+
+commit f7f154f1246ccc5a0a7e9ce50932627d60a0c878 upstream.
+
+virtio_rng feeds the randomness buffer handed by the core directly
+into the scatterlist, since commit bb347d98079a547e80bd4722dee1de61e4dca0e8.
+
+However, if CONFIG_HW_RANDOM=m, the static buffer isn't a linear address
+(at least on most archs). We could fix this in virtio_rng, but it's actually
+far easier to just do it in the core as virtio_rng would have to allocate
+a buffer every time (it doesn't know how much the core will want to read).
+
+Reported-by: Aurelien Jarno <aurelien@aurel32.net>
+Tested-by: Aurelien Jarno <aurelien@aurel32.net>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/hw_random/core.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/char/hw_random/core.c
++++ b/drivers/char/hw_random/core.c
+@@ -40,6 +40,7 @@
+ #include <linux/init.h>
+ #include <linux/miscdevice.h>
+ #include <linux/delay.h>
++#include <linux/slab.h>
+ #include <asm/uaccess.h>
+
+
+@@ -52,8 +53,12 @@ static struct hwrng *current_rng;
+ static LIST_HEAD(rng_list);
+ static DEFINE_MUTEX(rng_mutex);
+ static int data_avail;
+-static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
+- __cacheline_aligned;
++static u8 *rng_buffer;
++
++static size_t rng_buffer_size(void)
++{
++ return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
++}
+
+ static inline int hwrng_init(struct hwrng *rng)
+ {
+@@ -116,7 +121,7 @@ static ssize_t rng_dev_read(struct file
+
+ if (!data_avail) {
+ bytes_read = rng_get_data(current_rng, rng_buffer,
+- sizeof(rng_buffer),
++ rng_buffer_size(),
+ !(filp->f_flags & O_NONBLOCK));
+ if (bytes_read < 0) {
+ err = bytes_read;
+@@ -307,6 +312,14 @@ int hwrng_register(struct hwrng *rng)
+
+ mutex_lock(&rng_mutex);
+
++ /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
++ err = -ENOMEM;
++ if (!rng_buffer) {
++ rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
++ if (!rng_buffer)
++ goto out_unlock;
++ }
++
+ /* Must not register two RNGs with the same name. */
+ err = -EEXIST;
+ list_for_each_entry(tmp, &rng_list, list) {
--- /dev/null
+From 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Mon, 25 Feb 2013 16:01:34 +0100
+Subject: iwlwifi: always copy first 16 bytes of commands
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 upstream.
+
+The FH hardware will always write back to the scratch field
+in commands, even host commands not just TX commands, which
+can overwrite parts of the command. This is problematic if
+the command is re-used (with IWL_HCMD_DFL_NOCOPY) and can
+cause calibration issues.
+
+Address this problem by always putting at least the first
+16 bytes into the buffer we also use for the command header
+and therefore make the DMA engine write back into this.
+
+For commands that are smaller than 16 bytes also always map
+enough memory for the DMA engine to write back to.
+
+Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-devtrace.h | 10 +--
+ drivers/net/wireless/iwlwifi/pcie/internal.h | 9 +++
+ drivers/net/wireless/iwlwifi/pcie/tx.c | 75 ++++++++++++++++++++-------
+ 3 files changed, 71 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
++++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
+ TRACE_EVENT(iwlwifi_dev_hcmd,
+ TP_PROTO(const struct device *dev,
+ struct iwl_host_cmd *cmd, u16 total_size,
+- const void *hdr, size_t hdr_len),
+- TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
++ struct iwl_cmd_header *hdr),
++ TP_ARGS(dev, cmd, total_size, hdr),
+ TP_STRUCT__entry(
+ DEV_ENTRY
+ __dynamic_array(u8, hcmd, total_size)
+ __field(u32, flags)
+ ),
+ TP_fast_assign(
+- int i, offset = hdr_len;
++ int i, offset = sizeof(*hdr);
+
+ DEV_ASSIGN;
+ __entry->flags = cmd->flags;
+- memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
++ memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
+
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ if (!cmd->len[i])
+ continue;
+- if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
+- continue;
+ memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
+ cmd->data[i], cmd->len[i]);
+ offset += cmd->len[i];
+--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
++++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
+@@ -182,6 +182,15 @@ struct iwl_queue {
+ #define TFD_TX_CMD_SLOTS 256
+ #define TFD_CMD_SLOTS 32
+
++/*
++ * The FH will write back to the first TB only, so we need
++ * to copy some data into the buffer regardless of whether
++ * it should be mapped or not. This indicates how much to
++ * copy, even for HCMDs it must be big enough to fit the
++ * DRAM scratch from the TX cmd, at least 16 bytes.
++ */
++#define IWL_HCMD_MIN_COPY_SIZE 16
++
+ struct iwl_pcie_txq_entry {
+ struct iwl_device_cmd *cmd;
+ struct iwl_device_cmd *copy_cmd;
+--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
+@@ -1131,10 +1131,12 @@ static int iwl_pcie_enqueue_hcmd(struct
+ void *dup_buf = NULL;
+ dma_addr_t phys_addr;
+ int idx;
+- u16 copy_size, cmd_size;
++ u16 copy_size, cmd_size, dma_size;
+ bool had_nocopy = false;
+ int i;
+ u32 cmd_pos;
++ const u8 *cmddata[IWL_MAX_CMD_TFDS];
++ u16 cmdlen[IWL_MAX_CMD_TFDS];
+
+ copy_size = sizeof(out_cmd->hdr);
+ cmd_size = sizeof(out_cmd->hdr);
+@@ -1143,8 +1145,23 @@ static int iwl_pcie_enqueue_hcmd(struct
+ BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
+
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
++ cmddata[i] = cmd->data[i];
++ cmdlen[i] = cmd->len[i];
++
+ if (!cmd->len[i])
+ continue;
++
++ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
++ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
++ int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
++
++ if (copy > cmdlen[i])
++ copy = cmdlen[i];
++ cmdlen[i] -= copy;
++ cmddata[i] += copy;
++ copy_size += copy;
++ }
++
+ if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
+ had_nocopy = true;
+ if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
+@@ -1164,7 +1181,7 @@ static int iwl_pcie_enqueue_hcmd(struct
+ goto free_dup_buf;
+ }
+
+- dup_buf = kmemdup(cmd->data[i], cmd->len[i],
++ dup_buf = kmemdup(cmddata[i], cmdlen[i],
+ GFP_ATOMIC);
+ if (!dup_buf)
+ return -ENOMEM;
+@@ -1174,7 +1191,7 @@ static int iwl_pcie_enqueue_hcmd(struct
+ idx = -EINVAL;
+ goto free_dup_buf;
+ }
+- copy_size += cmd->len[i];
++ copy_size += cmdlen[i];
+ }
+ cmd_size += cmd->len[i];
+ }
+@@ -1221,14 +1238,31 @@ static int iwl_pcie_enqueue_hcmd(struct
+
+ /* and copy the data that needs to be copied */
+ cmd_pos = offsetof(struct iwl_device_cmd, payload);
++ copy_size = sizeof(out_cmd->hdr);
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+- if (!cmd->len[i])
++ int copy = 0;
++
++ if (!cmd->len)
+ continue;
+- if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+- IWL_HCMD_DFL_DUP))
+- break;
+- memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
+- cmd_pos += cmd->len[i];
++
++ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
++ if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
++ copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
++
++ if (copy > cmd->len[i])
++ copy = cmd->len[i];
++ }
++
++ /* copy everything if not nocopy/dup */
++ if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
++ IWL_HCMD_DFL_DUP)))
++ copy = cmd->len[i];
++
++ if (copy) {
++ memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
++ cmd_pos += copy;
++ copy_size += copy;
++ }
+ }
+
+ WARN_ON_ONCE(txq->entries[idx].copy_cmd);
+@@ -1254,7 +1288,14 @@ static int iwl_pcie_enqueue_hcmd(struct
+ out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
+ cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
+
+- phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
++ /*
++ * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
++ * still map at least that many bytes for the hardware to write back to.
++ * We have enough space, so that's not a problem.
++ */
++ dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE);
++
++ phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size,
+ DMA_BIDIRECTIONAL);
+ if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
+ idx = -ENOMEM;
+@@ -1262,14 +1303,15 @@ static int iwl_pcie_enqueue_hcmd(struct
+ }
+
+ dma_unmap_addr_set(out_meta, mapping, phys_addr);
+- dma_unmap_len_set(out_meta, len, copy_size);
++ dma_unmap_len_set(out_meta, len, dma_size);
+
+ iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
+
++ /* map the remaining (adjusted) nocopy/dup fragments */
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+- const void *data = cmd->data[i];
++ const void *data = cmddata[i];
+
+- if (!cmd->len[i])
++ if (!cmdlen[i])
+ continue;
+ if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+ IWL_HCMD_DFL_DUP)))
+@@ -1277,7 +1319,7 @@ static int iwl_pcie_enqueue_hcmd(struct
+ if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
+ data = dup_buf;
+ phys_addr = dma_map_single(trans->dev, (void *)data,
+- cmd->len[i], DMA_BIDIRECTIONAL);
++ cmdlen[i], DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(trans->dev, phys_addr)) {
+ iwl_pcie_tfd_unmap(trans, out_meta,
+ &txq->tfds[q->write_ptr],
+@@ -1286,7 +1328,7 @@ static int iwl_pcie_enqueue_hcmd(struct
+ goto out;
+ }
+
+- iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);
++ iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
+ }
+
+ out_meta->flags = cmd->flags;
+@@ -1296,8 +1338,7 @@ static int iwl_pcie_enqueue_hcmd(struct
+
+ txq->need_update = 1;
+
+- trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,
+- &out_cmd->hdr, copy_size);
++ trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
+
+ /* start timer if queue currently empty */
+ if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
--- /dev/null
+From 466026989f112e0546ca39ab00a759af82dbe83a Mon Sep 17 00:00:00 2001
+From: Bing Zhao <bzhao@marvell.com>
+Date: Tue, 26 Feb 2013 12:58:35 -0800
+Subject: libertas: fix crash for SD8688
+
+From: Bing Zhao <bzhao@marvell.com>
+
+commit 466026989f112e0546ca39ab00a759af82dbe83a upstream.
+
+For SD8688, FUNC_INIT command is queued before fw_ready flag is
+set. This causes the following crash as lbs_thread blocks any
+command if fw_ready is not set.
+
+[ 209.338953] [<c0502248>] (__schedule+0x610/0x764) from [<bf20ae24>] (__lbs_cmd+0xb8/0x130 [libertas])
+[ 209.348340] [<bf20ae24>] (__lbs_cmd+0xb8/0x130 [libertas]) from [<bf222474>] (if_sdio_finish_power_on+0xec/0x1b0 [libertas_sdio])
+[ 209.360136] [<bf222474>] (if_sdio_finish_power_on+0xec/0x1b0 [libertas_sdio]) from [<bf2226c4>] (if_sdio_power_on+0x18c/0x20c [libertas_sdio])
+[ 209.373052] [<bf2226c4>] (if_sdio_power_on+0x18c/0x20c [libertas_sdio]) from [<bf222944>] (if_sdio_probe+0x200/0x31c [libertas_sdio])
+[ 209.385316] [<bf222944>] (if_sdio_probe+0x200/0x31c [libertas_sdio]) from [<bf01d820>] (sdio_bus_probe+0x94/0xfc [mmc_core])
+[ 209.396748] [<bf01d820>] (sdio_bus_probe+0x94/0xfc [mmc_core]) from [<c02e729c>] (driver_probe_device+0x12c/0x348)
+[ 209.407214] [<c02e729c>] (driver_probe_device+0x12c/0x348) from [<c02e7530>] (__driver_attach+0x78/0x9c)
+[ 209.416798] [<c02e7530>] (__driver_attach+0x78/0x9c) from [<c02e5658>] (bus_for_each_dev+0x50/0x88)
+[ 209.425946] [<c02e5658>] (bus_for_each_dev+0x50/0x88) from [<c02e6810>] (bus_add_driver+0x108/0x268)
+[ 209.435180] [<c02e6810>] (bus_add_driver+0x108/0x268) from [<c02e782c>] (driver_register+0xa4/0x134)
+[ 209.444426] [<c02e782c>] (driver_register+0xa4/0x134) from [<bf22601c>] (if_sdio_init_module+0x1c/0x3c [libertas_sdio])
+[ 209.455339] [<bf22601c>] (if_sdio_init_module+0x1c/0x3c [libertas_sdio]) from [<c00085b8>] (do_one_initcall+0x98/0x174)
+[ 209.466236] [<c00085b8>] (do_one_initcall+0x98/0x174) from [<c0076504>] (load_module+0x1c5c/0x1f80)
+[ 209.475390] [<c0076504>] (load_module+0x1c5c/0x1f80) from [<c007692c>] (sys_init_module+0x104/0x128)
+[ 209.484632] [<c007692c>] (sys_init_module+0x104/0x128) from [<c0008c40>] (ret_fast_syscall+0x0/0x38)
+
+Fix it by setting fw_ready flag prior to queuing FUNC_INIT command.
+
+Reported-by: Lubomir Rintel <lkundrak@v3.sk>
+Tested-by: Lubomir Rintel <lkundrak@v3.sk>
+Signed-off-by: Bing Zhao <bzhao@marvell.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/libertas/if_sdio.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/libertas/if_sdio.c
++++ b/drivers/net/wireless/libertas/if_sdio.c
+@@ -825,6 +825,11 @@ static void if_sdio_finish_power_on(stru
+
+ sdio_release_host(func);
+
++ /* Set fw_ready before queuing any commands so that
++ * lbs_thread won't block from sending them to firmware.
++ */
++ priv->fw_ready = 1;
++
+ /*
+ * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
+ */
+@@ -839,7 +844,6 @@ static void if_sdio_finish_power_on(stru
+ netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
+ }
+
+- priv->fw_ready = 1;
+ wake_up(&card->pwron_waitq);
+
+ if (!card->started) {