Skip to content

Commit 1da9a58

Browse files
committed
Merge tag 'wireless-drivers-for-davem-2018-04-26' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers
Kalle Valo says: ==================== wireless-drivers fixes for 4.17 A few fixes for 4.17 but nothing really special. The new ETSI WMM parameter support for iwlwifi is not technically a bugfix but important for regulatory compliance. iwlwifi * use new ETSI WMM parameters from regulatory database * fix a regression with the older firmware API 31 (eg. 31.560484.0) brcmfmac * fix a double free in nvmam loading fails rtlwifi * yet another fix for ant_sel module parameter ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c7f46cc + af8a41c commit 1da9a58

File tree

8 files changed

+138
-62
lines changed

8 files changed

+138
-62
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct brcmf_fw_request *req)
459459
kfree(req);
460460
}
461461

462-
static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
462+
static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
463463
{
464464
struct brcmf_fw *fwctx = ctx;
465465
struct brcmf_fw_item *cur;
@@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
498498
brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
499499
cur->nv_data.data = nvram;
500500
cur->nv_data.len = nvram_length;
501-
return;
501+
return 0;
502502

503503
fail:
504-
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
505-
fwctx->done(fwctx->dev, -ENOENT, NULL);
506-
brcmf_fw_free_request(fwctx->req);
507-
kfree(fwctx);
504+
return -ENOENT;
508505
}
509506

510507
static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
@@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
553550
brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
554551
fw ? "" : "not ");
555552

556-
if (fw) {
557-
if (cur->type == BRCMF_FW_TYPE_BINARY)
558-
cur->binary = fw;
559-
else if (cur->type == BRCMF_FW_TYPE_NVRAM)
560-
brcmf_fw_request_nvram_done(fw, fwctx);
561-
else
562-
release_firmware(fw);
563-
} else if (cur->type == BRCMF_FW_TYPE_NVRAM) {
564-
brcmf_fw_request_nvram_done(NULL, fwctx);
565-
} else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) {
553+
if (!fw)
566554
ret = -ENOENT;
555+
556+
switch (cur->type) {
557+
case BRCMF_FW_TYPE_NVRAM:
558+
ret = brcmf_fw_request_nvram_done(fw, fwctx);
559+
break;
560+
case BRCMF_FW_TYPE_BINARY:
561+
cur->binary = fw;
562+
break;
563+
default:
564+
/* something fishy here so bail out early */
565+
brcmf_err("unknown fw type: %d\n", cur->type);
566+
release_firmware(fw);
567+
ret = -EINVAL;
567568
goto fail;
568569
}
569570

571+
if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
572+
goto fail;
573+
570574
do {
571575
if (++fwctx->curpos == fwctx->req->n_items) {
572576
ret = 0;

drivers/net/wireless/intel/iwlwifi/fw/api/scan.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
99
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
1010
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11+
* Copyright(c) 2018 Intel Corporation
1112
*
1213
* This program is free software; you can redistribute it and/or modify
1314
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +31,7 @@
3031
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
3132
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
3233
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
33-
* Copyright(c) 2018 Intel Corporation
34+
* Copyright(c) 2018 Intel Corporation
3435
* All rights reserved.
3536
*
3637
* Redistribution and use in source and binary forms, with or without
@@ -749,13 +750,9 @@ struct iwl_scan_req_umac {
749750
} __packed;
750751

751752
#define IWL_SCAN_REQ_UMAC_SIZE_V8 sizeof(struct iwl_scan_req_umac)
752-
#define IWL_SCAN_REQ_UMAC_SIZE_V7 (sizeof(struct iwl_scan_req_umac) - \
753-
4 * sizeof(u8))
754-
#define IWL_SCAN_REQ_UMAC_SIZE_V6 (sizeof(struct iwl_scan_req_umac) - \
755-
2 * sizeof(u8) - sizeof(__le16))
756-
#define IWL_SCAN_REQ_UMAC_SIZE_V1 (sizeof(struct iwl_scan_req_umac) - \
757-
2 * sizeof(__le32) - 2 * sizeof(u8) - \
758-
sizeof(__le16))
753+
#define IWL_SCAN_REQ_UMAC_SIZE_V7 48
754+
#define IWL_SCAN_REQ_UMAC_SIZE_V6 44
755+
#define IWL_SCAN_REQ_UMAC_SIZE_V1 36
759756

760757
/**
761758
* struct iwl_umac_scan_abort

drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#include "iwl-io.h"
7777
#include "iwl-csr.h"
7878
#include "fw/acpi.h"
79+
#include "fw/api/nvm-reg.h"
7980

8081
/* NVM offsets (in words) definitions */
8182
enum nvm_offsets {
@@ -146,8 +147,8 @@ static const u8 iwl_ext_nvm_channels[] = {
146147
149, 153, 157, 161, 165, 169, 173, 177, 181
147148
};
148149

149-
#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
150-
#define IWL_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels)
150+
#define IWL_NVM_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
151+
#define IWL_NVM_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels)
151152
#define NUM_2GHZ_CHANNELS 14
152153
#define NUM_2GHZ_CHANNELS_EXT 14
153154
#define FIRST_2GHZ_HT_MINUS 5
@@ -301,11 +302,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
301302
const u8 *nvm_chan;
302303

303304
if (cfg->nvm_type != IWL_NVM_EXT) {
304-
num_of_ch = IWL_NUM_CHANNELS;
305+
num_of_ch = IWL_NVM_NUM_CHANNELS;
305306
nvm_chan = &iwl_nvm_channels[0];
306307
num_2ghz_channels = NUM_2GHZ_CHANNELS;
307308
} else {
308-
num_of_ch = IWL_NUM_CHANNELS_EXT;
309+
num_of_ch = IWL_NVM_NUM_CHANNELS_EXT;
309310
nvm_chan = &iwl_ext_nvm_channels[0];
310311
num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT;
311312
}
@@ -720,12 +721,12 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
720721
if (cfg->nvm_type != IWL_NVM_EXT)
721722
data = kzalloc(sizeof(*data) +
722723
sizeof(struct ieee80211_channel) *
723-
IWL_NUM_CHANNELS,
724+
IWL_NVM_NUM_CHANNELS,
724725
GFP_KERNEL);
725726
else
726727
data = kzalloc(sizeof(*data) +
727728
sizeof(struct ieee80211_channel) *
728-
IWL_NUM_CHANNELS_EXT,
729+
IWL_NVM_NUM_CHANNELS_EXT,
729730
GFP_KERNEL);
730731
if (!data)
731732
return NULL;
@@ -842,24 +843,34 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
842843
return flags;
843844
}
844845

846+
struct regdb_ptrs {
847+
struct ieee80211_wmm_rule *rule;
848+
u32 token;
849+
};
850+
845851
struct ieee80211_regdomain *
846852
iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
847-
int num_of_ch, __le32 *channels, u16 fw_mcc)
853+
int num_of_ch, __le32 *channels, u16 fw_mcc,
854+
u16 geo_info)
848855
{
849856
int ch_idx;
850857
u16 ch_flags;
851858
u32 reg_rule_flags, prev_reg_rule_flags = 0;
852859
const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
853860
iwl_ext_nvm_channels : iwl_nvm_channels;
854-
struct ieee80211_regdomain *regd;
855-
int size_of_regd;
861+
struct ieee80211_regdomain *regd, *copy_rd;
862+
int size_of_regd, regd_to_copy, wmms_to_copy;
863+
int size_of_wmms = 0;
856864
struct ieee80211_reg_rule *rule;
865+
struct ieee80211_wmm_rule *wmm_rule, *d_wmm, *s_wmm;
866+
struct regdb_ptrs *regdb_ptrs;
857867
enum nl80211_band band;
858868
int center_freq, prev_center_freq = 0;
859-
int valid_rules = 0;
869+
int valid_rules = 0, n_wmms = 0;
870+
int i;
860871
bool new_rule;
861872
int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
862-
IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS;
873+
IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS;
863874

864875
if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
865876
return ERR_PTR(-EINVAL);
@@ -875,10 +886,26 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
875886
sizeof(struct ieee80211_regdomain) +
876887
num_of_ch * sizeof(struct ieee80211_reg_rule);
877888

878-
regd = kzalloc(size_of_regd, GFP_KERNEL);
889+
if (geo_info & GEO_WMM_ETSI_5GHZ_INFO)
890+
size_of_wmms =
891+
num_of_ch * sizeof(struct ieee80211_wmm_rule);
892+
893+
regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL);
879894
if (!regd)
880895
return ERR_PTR(-ENOMEM);
881896

897+
regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL);
898+
if (!regdb_ptrs) {
899+
copy_rd = ERR_PTR(-ENOMEM);
900+
goto out;
901+
}
902+
903+
/* set alpha2 from FW. */
904+
regd->alpha2[0] = fw_mcc >> 8;
905+
regd->alpha2[1] = fw_mcc & 0xff;
906+
907+
wmm_rule = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd);
908+
882909
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
883910
ch_flags = (u16)__le32_to_cpup(channels + ch_idx);
884911
band = (ch_idx < NUM_2GHZ_CHANNELS) ?
@@ -927,14 +954,66 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
927954

928955
iwl_nvm_print_channel_flags(dev, IWL_DL_LAR,
929956
nvm_chan[ch_idx], ch_flags);
957+
958+
if (!(geo_info & GEO_WMM_ETSI_5GHZ_INFO) ||
959+
band == NL80211_BAND_2GHZ)
960+
continue;
961+
962+
if (!reg_query_regdb_wmm(regd->alpha2, center_freq,
963+
&regdb_ptrs[n_wmms].token, wmm_rule)) {
964+
/* Add only new rules */
965+
for (i = 0; i < n_wmms; i++) {
966+
if (regdb_ptrs[i].token ==
967+
regdb_ptrs[n_wmms].token) {
968+
rule->wmm_rule = regdb_ptrs[i].rule;
969+
break;
970+
}
971+
}
972+
if (i == n_wmms) {
973+
rule->wmm_rule = wmm_rule;
974+
regdb_ptrs[n_wmms++].rule = wmm_rule;
975+
wmm_rule++;
976+
}
977+
}
930978
}
931979

932980
regd->n_reg_rules = valid_rules;
981+
regd->n_wmm_rules = n_wmms;
933982

934-
/* set alpha2 from FW. */
935-
regd->alpha2[0] = fw_mcc >> 8;
936-
regd->alpha2[1] = fw_mcc & 0xff;
983+
/*
984+
* Narrow down regdom for unused regulatory rules to prevent hole
985+
* between reg rules to wmm rules.
986+
*/
987+
regd_to_copy = sizeof(struct ieee80211_regdomain) +
988+
valid_rules * sizeof(struct ieee80211_reg_rule);
989+
990+
wmms_to_copy = sizeof(struct ieee80211_wmm_rule) * n_wmms;
991+
992+
copy_rd = kzalloc(regd_to_copy + wmms_to_copy, GFP_KERNEL);
993+
if (!copy_rd) {
994+
copy_rd = ERR_PTR(-ENOMEM);
995+
goto out;
996+
}
997+
998+
memcpy(copy_rd, regd, regd_to_copy);
999+
memcpy((u8 *)copy_rd + regd_to_copy, (u8 *)regd + size_of_regd,
1000+
wmms_to_copy);
1001+
1002+
d_wmm = (struct ieee80211_wmm_rule *)((u8 *)copy_rd + regd_to_copy);
1003+
s_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd);
1004+
1005+
for (i = 0; i < regd->n_reg_rules; i++) {
1006+
if (!regd->reg_rules[i].wmm_rule)
1007+
continue;
1008+
1009+
copy_rd->reg_rules[i].wmm_rule = d_wmm +
1010+
(regd->reg_rules[i].wmm_rule - s_wmm) /
1011+
sizeof(struct ieee80211_wmm_rule);
1012+
}
9371013

938-
return regd;
1014+
out:
1015+
kfree(regdb_ptrs);
1016+
kfree(regd);
1017+
return copy_rd;
9391018
}
9401019
IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info);

drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
101101
*
102102
* This function parses the regulatory channel data received as a
103103
* MCC_UPDATE_CMD command. It returns a newly allocation regulatory domain,
104-
* to be fed into the regulatory core. An ERR_PTR is returned on error.
104+
* to be fed into the regulatory core. In case the geo_info is set handle
105+
* accordingly. An ERR_PTR is returned on error.
105106
* If not given to the regulatory core, the user is responsible for freeing
106107
* the regdomain returned here with kfree.
107108
*/
108109
struct ieee80211_regdomain *
109110
iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
110-
int num_of_ch, __le32 *channels, u16 fw_mcc);
111+
int num_of_ch, __le32 *channels, u16 fw_mcc,
112+
u16 geo_info);
111113

112114
#endif /* __iwl_nvm_parse_h__ */

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
311311
regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
312312
__le32_to_cpu(resp->n_channels),
313313
resp->channels,
314-
__le16_to_cpu(resp->mcc));
314+
__le16_to_cpu(resp->mcc),
315+
__le16_to_cpu(resp->geo_info));
315316
/* Store the return source id */
316317
src_id = resp->source_id;
317318
kfree(resp);

drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,6 @@ static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
158158

159159
static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
160160
{
161-
struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
162-
163-
/* override ant_num / ant_path */
164-
if (mod_params->ant_sel) {
165-
rtlpriv->btcoexist.btc_info.ant_num =
166-
(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
167-
168-
rtlpriv->btcoexist.btc_info.single_ant_path =
169-
(mod_params->ant_sel == 1 ? 0 : 1);
170-
}
171161
return rtlpriv->btcoexist.btc_info.single_ant_path;
172162
}
173163

@@ -178,18 +168,13 @@ static u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
178168

179169
static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
180170
{
181-
struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
182171
u8 num;
183172

184173
if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
185174
num = 2;
186175
else
187176
num = 1;
188177

189-
/* override ant_num / ant_path */
190-
if (mod_params->ant_sel)
191-
num = (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1) + 1;
192-
193178
return num;
194179
}
195180

drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,9 @@ static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
848848
return false;
849849
}
850850

851+
if (rtlpriv->cfg->ops->get_btc_status())
852+
rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv);
853+
851854
bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
852855
rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
853856

@@ -2696,21 +2699,21 @@ void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
26962699
rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
26972700
rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
26982701
rtlpriv->btcoexist.btc_info.single_ant_path =
2699-
(value & 0x40); /*0xc3[6]*/
2702+
(value & 0x40 ? ANT_AUX : ANT_MAIN); /*0xc3[6]*/
27002703
} else {
27012704
rtlpriv->btcoexist.btc_info.btcoexist = 0;
27022705
rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
27032706
rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
2704-
rtlpriv->btcoexist.btc_info.single_ant_path = 0;
2707+
rtlpriv->btcoexist.btc_info.single_ant_path = ANT_MAIN;
27052708
}
27062709

27072710
/* override ant_num / ant_path */
27082711
if (mod_params->ant_sel) {
27092712
rtlpriv->btcoexist.btc_info.ant_num =
2710-
(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
2713+
(mod_params->ant_sel == 1 ? ANT_X1 : ANT_X2);
27112714

27122715
rtlpriv->btcoexist.btc_info.single_ant_path =
2713-
(mod_params->ant_sel == 1 ? 0 : 1);
2716+
(mod_params->ant_sel == 1 ? ANT_AUX : ANT_MAIN);
27142717
}
27152718
}
27162719

drivers/net/wireless/realtek/rtlwifi/wifi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,6 +2823,11 @@ enum bt_ant_num {
28232823
ANT_X1 = 1,
28242824
};
28252825

2826+
enum bt_ant_path {
2827+
ANT_MAIN = 0,
2828+
ANT_AUX = 1,
2829+
};
2830+
28262831
enum bt_co_type {
28272832
BT_2WIRE = 0,
28282833
BT_ISSC_3WIRE = 1,

0 commit comments

Comments
 (0)