--- /dev/null
+From 01a9c948a09348950515bf2abb6113ed83e696d8 Mon Sep 17 00:00:00 2001
+From: Luca Coelho <luciano.coelho@intel.com>
+Date: Tue, 15 Aug 2017 20:48:41 +0300
+Subject: iwlwifi: add workaround to disable wide channels in 5GHz
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+commit 01a9c948a09348950515bf2abb6113ed83e696d8 upstream.
+
+The OTP in some SKUs have erroneously allowed 40MHz and 80MHz channels
+in the 5.2GHz band. The firmware has been modified to not allow this
+in those SKUs, so the driver needs to do the same otherwise the
+firmware will assert when we try to use it.
+
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 70 ++++++++++++++++++++++-----
+ 1 file changed, 58 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
++++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+@@ -73,6 +73,7 @@
+ /* NVM offsets (in words) definitions */
+ enum wkp_nvm_offsets {
+ /* NVM HW-Section offset (in words) definitions */
++ SUBSYSTEM_ID = 0x0A,
+ HW_ADDR = 0x15,
+
+ /* NVM SW-Section offset (in words) definitions */
+@@ -257,13 +258,12 @@ static u32 iwl_get_channel_flags(u8 ch_n
+ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
+ struct iwl_nvm_data *data,
+ const __le16 * const nvm_ch_flags,
+- bool lar_supported)
++ bool lar_supported, bool no_wide_in_5ghz)
+ {
+ int ch_idx;
+ int n_channels = 0;
+ struct ieee80211_channel *channel;
+ u16 ch_flags;
+- bool is_5ghz;
+ int num_of_ch, num_2ghz_channels;
+ const u8 *nvm_chan;
+
+@@ -278,12 +278,20 @@ static int iwl_init_channel_map(struct d
+ }
+
+ for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
++ bool is_5ghz = (ch_idx >= num_2ghz_channels);
++
+ ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
+
+- if (ch_idx >= num_2ghz_channels &&
+- !data->sku_cap_band_52GHz_enable)
++ if (is_5ghz && !data->sku_cap_band_52GHz_enable)
+ continue;
+
++ /* workaround to disable wide channels in 5GHz */
++ if (no_wide_in_5ghz && is_5ghz) {
++ ch_flags &= ~(NVM_CHANNEL_40MHZ |
++ NVM_CHANNEL_80MHZ |
++ NVM_CHANNEL_160MHZ);
++ }
++
+ if (!lar_supported && !(ch_flags & NVM_CHANNEL_VALID)) {
+ /*
+ * Channels might become valid later if lar is
+@@ -303,8 +311,8 @@ static int iwl_init_channel_map(struct d
+ n_channels++;
+
+ channel->hw_value = nvm_chan[ch_idx];
+- channel->band = (ch_idx < num_2ghz_channels) ?
+- IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
++ channel->band = is_5ghz ?
++ IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
+ channel->center_freq =
+ ieee80211_channel_to_frequency(
+ channel->hw_value, channel->band);
+@@ -316,7 +324,6 @@ static int iwl_init_channel_map(struct d
+ * is not used in mvm, and is used for backwards compatibility
+ */
+ channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
+- is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
+
+ /* don't put limitations in case we're using LAR */
+ if (!lar_supported)
+@@ -405,7 +412,8 @@ static void iwl_init_vht_hw_capab(const
+ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
+ struct iwl_nvm_data *data,
+ const __le16 *ch_section,
+- u8 tx_chains, u8 rx_chains, bool lar_supported)
++ u8 tx_chains, u8 rx_chains, bool lar_supported,
++ bool no_wide_in_5ghz)
+ {
+ int n_channels;
+ int n_used = 0;
+@@ -414,12 +422,14 @@ static void iwl_init_sbands(struct devic
+ if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
+ n_channels = iwl_init_channel_map(
+ dev, cfg, data,
+- &ch_section[NVM_CHANNELS], lar_supported);
++ &ch_section[NVM_CHANNELS], lar_supported,
++ no_wide_in_5ghz);
+ else
+ n_channels = iwl_init_channel_map(
+ dev, cfg, data,
+ &ch_section[NVM_CHANNELS_FAMILY_8000],
+- lar_supported);
++ lar_supported,
++ no_wide_in_5ghz);
+
+ sband = &data->bands[IEEE80211_BAND_2GHZ];
+ sband->band = IEEE80211_BAND_2GHZ;
+@@ -582,6 +592,39 @@ static void iwl_set_hw_address_family_80
+
+ #define IWL_4165_DEVICE_ID 0x5501
+
++static bool
++iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
++ const __le16 *nvm_hw)
++{
++ /*
++ * Workaround a bug in Indonesia SKUs where the regulatory in
++ * some 7000-family OTPs erroneously allow wide channels in
++ * 5GHz. To check for Indonesia, we take the SKU value from
++ * bits 1-4 in the subsystem ID and check if it is either 5 or
++ * 9. In those cases, we need to force-disable wide channels
++ * in 5GHz otherwise the FW will throw a sysassert when we try
++ * to use them.
++ */
++ if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
++ /*
++ * Unlike the other sections in the NVM, the hw
++ * section uses big-endian.
++ */
++ u16 subsystem_id = be16_to_cpup((const __be16 *)nvm_hw
++ + SUBSYSTEM_ID);
++ u8 sku = (subsystem_id & 0x1e) >> 1;
++
++ if (sku == 5 || sku == 9) {
++ IWL_DEBUG_EEPROM(dev,
++ "disabling wide channels in 5GHz (0x%0x %d)\n",
++ subsystem_id, sku);
++ return true;
++ }
++ }
++
++ return false;
++}
++
+ struct iwl_nvm_data *
+ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
+ const __le16 *nvm_hw, const __le16 *nvm_sw,
+@@ -591,6 +634,7 @@ iwl_parse_nvm_data(struct device *dev, c
+ u32 mac_addr0, u32 mac_addr1, u32 hw_id)
+ {
+ struct iwl_nvm_data *data;
++ bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
+ u32 sku;
+ u32 radio_cfg;
+ u16 lar_config;
+@@ -657,7 +701,8 @@ iwl_parse_nvm_data(struct device *dev, c
+ iwl_set_hw_address(cfg, data, nvm_hw);
+
+ iwl_init_sbands(dev, cfg, data, nvm_sw,
+- tx_chains, rx_chains, lar_fw_supported);
++ tx_chains, rx_chains, lar_fw_supported,
++ no_wide_in_5ghz);
+ } else {
+ u16 lar_offset = data->nvm_version < 0xE39 ?
+ NVM_LAR_OFFSET_FAMILY_8000_OLD :
+@@ -673,7 +718,8 @@ iwl_parse_nvm_data(struct device *dev, c
+
+ iwl_init_sbands(dev, cfg, data, regulatory,
+ tx_chains, rx_chains,
+- lar_fw_supported && data->lar_enabled);
++ lar_fw_supported && data->lar_enabled,
++ no_wide_in_5ghz);
+ }
+
+ data->calib_version = 255;
--- /dev/null
+From 77082ca503bed061f7fbda7cfd7c93beda967a41 Mon Sep 17 00:00:00 2001
+From: "Martin K. Petersen" <martin.petersen@oracle.com>
+Date: Wed, 27 Sep 2017 21:38:59 -0400
+Subject: scsi: sd: Do not override max_sectors_kb sysfs setting
+
+From: Martin K. Petersen <martin.petersen@oracle.com>
+
+commit 77082ca503bed061f7fbda7cfd7c93beda967a41 upstream.
+
+A user may lower the max_sectors_kb setting in sysfs to accommodate
+certain workloads. Previously we would always set the max I/O size to
+either the block layer default or the optional preferred I/O size
+reported by the device.
+
+Keep the current heuristics for the initial setting of max_sectors_kb.
+For subsequent invocations, only update the current queue limit if it
+exceeds the capabilities of the hardware.
+
+Reported-by: Don Brace <don.brace@microsemi.com>
+Reviewed-by: Martin Wilck <mwilck@suse.com>
+Tested-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sd.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -2878,8 +2878,6 @@ static int sd_revalidate_disk(struct gen
+ sd_read_write_same(sdkp, buffer);
+ }
+
+- sdkp->first_scan = 0;
+-
+ /*
+ * We now have all cache related info, determine how we deal
+ * with flush requests.
+@@ -2894,7 +2892,7 @@ static int sd_revalidate_disk(struct gen
+ q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);
+
+ /*
+- * Use the device's preferred I/O size for reads and writes
++ * Determine the device's preferred I/O size for reads and writes
+ * unless the reported value is unreasonably small, large, or
+ * garbage.
+ */
+@@ -2908,8 +2906,19 @@ static int sd_revalidate_disk(struct gen
+ rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
+ (sector_t)BLK_DEF_MAX_SECTORS);
+
+- /* Combine with controller limits */
+- q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
++ /* Do not exceed controller limit */
++ rw_max = min(rw_max, queue_max_hw_sectors(q));
++
++ /*
++ * Only update max_sectors if previously unset or if the current value
++ * exceeds the capabilities of the hardware.
++ */
++ if (sdkp->first_scan ||
++ q->limits.max_sectors > q->limits.max_dev_sectors ||
++ q->limits.max_sectors > q->limits.max_hw_sectors)
++ q->limits.max_sectors = rw_max;
++
++ sdkp->first_scan = 0;
+
+ set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));
+ sd_config_write_same(sdkp);