diff options
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 326 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/include/brcmu_wifi.h | 28 |
3 files changed, 278 insertions, 82 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index c7fa20846b32..b4b970038799 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -72,6 +72,7 @@ | |||
72 | #define BRCMF_C_SET_WSEC 134 | 72 | #define BRCMF_C_SET_WSEC 134 |
73 | #define BRCMF_C_GET_PHY_NOISE 135 | 73 | #define BRCMF_C_GET_PHY_NOISE 135 |
74 | #define BRCMF_C_GET_BSS_INFO 136 | 74 | #define BRCMF_C_GET_BSS_INFO 136 |
75 | #define BRCMF_C_GET_BANDLIST 140 | ||
75 | #define BRCMF_C_SET_SCB_TIMEOUT 158 | 76 | #define BRCMF_C_SET_SCB_TIMEOUT 158 |
76 | #define BRCMF_C_GET_PHYLIST 180 | 77 | #define BRCMF_C_GET_PHYLIST 180 |
77 | #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 | 78 | #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 |
@@ -475,6 +476,11 @@ struct brcmf_sta_info_le { | |||
475 | __le32 rx_decrypt_failures; /* # of packet decrypted failed */ | 476 | __le32 rx_decrypt_failures; /* # of packet decrypted failed */ |
476 | }; | 477 | }; |
477 | 478 | ||
479 | struct brcmf_chanspec_list { | ||
480 | __le32 count; /* # of entries */ | ||
481 | __le32 element[1]; /* variable length uint32 list */ | ||
482 | }; | ||
483 | |||
478 | /* | 484 | /* |
479 | * WLC_E_PROBRESP_MSG | 485 | * WLC_E_PROBRESP_MSG |
480 | * WLC_E_P2P_PROBREQ_MSG | 486 | * WLC_E_P2P_PROBREQ_MSG |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 804473fc5c5e..c7459ae8254a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -182,64 +182,6 @@ static struct ieee80211_channel __wl_5ghz_a_channels[] = { | |||
182 | CHAN5G(216, 0), | 182 | CHAN5G(216, 0), |
183 | }; | 183 | }; |
184 | 184 | ||
185 | static struct ieee80211_channel __wl_5ghz_n_channels[] = { | ||
186 | CHAN5G(32, 0), CHAN5G(34, 0), | ||
187 | CHAN5G(36, 0), CHAN5G(38, 0), | ||
188 | CHAN5G(40, 0), CHAN5G(42, 0), | ||
189 | CHAN5G(44, 0), CHAN5G(46, 0), | ||
190 | CHAN5G(48, 0), CHAN5G(50, 0), | ||
191 | CHAN5G(52, 0), CHAN5G(54, 0), | ||
192 | CHAN5G(56, 0), CHAN5G(58, 0), | ||
193 | CHAN5G(60, 0), CHAN5G(62, 0), | ||
194 | CHAN5G(64, 0), CHAN5G(66, 0), | ||
195 | CHAN5G(68, 0), CHAN5G(70, 0), | ||
196 | CHAN5G(72, 0), CHAN5G(74, 0), | ||
197 | CHAN5G(76, 0), CHAN5G(78, 0), | ||
198 | CHAN5G(80, 0), CHAN5G(82, 0), | ||
199 | CHAN5G(84, 0), CHAN5G(86, 0), | ||
200 | CHAN5G(88, 0), CHAN5G(90, 0), | ||
201 | CHAN5G(92, 0), CHAN5G(94, 0), | ||
202 | CHAN5G(96, 0), CHAN5G(98, 0), | ||
203 | CHAN5G(100, 0), CHAN5G(102, 0), | ||
204 | CHAN5G(104, 0), CHAN5G(106, 0), | ||
205 | CHAN5G(108, 0), CHAN5G(110, 0), | ||
206 | CHAN5G(112, 0), CHAN5G(114, 0), | ||
207 | CHAN5G(116, 0), CHAN5G(118, 0), | ||
208 | CHAN5G(120, 0), CHAN5G(122, 0), | ||
209 | CHAN5G(124, 0), CHAN5G(126, 0), | ||
210 | CHAN5G(128, 0), CHAN5G(130, 0), | ||
211 | CHAN5G(132, 0), CHAN5G(134, 0), | ||
212 | CHAN5G(136, 0), CHAN5G(138, 0), | ||
213 | CHAN5G(140, 0), CHAN5G(142, 0), | ||
214 | CHAN5G(144, 0), CHAN5G(145, 0), | ||
215 | CHAN5G(146, 0), CHAN5G(147, 0), | ||
216 | CHAN5G(148, 0), CHAN5G(149, 0), | ||
217 | CHAN5G(150, 0), CHAN5G(151, 0), | ||
218 | CHAN5G(152, 0), CHAN5G(153, 0), | ||
219 | CHAN5G(154, 0), CHAN5G(155, 0), | ||
220 | CHAN5G(156, 0), CHAN5G(157, 0), | ||
221 | CHAN5G(158, 0), CHAN5G(159, 0), | ||
222 | CHAN5G(160, 0), CHAN5G(161, 0), | ||
223 | CHAN5G(162, 0), CHAN5G(163, 0), | ||
224 | CHAN5G(164, 0), CHAN5G(165, 0), | ||
225 | CHAN5G(166, 0), CHAN5G(168, 0), | ||
226 | CHAN5G(170, 0), CHAN5G(172, 0), | ||
227 | CHAN5G(174, 0), CHAN5G(176, 0), | ||
228 | CHAN5G(178, 0), CHAN5G(180, 0), | ||
229 | CHAN5G(182, 0), CHAN5G(184, 0), | ||
230 | CHAN5G(186, 0), CHAN5G(188, 0), | ||
231 | CHAN5G(190, 0), CHAN5G(192, 0), | ||
232 | CHAN5G(194, 0), CHAN5G(196, 0), | ||
233 | CHAN5G(198, 0), CHAN5G(200, 0), | ||
234 | CHAN5G(202, 0), CHAN5G(204, 0), | ||
235 | CHAN5G(206, 0), CHAN5G(208, 0), | ||
236 | CHAN5G(210, 0), CHAN5G(212, 0), | ||
237 | CHAN5G(214, 0), CHAN5G(216, 0), | ||
238 | CHAN5G(218, 0), CHAN5G(220, 0), | ||
239 | CHAN5G(222, 0), CHAN5G(224, 0), | ||
240 | CHAN5G(226, 0), CHAN5G(228, 0), | ||
241 | }; | ||
242 | |||
243 | static struct ieee80211_supported_band __wl_band_2ghz = { | 185 | static struct ieee80211_supported_band __wl_band_2ghz = { |
244 | .band = IEEE80211_BAND_2GHZ, | 186 | .band = IEEE80211_BAND_2GHZ, |
245 | .channels = __wl_2ghz_channels, | 187 | .channels = __wl_2ghz_channels, |
@@ -256,12 +198,28 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = { | |||
256 | .n_bitrates = wl_a_rates_size, | 198 | .n_bitrates = wl_a_rates_size, |
257 | }; | 199 | }; |
258 | 200 | ||
259 | static struct ieee80211_supported_band __wl_band_5ghz_n = { | 201 | /* This is to override regulatory domains defined in cfg80211 module (reg.c) |
260 | .band = IEEE80211_BAND_5GHZ, | 202 | * By default world regulatory domain defined in reg.c puts the flags |
261 | .channels = __wl_5ghz_n_channels, | 203 | * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for |
262 | .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels), | 204 | * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't |
263 | .bitrates = wl_a_rates, | 205 | * start p2p operations on 5GHz channels. All the changes in world regulatory |
264 | .n_bitrates = wl_a_rates_size, | 206 | * domain are to be done here. |
207 | */ | ||
208 | static const struct ieee80211_regdomain brcmf_regdom = { | ||
209 | .n_reg_rules = 4, | ||
210 | .alpha2 = "99", | ||
211 | .reg_rules = { | ||
212 | /* IEEE 802.11b/g, channels 1..11 */ | ||
213 | REG_RULE(2412-10, 2472+10, 40, 6, 20, 0), | ||
214 | /* If any */ | ||
215 | /* IEEE 802.11 channel 14 - Only JP enables | ||
216 | * this and for 802.11b only | ||
217 | */ | ||
218 | REG_RULE(2484-10, 2484+10, 20, 6, 20, 0), | ||
219 | /* IEEE 802.11a, channel 36..64 */ | ||
220 | REG_RULE(5150-10, 5350+10, 40, 6, 20, 0), | ||
221 | /* IEEE 802.11a, channel 100..165 */ | ||
222 | REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), } | ||
265 | }; | 223 | }; |
266 | 224 | ||
267 | static const u32 __wl_cipher_suites[] = { | 225 | static const u32 __wl_cipher_suites[] = { |
@@ -4188,13 +4146,6 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | |||
4188 | wiphy->iface_combinations = brcmf_iface_combos; | 4146 | wiphy->iface_combinations = brcmf_iface_combos; |
4189 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); | 4147 | wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); |
4190 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; | 4148 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; |
4191 | wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set | ||
4192 | * it as 11a by default. | ||
4193 | * This will be updated with | ||
4194 | * 11n phy tables in | ||
4195 | * "ifconfig up" | ||
4196 | * if phy has 11n capability | ||
4197 | */ | ||
4198 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 4149 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
4199 | wiphy->cipher_suites = __wl_cipher_suites; | 4150 | wiphy->cipher_suites = __wl_cipher_suites; |
4200 | wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); | 4151 | wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); |
@@ -4204,6 +4155,9 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | |||
4204 | wiphy->mgmt_stypes = brcmf_txrx_stypes; | 4155 | wiphy->mgmt_stypes = brcmf_txrx_stypes; |
4205 | wiphy->max_remain_on_channel_duration = 5000; | 4156 | wiphy->max_remain_on_channel_duration = 5000; |
4206 | brcmf_wiphy_pno_params(wiphy); | 4157 | brcmf_wiphy_pno_params(wiphy); |
4158 | brcmf_dbg(INFO, "Registering custom regulatory\n"); | ||
4159 | wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; | ||
4160 | wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); | ||
4207 | err = wiphy_register(wiphy); | 4161 | err = wiphy_register(wiphy); |
4208 | if (err < 0) { | 4162 | if (err < 0) { |
4209 | brcmf_err("Could not register wiphy device (%d)\n", err); | 4163 | brcmf_err("Could not register wiphy device (%d)\n", err); |
@@ -4927,34 +4881,248 @@ dongle_scantime_out: | |||
4927 | return err; | 4881 | return err; |
4928 | } | 4882 | } |
4929 | 4883 | ||
4930 | static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) | 4884 | |
4885 | static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | ||
4886 | { | ||
4887 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
4888 | struct ieee80211_channel *band_chan_arr; | ||
4889 | struct brcmf_chanspec_list *list; | ||
4890 | s32 err; | ||
4891 | u8 *pbuf; | ||
4892 | u32 i, j; | ||
4893 | u32 total; | ||
4894 | u16 chanspec; | ||
4895 | enum ieee80211_band band; | ||
4896 | u32 channel; | ||
4897 | u32 *n_cnt; | ||
4898 | bool ht40_allowed; | ||
4899 | u32 index; | ||
4900 | u32 ht40_flag; | ||
4901 | bool update; | ||
4902 | u32 array_size; | ||
4903 | |||
4904 | pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); | ||
4905 | |||
4906 | if (pbuf == NULL) | ||
4907 | return -ENOMEM; | ||
4908 | |||
4909 | list = (struct brcmf_chanspec_list *)pbuf; | ||
4910 | |||
4911 | err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf, | ||
4912 | BRCMF_DCMD_MEDLEN); | ||
4913 | if (err) { | ||
4914 | brcmf_err("get chanspecs error (%d)\n", err); | ||
4915 | goto exit; | ||
4916 | } | ||
4917 | |||
4918 | __wl_band_2ghz.n_channels = 0; | ||
4919 | __wl_band_5ghz_a.n_channels = 0; | ||
4920 | |||
4921 | total = le32_to_cpu(list->count); | ||
4922 | for (i = 0; i < total; i++) { | ||
4923 | chanspec = (u16)le32_to_cpu(list->element[i]); | ||
4924 | channel = CHSPEC_CHANNEL(chanspec); | ||
4925 | |||
4926 | if (CHSPEC_IS40(chanspec)) { | ||
4927 | if (CHSPEC_SB_UPPER(chanspec)) | ||
4928 | channel += CH_10MHZ_APART; | ||
4929 | else | ||
4930 | channel -= CH_10MHZ_APART; | ||
4931 | } else if (CHSPEC_IS80(chanspec)) { | ||
4932 | brcmf_dbg(INFO, "HT80 center channel : %d\n", | ||
4933 | channel); | ||
4934 | continue; | ||
4935 | } | ||
4936 | if (CHSPEC_IS2G(chanspec) && (channel >= CH_MIN_2G_CHANNEL) && | ||
4937 | (channel <= CH_MAX_2G_CHANNEL)) { | ||
4938 | band_chan_arr = __wl_2ghz_channels; | ||
4939 | array_size = ARRAY_SIZE(__wl_2ghz_channels); | ||
4940 | n_cnt = &__wl_band_2ghz.n_channels; | ||
4941 | band = IEEE80211_BAND_2GHZ; | ||
4942 | ht40_allowed = (bw_cap == WLC_N_BW_40ALL); | ||
4943 | } else if (CHSPEC_IS5G(chanspec) && | ||
4944 | channel >= CH_MIN_5G_CHANNEL) { | ||
4945 | band_chan_arr = __wl_5ghz_a_channels; | ||
4946 | array_size = ARRAY_SIZE(__wl_5ghz_a_channels); | ||
4947 | n_cnt = &__wl_band_5ghz_a.n_channels; | ||
4948 | band = IEEE80211_BAND_5GHZ; | ||
4949 | ht40_allowed = !(bw_cap == WLC_N_BW_20ALL); | ||
4950 | } else { | ||
4951 | brcmf_err("Invalid channel Sepc. 0x%x.\n", chanspec); | ||
4952 | continue; | ||
4953 | } | ||
4954 | if (!ht40_allowed && CHSPEC_IS40(chanspec)) | ||
4955 | continue; | ||
4956 | update = false; | ||
4957 | for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { | ||
4958 | if (band_chan_arr[j].hw_value == channel) { | ||
4959 | update = true; | ||
4960 | break; | ||
4961 | } | ||
4962 | } | ||
4963 | if (update) | ||
4964 | index = j; | ||
4965 | else | ||
4966 | index = *n_cnt; | ||
4967 | if (index < array_size) { | ||
4968 | band_chan_arr[index].center_freq = | ||
4969 | ieee80211_channel_to_frequency(channel, band); | ||
4970 | band_chan_arr[index].hw_value = channel; | ||
4971 | |||
4972 | if (CHSPEC_IS40(chanspec) && ht40_allowed) { | ||
4973 | /* assuming the order is HT20, HT40 Upper, | ||
4974 | * HT40 lower from chanspecs | ||
4975 | */ | ||
4976 | ht40_flag = band_chan_arr[index].flags & | ||
4977 | IEEE80211_CHAN_NO_HT40; | ||
4978 | if (CHSPEC_SB_UPPER(chanspec)) { | ||
4979 | if (ht40_flag == IEEE80211_CHAN_NO_HT40) | ||
4980 | band_chan_arr[index].flags &= | ||
4981 | ~IEEE80211_CHAN_NO_HT40; | ||
4982 | band_chan_arr[index].flags |= | ||
4983 | IEEE80211_CHAN_NO_HT40PLUS; | ||
4984 | } else { | ||
4985 | /* It should be one of | ||
4986 | * IEEE80211_CHAN_NO_HT40 or | ||
4987 | * IEEE80211_CHAN_NO_HT40PLUS | ||
4988 | */ | ||
4989 | band_chan_arr[index].flags &= | ||
4990 | ~IEEE80211_CHAN_NO_HT40; | ||
4991 | if (ht40_flag == IEEE80211_CHAN_NO_HT40) | ||
4992 | band_chan_arr[index].flags |= | ||
4993 | IEEE80211_CHAN_NO_HT40MINUS; | ||
4994 | } | ||
4995 | } else { | ||
4996 | band_chan_arr[index].flags = | ||
4997 | IEEE80211_CHAN_NO_HT40; | ||
4998 | if (band == IEEE80211_BAND_2GHZ) | ||
4999 | channel |= WL_CHANSPEC_BAND_2G; | ||
5000 | else | ||
5001 | channel |= WL_CHANSPEC_BAND_5G; | ||
5002 | channel |= WL_CHANSPEC_BW_20; | ||
5003 | err = brcmf_fil_bsscfg_int_get(ifp, | ||
5004 | "per_chan_info", | ||
5005 | &channel); | ||
5006 | if (!err) { | ||
5007 | if (channel & WL_CHAN_RADAR) | ||
5008 | band_chan_arr[index].flags |= | ||
5009 | (IEEE80211_CHAN_RADAR | | ||
5010 | IEEE80211_CHAN_NO_IBSS); | ||
5011 | if (channel & WL_CHAN_PASSIVE) | ||
5012 | band_chan_arr[index].flags |= | ||
5013 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
5014 | } | ||
5015 | } | ||
5016 | if (!update) | ||
5017 | (*n_cnt)++; | ||
5018 | } | ||
5019 | } | ||
5020 | exit: | ||
5021 | kfree(pbuf); | ||
5022 | return err; | ||
5023 | } | ||
5024 | |||
5025 | |||
5026 | static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) | ||
4931 | { | 5027 | { |
4932 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 5028 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |
4933 | struct wiphy *wiphy; | 5029 | struct wiphy *wiphy; |
4934 | s32 phy_list; | 5030 | s32 phy_list; |
5031 | u32 band_list[3]; | ||
5032 | u32 nmode; | ||
5033 | u32 bw_cap = 0; | ||
4935 | s8 phy; | 5034 | s8 phy; |
4936 | s32 err = 0; | 5035 | s32 err; |
5036 | u32 nband; | ||
5037 | s32 i; | ||
5038 | struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; | ||
5039 | s32 index; | ||
4937 | 5040 | ||
4938 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, | 5041 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, |
4939 | &phy_list, sizeof(phy_list)); | 5042 | &phy_list, sizeof(phy_list)); |
4940 | if (err) { | 5043 | if (err) { |
4941 | brcmf_err("error (%d)\n", err); | 5044 | brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err); |
4942 | return err; | 5045 | return err; |
4943 | } | 5046 | } |
4944 | 5047 | ||
4945 | phy = ((char *)&phy_list)[0]; | 5048 | phy = ((char *)&phy_list)[0]; |
4946 | brcmf_dbg(INFO, "%c phy\n", phy); | 5049 | brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy); |
4947 | if (phy == 'n' || phy == 'a') { | 5050 | |
4948 | wiphy = cfg_to_wiphy(cfg); | 5051 | |
4949 | wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; | 5052 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, |
5053 | &band_list, sizeof(band_list)); | ||
5054 | if (err) { | ||
5055 | brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err); | ||
5056 | return err; | ||
4950 | } | 5057 | } |
5058 | brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n", | ||
5059 | band_list[0], band_list[1], band_list[2]); | ||
5060 | |||
5061 | err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); | ||
5062 | if (err) { | ||
5063 | brcmf_err("nmode error (%d)\n", err); | ||
5064 | } else { | ||
5065 | err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap); | ||
5066 | if (err) | ||
5067 | brcmf_err("mimo_bw_cap error (%d)\n", err); | ||
5068 | } | ||
5069 | brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap); | ||
5070 | |||
5071 | err = brcmf_construct_reginfo(cfg, bw_cap); | ||
5072 | if (err) { | ||
5073 | brcmf_err("brcmf_construct_reginfo failed (%d)\n", err); | ||
5074 | return err; | ||
5075 | } | ||
5076 | |||
5077 | nband = band_list[0]; | ||
5078 | memset(bands, 0, sizeof(bands)); | ||
5079 | |||
5080 | for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) { | ||
5081 | index = -1; | ||
5082 | if ((band_list[i] == WLC_BAND_5G) && | ||
5083 | (__wl_band_5ghz_a.n_channels > 0)) { | ||
5084 | index = IEEE80211_BAND_5GHZ; | ||
5085 | bands[index] = &__wl_band_5ghz_a; | ||
5086 | if ((bw_cap == WLC_N_BW_40ALL) || | ||
5087 | (bw_cap == WLC_N_BW_20IN2G_40IN5G)) | ||
5088 | bands[index]->ht_cap.cap |= | ||
5089 | IEEE80211_HT_CAP_SGI_40; | ||
5090 | } else if ((band_list[i] == WLC_BAND_2G) && | ||
5091 | (__wl_band_2ghz.n_channels > 0)) { | ||
5092 | index = IEEE80211_BAND_2GHZ; | ||
5093 | bands[index] = &__wl_band_2ghz; | ||
5094 | if (bw_cap == WLC_N_BW_40ALL) | ||
5095 | bands[index]->ht_cap.cap |= | ||
5096 | IEEE80211_HT_CAP_SGI_40; | ||
5097 | } | ||
5098 | |||
5099 | if ((index >= 0) && nmode) { | ||
5100 | bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; | ||
5101 | bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; | ||
5102 | bands[index]->ht_cap.ht_supported = true; | ||
5103 | bands[index]->ht_cap.ampdu_factor = | ||
5104 | IEEE80211_HT_MAX_AMPDU_64K; | ||
5105 | bands[index]->ht_cap.ampdu_density = | ||
5106 | IEEE80211_HT_MPDU_DENSITY_16; | ||
5107 | /* An HT shall support all EQM rates for one spatial | ||
5108 | * stream | ||
5109 | */ | ||
5110 | bands[index]->ht_cap.mcs.rx_mask[0] = 0xff; | ||
5111 | } | ||
5112 | } | ||
5113 | |||
5114 | wiphy = cfg_to_wiphy(cfg); | ||
5115 | wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ]; | ||
5116 | wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ]; | ||
5117 | wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); | ||
4951 | 5118 | ||
4952 | return err; | 5119 | return err; |
4953 | } | 5120 | } |
4954 | 5121 | ||
5122 | |||
4955 | static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg) | 5123 | static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg) |
4956 | { | 5124 | { |
4957 | return wl_update_wiphybands(cfg); | 5125 | return brcmf_update_wiphybands(cfg); |
4958 | } | 5126 | } |
4959 | 5127 | ||
4960 | static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) | 5128 | static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) |
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h index c11a290a1edf..0505cc065e0d 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h | |||
@@ -32,8 +32,9 @@ | |||
32 | #define CH_20MHZ_APART 4 | 32 | #define CH_20MHZ_APART 4 |
33 | #define CH_10MHZ_APART 2 | 33 | #define CH_10MHZ_APART 2 |
34 | #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ | 34 | #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ |
35 | #define CH_MIN_2G_CHANNEL 1 | ||
35 | #define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ | 36 | #define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ |
36 | #define BRCM_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */ | 37 | #define CH_MIN_5G_CHANNEL 34 |
37 | 38 | ||
38 | /* bandstate array indices */ | 39 | /* bandstate array indices */ |
39 | #define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ | 40 | #define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ |
@@ -60,6 +61,7 @@ | |||
60 | #define WL_CHANSPEC_BW_10 0x0400 | 61 | #define WL_CHANSPEC_BW_10 0x0400 |
61 | #define WL_CHANSPEC_BW_20 0x0800 | 62 | #define WL_CHANSPEC_BW_20 0x0800 |
62 | #define WL_CHANSPEC_BW_40 0x0C00 | 63 | #define WL_CHANSPEC_BW_40 0x0C00 |
64 | #define WL_CHANSPEC_BW_80 0x2000 | ||
63 | 65 | ||
64 | #define WL_CHANSPEC_BAND_MASK 0xf000 | 66 | #define WL_CHANSPEC_BAND_MASK 0xf000 |
65 | #define WL_CHANSPEC_BAND_SHIFT 12 | 67 | #define WL_CHANSPEC_BAND_SHIFT 12 |
@@ -67,6 +69,25 @@ | |||
67 | #define WL_CHANSPEC_BAND_2G 0x2000 | 69 | #define WL_CHANSPEC_BAND_2G 0x2000 |
68 | #define INVCHANSPEC 255 | 70 | #define INVCHANSPEC 255 |
69 | 71 | ||
72 | #define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ | ||
73 | #define WL_CHAN_VALID_SW (1 << 1) /* valid with country sett. */ | ||
74 | #define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */ | ||
75 | #define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ | ||
76 | #define WL_CHAN_INACTIVE (1 << 4) /* inactive due to radar */ | ||
77 | #define WL_CHAN_PASSIVE (1 << 5) /* channel in passive mode */ | ||
78 | #define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */ | ||
79 | |||
80 | /* values for band specific 40MHz capabilities */ | ||
81 | #define WLC_N_BW_20ALL 0 | ||
82 | #define WLC_N_BW_40ALL 1 | ||
83 | #define WLC_N_BW_20IN2G_40IN5G 2 | ||
84 | |||
85 | /* band types */ | ||
86 | #define WLC_BAND_AUTO 0 /* auto-select */ | ||
87 | #define WLC_BAND_5G 1 /* 5 Ghz */ | ||
88 | #define WLC_BAND_2G 2 /* 2.4 Ghz */ | ||
89 | #define WLC_BAND_ALL 3 /* all bands */ | ||
90 | |||
70 | #define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) | 91 | #define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) |
71 | #define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) | 92 | #define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) |
72 | 93 | ||
@@ -79,10 +100,11 @@ | |||
79 | #define CHSPEC_IS20(chspec) \ | 100 | #define CHSPEC_IS20(chspec) \ |
80 | (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) | 101 | (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) |
81 | 102 | ||
82 | #ifndef CHSPEC_IS40 | ||
83 | #define CHSPEC_IS40(chspec) \ | 103 | #define CHSPEC_IS40(chspec) \ |
84 | (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) | 104 | (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) |
85 | #endif | 105 | |
106 | #define CHSPEC_IS80(chspec) \ | ||
107 | (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80) | ||
86 | 108 | ||
87 | #define CHSPEC_IS5G(chspec) \ | 109 | #define CHSPEC_IS5G(chspec) \ |
88 | (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) | 110 | (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) |