]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2017 15:29:57 +0000 (17:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2017 15:29:57 +0000 (17:29 +0200)
added patches:
iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch
scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch

queue-4.4/iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch [new file with mode: 0644]
queue-4.4/scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch b/queue-4.4/iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch
new file mode 100644 (file)
index 0000000..9654a47
--- /dev/null
@@ -0,0 +1,184 @@
+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;
diff --git a/queue-4.4/scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch b/queue-4.4/scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch
new file mode 100644 (file)
index 0000000..5159244
--- /dev/null
@@ -0,0 +1,70 @@
+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);
index f8b24fcd402b047871f7406058f32bb59febfed8..a7505b604ea32016e808456bf80ed6213e711b23 100644 (file)
@@ -23,6 +23,8 @@ drivers-hv-fcopy-restore-correct-transfer-length.patch
 stm-class-fix-a-use-after-free.patch
 ftrace-fix-kmemleak-in-unregister_ftrace_graph.patch
 hid-i2c-hid-allocate-hid-buffers-for-real-worst-case.patch
+iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch
+scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch
 usb-uas-fix-bug-in-handling-of-alternate-settings.patch
 usb-core-harden-cdc_parse_cdc_header.patch
 usb-increase-quirk-delay-for-usb-devices.patch