From: Greg Kroah-Hartman Date: Tue, 10 Oct 2017 15:29:57 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.75~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4c28e8327c69c1ce6946c356d79106dd7b34400e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch --- 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 index 00000000000..9654a47e3c2 --- /dev/null +++ b/queue-4.4/iwlwifi-add-workaround-to-disable-wide-channels-in-5ghz.patch @@ -0,0 +1,184 @@ +From 01a9c948a09348950515bf2abb6113ed83e696d8 Mon Sep 17 00:00:00 2001 +From: Luca Coelho +Date: Tue, 15 Aug 2017 20:48:41 +0300 +Subject: iwlwifi: add workaround to disable wide channels in 5GHz + +From: Luca Coelho + +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 +Signed-off-by: Greg Kroah-Hartman + + +--- + 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 index 00000000000..51592449c58 --- /dev/null +++ b/queue-4.4/scsi-sd-do-not-override-max_sectors_kb-sysfs-setting.patch @@ -0,0 +1,70 @@ +From 77082ca503bed061f7fbda7cfd7c93beda967a41 Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" +Date: Wed, 27 Sep 2017 21:38:59 -0400 +Subject: scsi: sd: Do not override max_sectors_kb sysfs setting + +From: Martin K. Petersen + +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 +Reviewed-by: Martin Wilck +Tested-by: Don Brace +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.4/series b/queue-4.4/series index f8b24fcd402..a7505b604ea 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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