0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/etherdevice.h>
0010 #include <linux/module.h>
0011 #include <linux/vmalloc.h>
0012 #include <net/cfg80211.h>
0013 #include <net/netlink.h>
0014 #include <uapi/linux/if_arp.h>
0015
0016 #include <brcmu_utils.h>
0017 #include <defs.h>
0018 #include <brcmu_wifi.h>
0019 #include <brcm_hw_ids.h>
0020 #include "core.h"
0021 #include "debug.h"
0022 #include "tracepoint.h"
0023 #include "fwil_types.h"
0024 #include "p2p.h"
0025 #include "btcoex.h"
0026 #include "pno.h"
0027 #include "fwsignal.h"
0028 #include "cfg80211.h"
0029 #include "feature.h"
0030 #include "fwil.h"
0031 #include "proto.h"
0032 #include "vendor.h"
0033 #include "bus.h"
0034 #include "common.h"
0035
0036 #define BRCMF_SCAN_IE_LEN_MAX 2048
0037
0038 #define WPA_OUI "\x00\x50\xF2"
0039 #define WPA_OUI_TYPE 1
0040 #define RSN_OUI "\x00\x0F\xAC"
0041 #define WME_OUI_TYPE 2
0042 #define WPS_OUI_TYPE 4
0043
0044 #define VS_IE_FIXED_HDR_LEN 6
0045 #define WPA_IE_VERSION_LEN 2
0046 #define WPA_IE_MIN_OUI_LEN 4
0047 #define WPA_IE_SUITE_COUNT_LEN 2
0048
0049 #define WPA_CIPHER_NONE 0
0050 #define WPA_CIPHER_WEP_40 1
0051 #define WPA_CIPHER_TKIP 2
0052 #define WPA_CIPHER_AES_CCM 4
0053 #define WPA_CIPHER_WEP_104 5
0054
0055 #define RSN_AKM_NONE 0
0056 #define RSN_AKM_UNSPECIFIED 1
0057 #define RSN_AKM_PSK 2
0058 #define RSN_AKM_SHA256_1X 5
0059 #define RSN_AKM_SHA256_PSK 6
0060 #define RSN_AKM_SAE 8
0061 #define RSN_CAP_LEN 2
0062 #define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
0063 #define RSN_CAP_MFPR_MASK BIT(6)
0064 #define RSN_CAP_MFPC_MASK BIT(7)
0065 #define RSN_PMKID_COUNT_LEN 2
0066
0067 #define VNDR_IE_CMD_LEN 4
0068
0069
0070 #define VNDR_IE_COUNT_OFFSET 4
0071 #define VNDR_IE_PKTFLAG_OFFSET 8
0072 #define VNDR_IE_VSIE_OFFSET 12
0073 #define VNDR_IE_HDR_SIZE 12
0074 #define VNDR_IE_PARSE_LIMIT 5
0075
0076 #define DOT11_MGMT_HDR_LEN 24
0077 #define DOT11_BCN_PRB_FIXED_LEN 12
0078
0079 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
0080 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
0081 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
0082
0083 #define BRCMF_SCAN_CHANNEL_TIME 40
0084 #define BRCMF_SCAN_UNASSOC_TIME 40
0085 #define BRCMF_SCAN_PASSIVE_TIME 120
0086
0087 #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
0088
0089 #define BRCMF_PS_MAX_TIMEOUT_MS 2000
0090
0091 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
0092 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
0093
0094 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
0095 {
0096 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
0097 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
0098 vif->sme_state);
0099 return false;
0100 }
0101 return true;
0102 }
0103
0104 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
0105 #define RATETAB_ENT(_rateid, _flags) \
0106 { \
0107 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
0108 .hw_value = (_rateid), \
0109 .flags = (_flags), \
0110 }
0111
0112 static struct ieee80211_rate __wl_rates[] = {
0113 RATETAB_ENT(BRCM_RATE_1M, 0),
0114 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
0115 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
0116 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
0117 RATETAB_ENT(BRCM_RATE_6M, 0),
0118 RATETAB_ENT(BRCM_RATE_9M, 0),
0119 RATETAB_ENT(BRCM_RATE_12M, 0),
0120 RATETAB_ENT(BRCM_RATE_18M, 0),
0121 RATETAB_ENT(BRCM_RATE_24M, 0),
0122 RATETAB_ENT(BRCM_RATE_36M, 0),
0123 RATETAB_ENT(BRCM_RATE_48M, 0),
0124 RATETAB_ENT(BRCM_RATE_54M, 0),
0125 };
0126
0127 #define wl_g_rates (__wl_rates + 0)
0128 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
0129 #define wl_a_rates (__wl_rates + 4)
0130 #define wl_a_rates_size (wl_g_rates_size - 4)
0131
0132 #define CHAN2G(_channel, _freq) { \
0133 .band = NL80211_BAND_2GHZ, \
0134 .center_freq = (_freq), \
0135 .hw_value = (_channel), \
0136 .max_antenna_gain = 0, \
0137 .max_power = 30, \
0138 }
0139
0140 #define CHAN5G(_channel) { \
0141 .band = NL80211_BAND_5GHZ, \
0142 .center_freq = 5000 + (5 * (_channel)), \
0143 .hw_value = (_channel), \
0144 .max_antenna_gain = 0, \
0145 .max_power = 30, \
0146 }
0147
0148 static struct ieee80211_channel __wl_2ghz_channels[] = {
0149 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
0150 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
0151 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
0152 CHAN2G(13, 2472), CHAN2G(14, 2484)
0153 };
0154
0155 static struct ieee80211_channel __wl_5ghz_channels[] = {
0156 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
0157 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
0158 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
0159 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
0160 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
0161 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
0162 };
0163
0164
0165
0166
0167 static const struct ieee80211_supported_band __wl_band_2ghz = {
0168 .band = NL80211_BAND_2GHZ,
0169 .bitrates = wl_g_rates,
0170 .n_bitrates = wl_g_rates_size,
0171 };
0172
0173 static const struct ieee80211_supported_band __wl_band_5ghz = {
0174 .band = NL80211_BAND_5GHZ,
0175 .bitrates = wl_a_rates,
0176 .n_bitrates = wl_a_rates_size,
0177 };
0178
0179
0180
0181
0182
0183
0184
0185
0186 static const struct ieee80211_regdomain brcmf_regdom = {
0187 .n_reg_rules = 4,
0188 .alpha2 = "99",
0189 .reg_rules = {
0190
0191 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
0192
0193
0194
0195
0196 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
0197
0198 REG_RULE(5150-10, 5350+10, 160, 6, 20, 0),
0199
0200 REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), }
0201 };
0202
0203
0204
0205
0206
0207
0208
0209 static const u32 brcmf_cipher_suites[] = {
0210 WLAN_CIPHER_SUITE_WEP40,
0211 WLAN_CIPHER_SUITE_WEP104,
0212 WLAN_CIPHER_SUITE_TKIP,
0213 WLAN_CIPHER_SUITE_CCMP,
0214
0215 WLAN_CIPHER_SUITE_AES_CMAC
0216 };
0217
0218
0219 struct brcmf_vs_tlv {
0220 u8 id;
0221 u8 len;
0222 u8 oui[3];
0223 u8 oui_type;
0224 };
0225
0226 struct parsed_vndr_ie_info {
0227 u8 *ie_ptr;
0228 u32 ie_len;
0229 struct brcmf_vs_tlv vndrie;
0230 };
0231
0232 struct parsed_vndr_ies {
0233 u32 count;
0234 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
0235 };
0236
0237 static u8 nl80211_band_to_fwil(enum nl80211_band band)
0238 {
0239 switch (band) {
0240 case NL80211_BAND_2GHZ:
0241 return WLC_BAND_2G;
0242 case NL80211_BAND_5GHZ:
0243 return WLC_BAND_5G;
0244 default:
0245 WARN_ON(1);
0246 break;
0247 }
0248 return 0;
0249 }
0250
0251 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
0252 struct cfg80211_chan_def *ch)
0253 {
0254 struct brcmu_chan ch_inf;
0255 s32 primary_offset;
0256
0257 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
0258 ch->chan->center_freq, ch->center_freq1, ch->width);
0259 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
0260 primary_offset = ch->chan->center_freq - ch->center_freq1;
0261 switch (ch->width) {
0262 case NL80211_CHAN_WIDTH_20:
0263 case NL80211_CHAN_WIDTH_20_NOHT:
0264 ch_inf.bw = BRCMU_CHAN_BW_20;
0265 WARN_ON(primary_offset != 0);
0266 break;
0267 case NL80211_CHAN_WIDTH_40:
0268 ch_inf.bw = BRCMU_CHAN_BW_40;
0269 if (primary_offset > 0)
0270 ch_inf.sb = BRCMU_CHAN_SB_U;
0271 else
0272 ch_inf.sb = BRCMU_CHAN_SB_L;
0273 break;
0274 case NL80211_CHAN_WIDTH_80:
0275 ch_inf.bw = BRCMU_CHAN_BW_80;
0276 if (primary_offset == -30)
0277 ch_inf.sb = BRCMU_CHAN_SB_LL;
0278 else if (primary_offset == -10)
0279 ch_inf.sb = BRCMU_CHAN_SB_LU;
0280 else if (primary_offset == 10)
0281 ch_inf.sb = BRCMU_CHAN_SB_UL;
0282 else
0283 ch_inf.sb = BRCMU_CHAN_SB_UU;
0284 break;
0285 case NL80211_CHAN_WIDTH_160:
0286 ch_inf.bw = BRCMU_CHAN_BW_160;
0287 if (primary_offset == -70)
0288 ch_inf.sb = BRCMU_CHAN_SB_LLL;
0289 else if (primary_offset == -50)
0290 ch_inf.sb = BRCMU_CHAN_SB_LLU;
0291 else if (primary_offset == -30)
0292 ch_inf.sb = BRCMU_CHAN_SB_LUL;
0293 else if (primary_offset == -10)
0294 ch_inf.sb = BRCMU_CHAN_SB_LUU;
0295 else if (primary_offset == 10)
0296 ch_inf.sb = BRCMU_CHAN_SB_ULL;
0297 else if (primary_offset == 30)
0298 ch_inf.sb = BRCMU_CHAN_SB_ULU;
0299 else if (primary_offset == 50)
0300 ch_inf.sb = BRCMU_CHAN_SB_UUL;
0301 else
0302 ch_inf.sb = BRCMU_CHAN_SB_UUU;
0303 break;
0304 case NL80211_CHAN_WIDTH_80P80:
0305 case NL80211_CHAN_WIDTH_5:
0306 case NL80211_CHAN_WIDTH_10:
0307 default:
0308 WARN_ON_ONCE(1);
0309 }
0310 switch (ch->chan->band) {
0311 case NL80211_BAND_2GHZ:
0312 ch_inf.band = BRCMU_CHAN_BAND_2G;
0313 break;
0314 case NL80211_BAND_5GHZ:
0315 ch_inf.band = BRCMU_CHAN_BAND_5G;
0316 break;
0317 case NL80211_BAND_60GHZ:
0318 default:
0319 WARN_ON_ONCE(1);
0320 }
0321 d11inf->encchspec(&ch_inf);
0322
0323 brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec);
0324 return ch_inf.chspec;
0325 }
0326
0327 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
0328 struct ieee80211_channel *ch)
0329 {
0330 struct brcmu_chan ch_inf;
0331
0332 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
0333 ch_inf.bw = BRCMU_CHAN_BW_20;
0334 d11inf->encchspec(&ch_inf);
0335
0336 return ch_inf.chspec;
0337 }
0338
0339
0340
0341
0342
0343 static const struct brcmf_tlv *
0344 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
0345 {
0346 const struct brcmf_tlv *elt = buf;
0347 int totlen = buflen;
0348
0349
0350 while (totlen >= TLV_HDR_LEN) {
0351 int len = elt->len;
0352
0353
0354 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
0355 return elt;
0356
0357 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
0358 totlen -= (len + TLV_HDR_LEN);
0359 }
0360
0361 return NULL;
0362 }
0363
0364
0365
0366
0367 static bool
0368 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
0369 const u8 *oui, u32 oui_len, u8 type)
0370 {
0371
0372 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
0373 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
0374 type == ie[TLV_BODY_OFF + oui_len]) {
0375 return true;
0376 }
0377
0378 if (tlvs == NULL)
0379 return false;
0380
0381 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
0382
0383 *tlvs_len -= (int)(ie - *tlvs);
0384
0385 *tlvs = ie;
0386
0387 return false;
0388 }
0389
0390 static struct brcmf_vs_tlv *
0391 brcmf_find_wpaie(const u8 *parse, u32 len)
0392 {
0393 const struct brcmf_tlv *ie;
0394
0395 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
0396 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
0397 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
0398 return (struct brcmf_vs_tlv *)ie;
0399 }
0400 return NULL;
0401 }
0402
0403 static struct brcmf_vs_tlv *
0404 brcmf_find_wpsie(const u8 *parse, u32 len)
0405 {
0406 const struct brcmf_tlv *ie;
0407
0408 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
0409 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
0410 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
0411 return (struct brcmf_vs_tlv *)ie;
0412 }
0413 return NULL;
0414 }
0415
0416 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
0417 struct brcmf_cfg80211_vif *vif,
0418 enum nl80211_iftype new_type)
0419 {
0420 struct brcmf_cfg80211_vif *pos;
0421 bool check_combos = false;
0422 int ret = 0;
0423 struct iface_combination_params params = {
0424 .num_different_channels = 1,
0425 };
0426
0427 list_for_each_entry(pos, &cfg->vif_list, list)
0428 if (pos == vif) {
0429 params.iftype_num[new_type]++;
0430 } else {
0431
0432 check_combos = true;
0433 params.iftype_num[pos->wdev.iftype]++;
0434 }
0435
0436 if (check_combos)
0437 ret = cfg80211_check_combinations(cfg->wiphy, ¶ms);
0438
0439 return ret;
0440 }
0441
0442 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
0443 enum nl80211_iftype new_type)
0444 {
0445 struct brcmf_cfg80211_vif *pos;
0446 struct iface_combination_params params = {
0447 .num_different_channels = 1,
0448 };
0449
0450 list_for_each_entry(pos, &cfg->vif_list, list)
0451 params.iftype_num[pos->wdev.iftype]++;
0452
0453 params.iftype_num[new_type]++;
0454 return cfg80211_check_combinations(cfg->wiphy, ¶ms);
0455 }
0456
0457 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
0458 struct brcmf_wsec_key_le *key_le)
0459 {
0460 key_le->index = cpu_to_le32(key->index);
0461 key_le->len = cpu_to_le32(key->len);
0462 key_le->algo = cpu_to_le32(key->algo);
0463 key_le->flags = cpu_to_le32(key->flags);
0464 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
0465 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
0466 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
0467 memcpy(key_le->data, key->data, sizeof(key->data));
0468 memcpy(key_le->ea, key->ea, sizeof(key->ea));
0469 }
0470
0471 static int
0472 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
0473 {
0474 struct brcmf_pub *drvr = ifp->drvr;
0475 int err;
0476 struct brcmf_wsec_key_le key_le;
0477
0478 convert_key_from_CPU(key, &key_le);
0479
0480 brcmf_netdev_wait_pend8021x(ifp);
0481
0482 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
0483 sizeof(key_le));
0484
0485 if (err)
0486 bphy_err(drvr, "wsec_key error (%d)\n", err);
0487 return err;
0488 }
0489
0490 static void
0491 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
0492 {
0493 struct brcmf_cfg80211_vif *vif;
0494 struct brcmf_if *ifp;
0495
0496 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
0497 ifp = vif->ifp;
0498
0499 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
0500 (wdev->iftype == NL80211_IFTYPE_AP) ||
0501 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
0502 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
0503 ADDR_DIRECT);
0504 else
0505 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
0506 ADDR_INDIRECT);
0507 }
0508
0509 static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
0510 {
0511 int bsscfgidx;
0512
0513 for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
0514
0515 if (bsscfgidx == 1)
0516 continue;
0517 if (!drvr->iflist[bsscfgidx])
0518 return bsscfgidx;
0519 }
0520
0521 return -ENOMEM;
0522 }
0523
0524 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
0525 {
0526 struct brcmf_pub *drvr = ifp->drvr;
0527 struct brcmf_mbss_ssid_le mbss_ssid_le;
0528 int bsscfgidx;
0529 int err;
0530
0531 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
0532 bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
0533 if (bsscfgidx < 0)
0534 return bsscfgidx;
0535
0536 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
0537 mbss_ssid_le.SSID_len = cpu_to_le32(5);
0538 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
0539
0540 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
0541 sizeof(mbss_ssid_le));
0542 if (err < 0)
0543 bphy_err(drvr, "setting ssid failed %d\n", err);
0544
0545 return err;
0546 }
0547
0548
0549
0550
0551
0552
0553
0554
0555 static
0556 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
0557 struct vif_params *params)
0558 {
0559 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
0560 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
0561 struct brcmf_pub *drvr = cfg->pub;
0562 struct brcmf_cfg80211_vif *vif;
0563 int err;
0564
0565 if (brcmf_cfg80211_vif_event_armed(cfg))
0566 return ERR_PTR(-EBUSY);
0567
0568 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
0569
0570 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
0571 if (IS_ERR(vif))
0572 return (struct wireless_dev *)vif;
0573
0574 brcmf_cfg80211_arm_vif_event(cfg, vif);
0575
0576 err = brcmf_cfg80211_request_ap_if(ifp);
0577 if (err) {
0578 brcmf_cfg80211_arm_vif_event(cfg, NULL);
0579 goto fail;
0580 }
0581
0582
0583 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
0584 BRCMF_VIF_EVENT_TIMEOUT);
0585 brcmf_cfg80211_arm_vif_event(cfg, NULL);
0586 if (!err) {
0587 bphy_err(drvr, "timeout occurred\n");
0588 err = -EIO;
0589 goto fail;
0590 }
0591
0592
0593 ifp = vif->ifp;
0594 if (!ifp) {
0595 bphy_err(drvr, "no if pointer provided\n");
0596 err = -ENOENT;
0597 goto fail;
0598 }
0599
0600 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
0601 err = brcmf_net_attach(ifp, true);
0602 if (err) {
0603 bphy_err(drvr, "Registering netdevice failed\n");
0604 free_netdev(ifp->ndev);
0605 goto fail;
0606 }
0607
0608 return &ifp->vif->wdev;
0609
0610 fail:
0611 brcmf_free_vif(vif);
0612 return ERR_PTR(err);
0613 }
0614
0615 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
0616 {
0617 enum nl80211_iftype iftype;
0618
0619 iftype = vif->wdev.iftype;
0620 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
0621 }
0622
0623 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
0624 {
0625 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
0626 }
0627
0628
0629
0630
0631
0632
0633
0634 static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
0635 const char *name)
0636 {
0637 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
0638 struct brcmf_cfg80211_vif *vif;
0639 struct net_device *ndev;
0640 struct brcmf_if *ifp;
0641 int err;
0642
0643 if (cfg->pub->mon_if) {
0644 err = -EEXIST;
0645 goto err_out;
0646 }
0647
0648 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_MONITOR);
0649 if (IS_ERR(vif)) {
0650 err = PTR_ERR(vif);
0651 goto err_out;
0652 }
0653
0654 ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, ether_setup);
0655 if (!ndev) {
0656 err = -ENOMEM;
0657 goto err_free_vif;
0658 }
0659 ndev->type = ARPHRD_IEEE80211_RADIOTAP;
0660 ndev->ieee80211_ptr = &vif->wdev;
0661 ndev->needs_free_netdev = true;
0662 ndev->priv_destructor = brcmf_cfg80211_free_netdev;
0663 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
0664
0665 ifp = netdev_priv(ndev);
0666 ifp->vif = vif;
0667 ifp->ndev = ndev;
0668 ifp->drvr = cfg->pub;
0669
0670 vif->ifp = ifp;
0671 vif->wdev.netdev = ndev;
0672
0673 err = brcmf_net_mon_attach(ifp);
0674 if (err) {
0675 brcmf_err("Failed to attach %s device\n", ndev->name);
0676 free_netdev(ndev);
0677 goto err_free_vif;
0678 }
0679
0680 cfg->pub->mon_if = ifp;
0681
0682 return &vif->wdev;
0683
0684 err_free_vif:
0685 brcmf_free_vif(vif);
0686 err_out:
0687 return ERR_PTR(err);
0688 }
0689
0690 static int brcmf_mon_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
0691 {
0692 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
0693 struct net_device *ndev = wdev->netdev;
0694
0695 ndev->netdev_ops->ndo_stop(ndev);
0696
0697 brcmf_net_detach(ndev, true);
0698
0699 cfg->pub->mon_if = NULL;
0700
0701 return 0;
0702 }
0703
0704 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
0705 const char *name,
0706 unsigned char name_assign_type,
0707 enum nl80211_iftype type,
0708 struct vif_params *params)
0709 {
0710 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
0711 struct brcmf_pub *drvr = cfg->pub;
0712 struct wireless_dev *wdev;
0713 int err;
0714
0715 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
0716 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
0717 if (err) {
0718 bphy_err(drvr, "iface validation failed: err=%d\n", err);
0719 return ERR_PTR(err);
0720 }
0721 switch (type) {
0722 case NL80211_IFTYPE_ADHOC:
0723 case NL80211_IFTYPE_STATION:
0724 case NL80211_IFTYPE_AP_VLAN:
0725 case NL80211_IFTYPE_WDS:
0726 case NL80211_IFTYPE_MESH_POINT:
0727 return ERR_PTR(-EOPNOTSUPP);
0728 case NL80211_IFTYPE_MONITOR:
0729 return brcmf_mon_add_vif(wiphy, name);
0730 case NL80211_IFTYPE_AP:
0731 wdev = brcmf_ap_add_vif(wiphy, name, params);
0732 break;
0733 case NL80211_IFTYPE_P2P_CLIENT:
0734 case NL80211_IFTYPE_P2P_GO:
0735 case NL80211_IFTYPE_P2P_DEVICE:
0736 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
0737 break;
0738 case NL80211_IFTYPE_UNSPECIFIED:
0739 default:
0740 return ERR_PTR(-EINVAL);
0741 }
0742
0743 if (IS_ERR(wdev))
0744 bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name,
0745 type, (int)PTR_ERR(wdev));
0746 else
0747 brcmf_cfg80211_update_proto_addr_mode(wdev);
0748
0749 return wdev;
0750 }
0751
0752 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
0753 {
0754 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
0755 brcmf_set_mpc(ifp, mpc);
0756 }
0757
0758 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
0759 {
0760 struct brcmf_pub *drvr = ifp->drvr;
0761 s32 err = 0;
0762
0763 if (check_vif_up(ifp->vif)) {
0764 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
0765 if (err) {
0766 bphy_err(drvr, "fail to set mpc\n");
0767 return;
0768 }
0769 brcmf_dbg(INFO, "MPC : %d\n", mpc);
0770 }
0771 }
0772
0773 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
0774 struct brcmf_if *ifp, bool aborted,
0775 bool fw_abort)
0776 {
0777 struct brcmf_pub *drvr = cfg->pub;
0778 struct brcmf_scan_params_le params_le;
0779 struct cfg80211_scan_request *scan_request;
0780 u64 reqid;
0781 u32 bucket;
0782 s32 err = 0;
0783
0784 brcmf_dbg(SCAN, "Enter\n");
0785
0786
0787
0788 scan_request = cfg->scan_request;
0789 cfg->scan_request = NULL;
0790
0791 if (timer_pending(&cfg->escan_timeout))
0792 del_timer_sync(&cfg->escan_timeout);
0793
0794 if (fw_abort) {
0795
0796 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
0797 memset(¶ms_le, 0, sizeof(params_le));
0798 eth_broadcast_addr(params_le.bssid);
0799 params_le.bss_type = DOT11_BSSTYPE_ANY;
0800 params_le.scan_type = 0;
0801 params_le.channel_num = cpu_to_le32(1);
0802 params_le.nprobes = cpu_to_le32(1);
0803 params_le.active_time = cpu_to_le32(-1);
0804 params_le.passive_time = cpu_to_le32(-1);
0805 params_le.home_time = cpu_to_le32(-1);
0806
0807 params_le.channel_list[0] = cpu_to_le16(-1);
0808
0809 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
0810 ¶ms_le, sizeof(params_le));
0811 if (err)
0812 bphy_err(drvr, "Scan abort failed\n");
0813 }
0814
0815 brcmf_scan_config_mpc(ifp, 1);
0816
0817
0818
0819
0820
0821 if (cfg->int_escan_map) {
0822 brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
0823 cfg->int_escan_map);
0824 while (cfg->int_escan_map) {
0825 bucket = __ffs(cfg->int_escan_map);
0826 cfg->int_escan_map &= ~BIT(bucket);
0827 reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
0828 bucket);
0829 if (!aborted) {
0830 brcmf_dbg(SCAN, "report results: reqid=%llu\n",
0831 reqid);
0832 cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
0833 reqid);
0834 }
0835 }
0836 } else if (scan_request) {
0837 struct cfg80211_scan_info info = {
0838 .aborted = aborted,
0839 };
0840
0841 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
0842 aborted ? "Aborted" : "Done");
0843 cfg80211_scan_done(scan_request, &info);
0844 }
0845 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
0846 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
0847
0848 return err;
0849 }
0850
0851 static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
0852 struct wireless_dev *wdev)
0853 {
0854 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
0855 struct net_device *ndev = wdev->netdev;
0856 struct brcmf_if *ifp = netdev_priv(ndev);
0857 struct brcmf_pub *drvr = cfg->pub;
0858 int ret;
0859 int err;
0860
0861 brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
0862
0863 err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
0864 if (err) {
0865 bphy_err(drvr, "interface_remove failed %d\n", err);
0866 goto err_unarm;
0867 }
0868
0869
0870 ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
0871 BRCMF_VIF_EVENT_TIMEOUT);
0872 if (!ret) {
0873 bphy_err(drvr, "timeout occurred\n");
0874 err = -EIO;
0875 goto err_unarm;
0876 }
0877
0878 brcmf_remove_interface(ifp, true);
0879
0880 err_unarm:
0881 brcmf_cfg80211_arm_vif_event(cfg, NULL);
0882 return err;
0883 }
0884
0885 static
0886 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
0887 {
0888 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
0889 struct net_device *ndev = wdev->netdev;
0890
0891 if (ndev && ndev == cfg_to_ndev(cfg))
0892 return -ENOTSUPP;
0893
0894
0895 if (brcmf_cfg80211_vif_event_armed(cfg))
0896 return -EBUSY;
0897
0898 if (ndev) {
0899 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
0900 cfg->escan_info.ifp == netdev_priv(ndev))
0901 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
0902 true, true);
0903
0904 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
0905 }
0906
0907 switch (wdev->iftype) {
0908 case NL80211_IFTYPE_ADHOC:
0909 case NL80211_IFTYPE_STATION:
0910 case NL80211_IFTYPE_AP_VLAN:
0911 case NL80211_IFTYPE_WDS:
0912 case NL80211_IFTYPE_MESH_POINT:
0913 return -EOPNOTSUPP;
0914 case NL80211_IFTYPE_MONITOR:
0915 return brcmf_mon_del_vif(wiphy, wdev);
0916 case NL80211_IFTYPE_AP:
0917 return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
0918 case NL80211_IFTYPE_P2P_CLIENT:
0919 case NL80211_IFTYPE_P2P_GO:
0920 case NL80211_IFTYPE_P2P_DEVICE:
0921 return brcmf_p2p_del_vif(wiphy, wdev);
0922 case NL80211_IFTYPE_UNSPECIFIED:
0923 default:
0924 return -EINVAL;
0925 }
0926 return -EOPNOTSUPP;
0927 }
0928
0929 static s32
0930 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
0931 enum nl80211_iftype type,
0932 struct vif_params *params)
0933 {
0934 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
0935 struct brcmf_if *ifp = netdev_priv(ndev);
0936 struct brcmf_cfg80211_vif *vif = ifp->vif;
0937 struct brcmf_pub *drvr = cfg->pub;
0938 s32 infra = 0;
0939 s32 ap = 0;
0940 s32 err = 0;
0941
0942 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
0943 type);
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953 if ((type == NL80211_IFTYPE_STATION) &&
0954 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
0955 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
0956 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
0957 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970 if (cfg->p2p.p2pdev_dynamically)
0971 return -EOPNOTSUPP;
0972 else
0973 return 0;
0974 }
0975 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
0976 if (err) {
0977 bphy_err(drvr, "iface validation failed: err=%d\n", err);
0978 return err;
0979 }
0980 switch (type) {
0981 case NL80211_IFTYPE_MONITOR:
0982 case NL80211_IFTYPE_WDS:
0983 bphy_err(drvr, "type (%d) : currently we do not support this type\n",
0984 type);
0985 return -EOPNOTSUPP;
0986 case NL80211_IFTYPE_ADHOC:
0987 infra = 0;
0988 break;
0989 case NL80211_IFTYPE_STATION:
0990 infra = 1;
0991 break;
0992 case NL80211_IFTYPE_AP:
0993 case NL80211_IFTYPE_P2P_GO:
0994 ap = 1;
0995 break;
0996 default:
0997 err = -EINVAL;
0998 goto done;
0999 }
1000
1001 if (ap) {
1002 if (type == NL80211_IFTYPE_P2P_GO) {
1003 brcmf_dbg(INFO, "IF Type = P2P GO\n");
1004 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
1005 }
1006 if (!err) {
1007 brcmf_dbg(INFO, "IF Type = AP\n");
1008 }
1009 } else {
1010 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
1011 if (err) {
1012 bphy_err(drvr, "WLC_SET_INFRA error (%d)\n", err);
1013 err = -EAGAIN;
1014 goto done;
1015 }
1016 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
1017 "Adhoc" : "Infra");
1018 }
1019 ndev->ieee80211_ptr->iftype = type;
1020
1021 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
1022
1023 done:
1024 brcmf_dbg(TRACE, "Exit\n");
1025
1026 return err;
1027 }
1028
1029 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
1030 struct brcmf_scan_params_le *params_le,
1031 struct cfg80211_scan_request *request)
1032 {
1033 u32 n_ssids;
1034 u32 n_channels;
1035 s32 i;
1036 s32 offset;
1037 u16 chanspec;
1038 char *ptr;
1039 struct brcmf_ssid_le ssid_le;
1040
1041 eth_broadcast_addr(params_le->bssid);
1042 params_le->bss_type = DOT11_BSSTYPE_ANY;
1043 params_le->scan_type = BRCMF_SCANTYPE_ACTIVE;
1044 params_le->channel_num = 0;
1045 params_le->nprobes = cpu_to_le32(-1);
1046 params_le->active_time = cpu_to_le32(-1);
1047 params_le->passive_time = cpu_to_le32(-1);
1048 params_le->home_time = cpu_to_le32(-1);
1049 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
1050
1051 n_ssids = request->n_ssids;
1052 n_channels = request->n_channels;
1053
1054
1055 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
1056 n_channels);
1057 if (n_channels > 0) {
1058 for (i = 0; i < n_channels; i++) {
1059 chanspec = channel_to_chanspec(&cfg->d11inf,
1060 request->channels[i]);
1061 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
1062 request->channels[i]->hw_value, chanspec);
1063 params_le->channel_list[i] = cpu_to_le16(chanspec);
1064 }
1065 } else {
1066 brcmf_dbg(SCAN, "Scanning all channels\n");
1067 }
1068
1069 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
1070 if (n_ssids > 0) {
1071 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
1072 n_channels * sizeof(u16);
1073 offset = roundup(offset, sizeof(u32));
1074 ptr = (char *)params_le + offset;
1075 for (i = 0; i < n_ssids; i++) {
1076 memset(&ssid_le, 0, sizeof(ssid_le));
1077 ssid_le.SSID_len =
1078 cpu_to_le32(request->ssids[i].ssid_len);
1079 memcpy(ssid_le.SSID, request->ssids[i].ssid,
1080 request->ssids[i].ssid_len);
1081 if (!ssid_le.SSID_len)
1082 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
1083 else
1084 brcmf_dbg(SCAN, "%d: scan for %.32s size=%d\n",
1085 i, ssid_le.SSID, ssid_le.SSID_len);
1086 memcpy(ptr, &ssid_le, sizeof(ssid_le));
1087 ptr += sizeof(ssid_le);
1088 }
1089 } else {
1090 brcmf_dbg(SCAN, "Performing passive scan\n");
1091 params_le->scan_type = BRCMF_SCANTYPE_PASSIVE;
1092 }
1093
1094 params_le->channel_num =
1095 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1096 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1097 }
1098
1099 static s32
1100 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1101 struct cfg80211_scan_request *request)
1102 {
1103 struct brcmf_pub *drvr = cfg->pub;
1104 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1105 offsetof(struct brcmf_escan_params_le, params_le);
1106 struct brcmf_escan_params_le *params;
1107 s32 err = 0;
1108
1109 brcmf_dbg(SCAN, "E-SCAN START\n");
1110
1111 if (request != NULL) {
1112
1113 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1114
1115
1116 params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1117 }
1118
1119 params = kzalloc(params_size, GFP_KERNEL);
1120 if (!params) {
1121 err = -ENOMEM;
1122 goto exit;
1123 }
1124 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1125 brcmf_escan_prep(cfg, ¶ms->params_le, request);
1126 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1127 params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
1128 params->sync_id = cpu_to_le16(0x1234);
1129
1130 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1131 if (err) {
1132 if (err == -EBUSY)
1133 brcmf_dbg(INFO, "system busy : escan canceled\n");
1134 else
1135 bphy_err(drvr, "error (%d)\n", err);
1136 }
1137
1138 kfree(params);
1139 exit:
1140 return err;
1141 }
1142
1143 static s32
1144 brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1145 {
1146 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1147 s32 err;
1148 struct brcmf_scan_results *results;
1149 struct escan_info *escan = &cfg->escan_info;
1150
1151 brcmf_dbg(SCAN, "Enter\n");
1152 escan->ifp = ifp;
1153 escan->wiphy = cfg->wiphy;
1154 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1155
1156 brcmf_scan_config_mpc(ifp, 0);
1157 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1158 results->version = 0;
1159 results->count = 0;
1160 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1161
1162 err = escan->run(cfg, ifp, request);
1163 if (err)
1164 brcmf_scan_config_mpc(ifp, 1);
1165 return err;
1166 }
1167
1168 static s32
1169 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1170 {
1171 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1172 struct brcmf_pub *drvr = cfg->pub;
1173 struct brcmf_cfg80211_vif *vif;
1174 s32 err = 0;
1175
1176 brcmf_dbg(TRACE, "Enter\n");
1177 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1178 if (!check_vif_up(vif))
1179 return -EIO;
1180
1181 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1182 bphy_err(drvr, "Scanning already: status (%lu)\n",
1183 cfg->scan_status);
1184 return -EAGAIN;
1185 }
1186 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1187 bphy_err(drvr, "Scanning being aborted: status (%lu)\n",
1188 cfg->scan_status);
1189 return -EAGAIN;
1190 }
1191 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1192 bphy_err(drvr, "Scanning suppressed: status (%lu)\n",
1193 cfg->scan_status);
1194 return -EAGAIN;
1195 }
1196 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
1197 bphy_err(drvr, "Connecting: status (%lu)\n", vif->sme_state);
1198 return -EAGAIN;
1199 }
1200
1201
1202 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1203 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1204
1205 brcmf_dbg(SCAN, "START ESCAN\n");
1206
1207 cfg->scan_request = request;
1208 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1209
1210 cfg->escan_info.run = brcmf_run_escan;
1211 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1212 if (err)
1213 goto scan_out;
1214
1215 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
1216 request->ie, request->ie_len);
1217 if (err)
1218 goto scan_out;
1219
1220 err = brcmf_do_escan(vif->ifp, request);
1221 if (err)
1222 goto scan_out;
1223
1224
1225 mod_timer(&cfg->escan_timeout,
1226 jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS));
1227
1228 return 0;
1229
1230 scan_out:
1231 bphy_err(drvr, "scan error (%d)\n", err);
1232 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1233 cfg->scan_request = NULL;
1234 return err;
1235 }
1236
1237 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1238 {
1239 struct brcmf_if *ifp = netdev_priv(ndev);
1240 struct brcmf_pub *drvr = ifp->drvr;
1241 s32 err = 0;
1242
1243 err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold);
1244 if (err)
1245 bphy_err(drvr, "Error (%d)\n", err);
1246
1247 return err;
1248 }
1249
1250 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1251 {
1252 struct brcmf_if *ifp = netdev_priv(ndev);
1253 struct brcmf_pub *drvr = ifp->drvr;
1254 s32 err = 0;
1255
1256 err = brcmf_fil_iovar_int_set(ifp, "fragthresh",
1257 frag_threshold);
1258 if (err)
1259 bphy_err(drvr, "Error (%d)\n", err);
1260
1261 return err;
1262 }
1263
1264 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1265 {
1266 struct brcmf_if *ifp = netdev_priv(ndev);
1267 struct brcmf_pub *drvr = ifp->drvr;
1268 s32 err = 0;
1269 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1270
1271 err = brcmf_fil_cmd_int_set(ifp, cmd, retry);
1272 if (err) {
1273 bphy_err(drvr, "cmd (%d) , error (%d)\n", cmd, err);
1274 return err;
1275 }
1276 return err;
1277 }
1278
1279 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1280 {
1281 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1282 struct net_device *ndev = cfg_to_ndev(cfg);
1283 struct brcmf_if *ifp = netdev_priv(ndev);
1284 s32 err = 0;
1285
1286 brcmf_dbg(TRACE, "Enter\n");
1287 if (!check_vif_up(ifp->vif))
1288 return -EIO;
1289
1290 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1291 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1292 cfg->conf->rts_threshold = wiphy->rts_threshold;
1293 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1294 if (!err)
1295 goto done;
1296 }
1297 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1298 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1299 cfg->conf->frag_threshold = wiphy->frag_threshold;
1300 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1301 if (!err)
1302 goto done;
1303 }
1304 if (changed & WIPHY_PARAM_RETRY_LONG
1305 && (cfg->conf->retry_long != wiphy->retry_long)) {
1306 cfg->conf->retry_long = wiphy->retry_long;
1307 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1308 if (!err)
1309 goto done;
1310 }
1311 if (changed & WIPHY_PARAM_RETRY_SHORT
1312 && (cfg->conf->retry_short != wiphy->retry_short)) {
1313 cfg->conf->retry_short = wiphy->retry_short;
1314 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1315 if (!err)
1316 goto done;
1317 }
1318
1319 done:
1320 brcmf_dbg(TRACE, "Exit\n");
1321 return err;
1322 }
1323
1324 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1325 {
1326 memset(prof, 0, sizeof(*prof));
1327 }
1328
1329 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1330 {
1331 u16 reason;
1332
1333 switch (e->event_code) {
1334 case BRCMF_E_DEAUTH:
1335 case BRCMF_E_DEAUTH_IND:
1336 case BRCMF_E_DISASSOC_IND:
1337 reason = e->reason;
1338 break;
1339 case BRCMF_E_LINK:
1340 default:
1341 reason = 0;
1342 break;
1343 }
1344 return reason;
1345 }
1346
1347 static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
1348 {
1349 struct brcmf_pub *drvr = ifp->drvr;
1350 struct brcmf_wsec_pmk_le pmk;
1351 int i, err;
1352
1353
1354 pmk.key_len = cpu_to_le16(pmk_len << 1);
1355 pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE);
1356 for (i = 0; i < pmk_len; i++)
1357 snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]);
1358
1359
1360 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
1361 &pmk, sizeof(pmk));
1362 if (err < 0)
1363 bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n",
1364 pmk_len);
1365
1366 return err;
1367 }
1368
1369 static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data,
1370 u16 pwd_len)
1371 {
1372 struct brcmf_pub *drvr = ifp->drvr;
1373 struct brcmf_wsec_sae_pwd_le sae_pwd;
1374 int err;
1375
1376 if (pwd_len > BRCMF_WSEC_MAX_SAE_PASSWORD_LEN) {
1377 bphy_err(drvr, "sae_password must be less than %d\n",
1378 BRCMF_WSEC_MAX_SAE_PASSWORD_LEN);
1379 return -EINVAL;
1380 }
1381
1382 sae_pwd.key_len = cpu_to_le16(pwd_len);
1383 memcpy(sae_pwd.key, pwd_data, pwd_len);
1384
1385 err = brcmf_fil_iovar_data_set(ifp, "sae_password", &sae_pwd,
1386 sizeof(sae_pwd));
1387 if (err < 0)
1388 bphy_err(drvr, "failed to set SAE password in firmware (len=%u)\n",
1389 pwd_len);
1390
1391 return err;
1392 }
1393
1394 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
1395 bool locally_generated)
1396 {
1397 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1398 struct brcmf_pub *drvr = cfg->pub;
1399 bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP;
1400 s32 err = 0;
1401
1402 brcmf_dbg(TRACE, "Enter\n");
1403
1404 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1405 if (bus_up) {
1406 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n");
1407 err = brcmf_fil_cmd_data_set(vif->ifp,
1408 BRCMF_C_DISASSOC, NULL, 0);
1409 if (err)
1410 bphy_err(drvr, "WLC_DISASSOC failed (%d)\n",
1411 err);
1412 }
1413
1414 if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1415 (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1416 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1417 locally_generated, GFP_KERNEL);
1418 }
1419 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1420 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1421 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1422 if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1423 if (bus_up)
1424 brcmf_set_pmk(vif->ifp, NULL, 0);
1425 vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1426 }
1427 brcmf_dbg(TRACE, "Exit\n");
1428 }
1429
1430 static s32
1431 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1432 struct cfg80211_ibss_params *params)
1433 {
1434 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1435 struct brcmf_if *ifp = netdev_priv(ndev);
1436 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1437 struct brcmf_pub *drvr = cfg->pub;
1438 struct brcmf_join_params join_params;
1439 size_t join_params_size = 0;
1440 s32 err = 0;
1441 s32 wsec = 0;
1442 s32 bcnprd;
1443 u16 chanspec;
1444 u32 ssid_len;
1445
1446 brcmf_dbg(TRACE, "Enter\n");
1447 if (!check_vif_up(ifp->vif))
1448 return -EIO;
1449
1450 if (params->ssid)
1451 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1452 else {
1453 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1454 return -EOPNOTSUPP;
1455 }
1456
1457 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1458
1459 if (params->bssid)
1460 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1461 else
1462 brcmf_dbg(CONN, "No BSSID specified\n");
1463
1464 if (params->chandef.chan)
1465 brcmf_dbg(CONN, "channel: %d\n",
1466 params->chandef.chan->center_freq);
1467 else
1468 brcmf_dbg(CONN, "no channel specified\n");
1469
1470 if (params->channel_fixed)
1471 brcmf_dbg(CONN, "fixed channel required\n");
1472 else
1473 brcmf_dbg(CONN, "no fixed channel required\n");
1474
1475 if (params->ie && params->ie_len)
1476 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1477 else
1478 brcmf_dbg(CONN, "no ie specified\n");
1479
1480 if (params->beacon_interval)
1481 brcmf_dbg(CONN, "beacon interval: %d\n",
1482 params->beacon_interval);
1483 else
1484 brcmf_dbg(CONN, "no beacon interval specified\n");
1485
1486 if (params->basic_rates)
1487 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1488 else
1489 brcmf_dbg(CONN, "no basic rates specified\n");
1490
1491 if (params->privacy)
1492 brcmf_dbg(CONN, "privacy required\n");
1493 else
1494 brcmf_dbg(CONN, "no privacy required\n");
1495
1496
1497 if (params->privacy)
1498 wsec |= WEP_ENABLED;
1499
1500 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1501 if (err) {
1502 bphy_err(drvr, "wsec failed (%d)\n", err);
1503 goto done;
1504 }
1505
1506
1507 if (params->beacon_interval)
1508 bcnprd = params->beacon_interval;
1509 else
1510 bcnprd = 100;
1511
1512 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1513 if (err) {
1514 bphy_err(drvr, "WLC_SET_BCNPRD failed (%d)\n", err);
1515 goto done;
1516 }
1517
1518
1519 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1520
1521
1522 ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1523 memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1524 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1525 join_params_size = sizeof(join_params.ssid_le);
1526
1527
1528 if (params->bssid) {
1529 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1530 join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1531 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1532 } else {
1533 eth_broadcast_addr(join_params.params_le.bssid);
1534 eth_zero_addr(profile->bssid);
1535 }
1536
1537
1538 if (params->chandef.chan) {
1539 u32 target_channel;
1540
1541 cfg->channel =
1542 ieee80211_frequency_to_channel(
1543 params->chandef.chan->center_freq);
1544 if (params->channel_fixed) {
1545
1546 chanspec = chandef_to_chanspec(&cfg->d11inf,
1547 ¶ms->chandef);
1548 join_params.params_le.chanspec_list[0] =
1549 cpu_to_le16(chanspec);
1550 join_params.params_le.chanspec_num = cpu_to_le32(1);
1551 join_params_size += sizeof(join_params.params_le);
1552 }
1553
1554
1555 target_channel = cfg->channel;
1556 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1557 target_channel);
1558 if (err) {
1559 bphy_err(drvr, "WLC_SET_CHANNEL failed (%d)\n", err);
1560 goto done;
1561 }
1562 } else
1563 cfg->channel = 0;
1564
1565 cfg->ibss_starter = false;
1566
1567
1568 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1569 &join_params, join_params_size);
1570 if (err) {
1571 bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err);
1572 goto done;
1573 }
1574
1575 done:
1576 if (err)
1577 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1578 brcmf_dbg(TRACE, "Exit\n");
1579 return err;
1580 }
1581
1582 static s32
1583 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1584 {
1585 struct brcmf_if *ifp = netdev_priv(ndev);
1586
1587 brcmf_dbg(TRACE, "Enter\n");
1588 if (!check_vif_up(ifp->vif)) {
1589
1590
1591
1592
1593 return 0;
1594 }
1595
1596 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING, true);
1597 brcmf_net_setcarrier(ifp, false);
1598
1599 brcmf_dbg(TRACE, "Exit\n");
1600
1601 return 0;
1602 }
1603
1604 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1605 struct cfg80211_connect_params *sme)
1606 {
1607 struct brcmf_if *ifp = netdev_priv(ndev);
1608 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1609 struct brcmf_pub *drvr = ifp->drvr;
1610 struct brcmf_cfg80211_security *sec;
1611 s32 val = 0;
1612 s32 err = 0;
1613
1614 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1615 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1616 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1617 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1618 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3)
1619 val = WPA3_AUTH_SAE_PSK;
1620 else
1621 val = WPA_AUTH_DISABLED;
1622 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1623 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
1624 if (err) {
1625 bphy_err(drvr, "set wpa_auth failed (%d)\n", err);
1626 return err;
1627 }
1628 sec = &profile->sec;
1629 sec->wpa_versions = sme->crypto.wpa_versions;
1630 return err;
1631 }
1632
1633 static s32 brcmf_set_auth_type(struct net_device *ndev,
1634 struct cfg80211_connect_params *sme)
1635 {
1636 struct brcmf_if *ifp = netdev_priv(ndev);
1637 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1638 struct brcmf_pub *drvr = ifp->drvr;
1639 struct brcmf_cfg80211_security *sec;
1640 s32 val = 0;
1641 s32 err = 0;
1642
1643 switch (sme->auth_type) {
1644 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1645 val = 0;
1646 brcmf_dbg(CONN, "open system\n");
1647 break;
1648 case NL80211_AUTHTYPE_SHARED_KEY:
1649 val = 1;
1650 brcmf_dbg(CONN, "shared key\n");
1651 break;
1652 case NL80211_AUTHTYPE_SAE:
1653 val = 3;
1654 brcmf_dbg(CONN, "SAE authentication\n");
1655 break;
1656 default:
1657 val = 2;
1658 brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
1659 break;
1660 }
1661
1662 err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
1663 if (err) {
1664 bphy_err(drvr, "set auth failed (%d)\n", err);
1665 return err;
1666 }
1667 sec = &profile->sec;
1668 sec->auth_type = sme->auth_type;
1669 return err;
1670 }
1671
1672 static s32
1673 brcmf_set_wsec_mode(struct net_device *ndev,
1674 struct cfg80211_connect_params *sme)
1675 {
1676 struct brcmf_if *ifp = netdev_priv(ndev);
1677 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1678 struct brcmf_pub *drvr = ifp->drvr;
1679 struct brcmf_cfg80211_security *sec;
1680 s32 pval = 0;
1681 s32 gval = 0;
1682 s32 wsec;
1683 s32 err = 0;
1684
1685 if (sme->crypto.n_ciphers_pairwise) {
1686 switch (sme->crypto.ciphers_pairwise[0]) {
1687 case WLAN_CIPHER_SUITE_WEP40:
1688 case WLAN_CIPHER_SUITE_WEP104:
1689 pval = WEP_ENABLED;
1690 break;
1691 case WLAN_CIPHER_SUITE_TKIP:
1692 pval = TKIP_ENABLED;
1693 break;
1694 case WLAN_CIPHER_SUITE_CCMP:
1695 pval = AES_ENABLED;
1696 break;
1697 case WLAN_CIPHER_SUITE_AES_CMAC:
1698 pval = AES_ENABLED;
1699 break;
1700 default:
1701 bphy_err(drvr, "invalid cipher pairwise (%d)\n",
1702 sme->crypto.ciphers_pairwise[0]);
1703 return -EINVAL;
1704 }
1705 }
1706 if (sme->crypto.cipher_group) {
1707 switch (sme->crypto.cipher_group) {
1708 case WLAN_CIPHER_SUITE_WEP40:
1709 case WLAN_CIPHER_SUITE_WEP104:
1710 gval = WEP_ENABLED;
1711 break;
1712 case WLAN_CIPHER_SUITE_TKIP:
1713 gval = TKIP_ENABLED;
1714 break;
1715 case WLAN_CIPHER_SUITE_CCMP:
1716 gval = AES_ENABLED;
1717 break;
1718 case WLAN_CIPHER_SUITE_AES_CMAC:
1719 gval = AES_ENABLED;
1720 break;
1721 default:
1722 bphy_err(drvr, "invalid cipher group (%d)\n",
1723 sme->crypto.cipher_group);
1724 return -EINVAL;
1725 }
1726 }
1727
1728 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1729
1730
1731 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1732 sme->privacy)
1733 pval = AES_ENABLED;
1734
1735 wsec = pval | gval;
1736 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1737 if (err) {
1738 bphy_err(drvr, "error (%d)\n", err);
1739 return err;
1740 }
1741
1742 sec = &profile->sec;
1743 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1744 sec->cipher_group = sme->crypto.cipher_group;
1745
1746 return err;
1747 }
1748
1749 static s32
1750 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1751 {
1752 struct brcmf_if *ifp = netdev_priv(ndev);
1753 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1754 struct brcmf_pub *drvr = ifp->drvr;
1755 s32 val;
1756 s32 err;
1757 const struct brcmf_tlv *rsn_ie;
1758 const u8 *ie;
1759 u32 ie_len;
1760 u32 offset;
1761 u16 rsn_cap;
1762 u32 mfp;
1763 u16 count;
1764
1765 profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1766 profile->is_ft = false;
1767
1768 if (!sme->crypto.n_akm_suites)
1769 return 0;
1770
1771 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
1772 if (err) {
1773 bphy_err(drvr, "could not get wpa_auth (%d)\n", err);
1774 return err;
1775 }
1776 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1777 switch (sme->crypto.akm_suites[0]) {
1778 case WLAN_AKM_SUITE_8021X:
1779 val = WPA_AUTH_UNSPECIFIED;
1780 if (sme->want_1x)
1781 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1782 break;
1783 case WLAN_AKM_SUITE_PSK:
1784 val = WPA_AUTH_PSK;
1785 break;
1786 default:
1787 bphy_err(drvr, "invalid akm suite (%d)\n",
1788 sme->crypto.akm_suites[0]);
1789 return -EINVAL;
1790 }
1791 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1792 switch (sme->crypto.akm_suites[0]) {
1793 case WLAN_AKM_SUITE_8021X:
1794 val = WPA2_AUTH_UNSPECIFIED;
1795 if (sme->want_1x)
1796 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1797 break;
1798 case WLAN_AKM_SUITE_8021X_SHA256:
1799 val = WPA2_AUTH_1X_SHA256;
1800 if (sme->want_1x)
1801 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1802 break;
1803 case WLAN_AKM_SUITE_PSK_SHA256:
1804 val = WPA2_AUTH_PSK_SHA256;
1805 break;
1806 case WLAN_AKM_SUITE_PSK:
1807 val = WPA2_AUTH_PSK;
1808 break;
1809 case WLAN_AKM_SUITE_FT_8021X:
1810 val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT;
1811 profile->is_ft = true;
1812 if (sme->want_1x)
1813 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1814 break;
1815 case WLAN_AKM_SUITE_FT_PSK:
1816 val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
1817 profile->is_ft = true;
1818 break;
1819 default:
1820 bphy_err(drvr, "invalid akm suite (%d)\n",
1821 sme->crypto.akm_suites[0]);
1822 return -EINVAL;
1823 }
1824 } else if (val & WPA3_AUTH_SAE_PSK) {
1825 switch (sme->crypto.akm_suites[0]) {
1826 case WLAN_AKM_SUITE_SAE:
1827 val = WPA3_AUTH_SAE_PSK;
1828 if (sme->crypto.sae_pwd) {
1829 brcmf_dbg(INFO, "using SAE offload\n");
1830 profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
1831 }
1832 break;
1833 case WLAN_AKM_SUITE_FT_OVER_SAE:
1834 val = WPA3_AUTH_SAE_PSK | WPA2_AUTH_FT;
1835 profile->is_ft = true;
1836 if (sme->crypto.sae_pwd) {
1837 brcmf_dbg(INFO, "using SAE offload\n");
1838 profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
1839 }
1840 break;
1841 default:
1842 bphy_err(drvr, "invalid akm suite (%d)\n",
1843 sme->crypto.akm_suites[0]);
1844 return -EINVAL;
1845 }
1846 }
1847
1848 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
1849 brcmf_dbg(INFO, "using 1X offload\n");
1850
1851 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
1852 goto skip_mfp_config;
1853
1854
1855
1856 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
1857 WLAN_EID_RSN);
1858 if (!rsn_ie)
1859 goto skip_mfp_config;
1860 ie = (const u8 *)rsn_ie;
1861 ie_len = rsn_ie->len + TLV_HDR_LEN;
1862
1863 offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
1864 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1865 goto skip_mfp_config;
1866
1867 count = ie[offset] + (ie[offset + 1] << 8);
1868 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1869 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1870 goto skip_mfp_config;
1871
1872 count = ie[offset] + (ie[offset + 1] << 8);
1873 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1874 if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
1875 goto skip_mfp_config;
1876
1877 mfp = BRCMF_MFP_NONE;
1878 rsn_cap = ie[offset] + (ie[offset + 1] << 8);
1879 if (rsn_cap & RSN_CAP_MFPR_MASK)
1880 mfp = BRCMF_MFP_REQUIRED;
1881 else if (rsn_cap & RSN_CAP_MFPC_MASK)
1882 mfp = BRCMF_MFP_CAPABLE;
1883 brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
1884
1885 skip_mfp_config:
1886 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1887 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1888 if (err) {
1889 bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
1890 return err;
1891 }
1892
1893 return err;
1894 }
1895
1896 static s32
1897 brcmf_set_sharedkey(struct net_device *ndev,
1898 struct cfg80211_connect_params *sme)
1899 {
1900 struct brcmf_if *ifp = netdev_priv(ndev);
1901 struct brcmf_pub *drvr = ifp->drvr;
1902 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1903 struct brcmf_cfg80211_security *sec;
1904 struct brcmf_wsec_key key;
1905 s32 val;
1906 s32 err = 0;
1907
1908 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1909
1910 if (sme->key_len == 0)
1911 return 0;
1912
1913 sec = &profile->sec;
1914 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1915 sec->wpa_versions, sec->cipher_pairwise);
1916
1917 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2 |
1918 NL80211_WPA_VERSION_3))
1919 return 0;
1920
1921 if (!(sec->cipher_pairwise &
1922 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1923 return 0;
1924
1925 memset(&key, 0, sizeof(key));
1926 key.len = (u32) sme->key_len;
1927 key.index = (u32) sme->key_idx;
1928 if (key.len > sizeof(key.data)) {
1929 bphy_err(drvr, "Too long key length (%u)\n", key.len);
1930 return -EINVAL;
1931 }
1932 memcpy(key.data, sme->key, key.len);
1933 key.flags = BRCMF_PRIMARY_KEY;
1934 switch (sec->cipher_pairwise) {
1935 case WLAN_CIPHER_SUITE_WEP40:
1936 key.algo = CRYPTO_ALGO_WEP1;
1937 break;
1938 case WLAN_CIPHER_SUITE_WEP104:
1939 key.algo = CRYPTO_ALGO_WEP128;
1940 break;
1941 default:
1942 bphy_err(drvr, "Invalid algorithm (%d)\n",
1943 sme->crypto.ciphers_pairwise[0]);
1944 return -EINVAL;
1945 }
1946
1947 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1948 key.len, key.index, key.algo);
1949 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1950 err = send_key_to_dongle(ifp, &key);
1951 if (err)
1952 return err;
1953
1954 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1955 brcmf_dbg(CONN, "set auth_type to shared key\n");
1956 val = WL_AUTH_SHARED_KEY;
1957 err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
1958 if (err)
1959 bphy_err(drvr, "set auth failed (%d)\n", err);
1960 }
1961 return err;
1962 }
1963
1964 static
1965 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1966 enum nl80211_auth_type type)
1967 {
1968 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1969 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1970 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1971 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1972 }
1973 return type;
1974 }
1975
1976 static void brcmf_set_join_pref(struct brcmf_if *ifp,
1977 struct cfg80211_bss_selection *bss_select)
1978 {
1979 struct brcmf_pub *drvr = ifp->drvr;
1980 struct brcmf_join_pref_params join_pref_params[2];
1981 enum nl80211_band band;
1982 int err, i = 0;
1983
1984 join_pref_params[i].len = 2;
1985 join_pref_params[i].rssi_gain = 0;
1986
1987 if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
1988 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
1989
1990 switch (bss_select->behaviour) {
1991 case __NL80211_BSS_SELECT_ATTR_INVALID:
1992 brcmf_c_set_joinpref_default(ifp);
1993 return;
1994 case NL80211_BSS_SELECT_ATTR_BAND_PREF:
1995 join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
1996 band = bss_select->param.band_pref;
1997 join_pref_params[i].band = nl80211_band_to_fwil(band);
1998 i++;
1999 break;
2000 case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
2001 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
2002 band = bss_select->param.adjust.band;
2003 join_pref_params[i].band = nl80211_band_to_fwil(band);
2004 join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
2005 i++;
2006 break;
2007 case NL80211_BSS_SELECT_ATTR_RSSI:
2008 default:
2009 break;
2010 }
2011 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
2012 join_pref_params[i].len = 2;
2013 join_pref_params[i].rssi_gain = 0;
2014 join_pref_params[i].band = 0;
2015 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
2016 sizeof(join_pref_params));
2017 if (err)
2018 bphy_err(drvr, "Set join_pref error (%d)\n", err);
2019 }
2020
2021 static s32
2022 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
2023 struct cfg80211_connect_params *sme)
2024 {
2025 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2026 struct brcmf_if *ifp = netdev_priv(ndev);
2027 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2028 struct ieee80211_channel *chan = sme->channel;
2029 struct brcmf_pub *drvr = ifp->drvr;
2030 struct brcmf_join_params join_params;
2031 size_t join_params_size;
2032 const struct brcmf_tlv *rsn_ie;
2033 const struct brcmf_vs_tlv *wpa_ie;
2034 const void *ie;
2035 u32 ie_len;
2036 struct brcmf_ext_join_params_le *ext_join_params;
2037 u16 chanspec;
2038 s32 err = 0;
2039 u32 ssid_len;
2040
2041 brcmf_dbg(TRACE, "Enter\n");
2042 if (!check_vif_up(ifp->vif))
2043 return -EIO;
2044
2045 if (!sme->ssid) {
2046 bphy_err(drvr, "Invalid ssid\n");
2047 return -EOPNOTSUPP;
2048 }
2049
2050 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
2051
2052 ie = NULL;
2053 ie_len = 0;
2054
2055 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
2056 if (wpa_ie) {
2057 ie = wpa_ie;
2058 ie_len = wpa_ie->len + TLV_HDR_LEN;
2059 } else {
2060
2061 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
2062 sme->ie_len,
2063 WLAN_EID_RSN);
2064 if (rsn_ie) {
2065 ie = rsn_ie;
2066 ie_len = rsn_ie->len + TLV_HDR_LEN;
2067 }
2068 }
2069 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
2070 }
2071
2072 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
2073 sme->ie, sme->ie_len);
2074 if (err)
2075 bphy_err(drvr, "Set Assoc REQ IE Failed\n");
2076 else
2077 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
2078
2079 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2080
2081 if (chan) {
2082 cfg->channel =
2083 ieee80211_frequency_to_channel(chan->center_freq);
2084 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
2085 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
2086 cfg->channel, chan->center_freq, chanspec);
2087 } else {
2088 cfg->channel = 0;
2089 chanspec = 0;
2090 }
2091
2092 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
2093
2094 err = brcmf_set_wpa_version(ndev, sme);
2095 if (err) {
2096 bphy_err(drvr, "wl_set_wpa_version failed (%d)\n", err);
2097 goto done;
2098 }
2099
2100 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
2101 err = brcmf_set_auth_type(ndev, sme);
2102 if (err) {
2103 bphy_err(drvr, "wl_set_auth_type failed (%d)\n", err);
2104 goto done;
2105 }
2106
2107 err = brcmf_set_wsec_mode(ndev, sme);
2108 if (err) {
2109 bphy_err(drvr, "wl_set_set_cipher failed (%d)\n", err);
2110 goto done;
2111 }
2112
2113 err = brcmf_set_key_mgmt(ndev, sme);
2114 if (err) {
2115 bphy_err(drvr, "wl_set_key_mgmt failed (%d)\n", err);
2116 goto done;
2117 }
2118
2119 err = brcmf_set_sharedkey(ndev, sme);
2120 if (err) {
2121 bphy_err(drvr, "brcmf_set_sharedkey failed (%d)\n", err);
2122 goto done;
2123 }
2124
2125 if (sme->crypto.psk &&
2126 profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
2127 if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
2128 err = -EINVAL;
2129 goto done;
2130 }
2131 brcmf_dbg(INFO, "using PSK offload\n");
2132 profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
2133 }
2134
2135 if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
2136
2137 err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
2138 if (err < 0) {
2139 bphy_err(drvr, "failed to enable fw supplicant\n");
2140 goto done;
2141 }
2142 }
2143
2144 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
2145 err = brcmf_set_pmk(ifp, sme->crypto.psk,
2146 BRCMF_WSEC_MAX_PSK_LEN);
2147 else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
2148
2149 err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0);
2150 if (err) {
2151 bphy_err(drvr, "failed to clean up user-space RSNE\n");
2152 goto done;
2153 }
2154 err = brcmf_set_sae_password(ifp, sme->crypto.sae_pwd,
2155 sme->crypto.sae_pwd_len);
2156 if (!err && sme->crypto.psk)
2157 err = brcmf_set_pmk(ifp, sme->crypto.psk,
2158 BRCMF_WSEC_MAX_PSK_LEN);
2159 }
2160 if (err)
2161 goto done;
2162
2163
2164
2165
2166 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
2167 offsetof(struct brcmf_assoc_params_le, chanspec_list);
2168 if (cfg->channel)
2169 join_params_size += sizeof(u16);
2170 ext_join_params = kzalloc(sizeof(*ext_join_params), GFP_KERNEL);
2171 if (ext_join_params == NULL) {
2172 err = -ENOMEM;
2173 goto done;
2174 }
2175 ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
2176 ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
2177 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
2178 if (ssid_len < IEEE80211_MAX_SSID_LEN)
2179 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
2180 ext_join_params->ssid_le.SSID, ssid_len);
2181
2182
2183 ext_join_params->scan_le.scan_type = -1;
2184 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
2185
2186 if (sme->bssid)
2187 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
2188 else
2189 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
2190
2191 if (cfg->channel) {
2192 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
2193
2194 ext_join_params->assoc_le.chanspec_list[0] =
2195 cpu_to_le16(chanspec);
2196
2197
2198
2199
2200 ext_join_params->scan_le.active_time =
2201 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
2202 ext_join_params->scan_le.passive_time =
2203 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
2204
2205
2206
2207
2208 ext_join_params->scan_le.nprobes =
2209 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
2210 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
2211 } else {
2212 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
2213 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
2214 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
2215 }
2216
2217 brcmf_set_join_pref(ifp, &sme->bss_select);
2218
2219 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
2220 join_params_size);
2221 kfree(ext_join_params);
2222 if (!err)
2223
2224 goto done;
2225
2226
2227 memset(&join_params, 0, sizeof(join_params));
2228 join_params_size = sizeof(join_params.ssid_le);
2229
2230 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
2231 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
2232
2233 if (sme->bssid)
2234 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
2235 else
2236 eth_broadcast_addr(join_params.params_le.bssid);
2237
2238 if (cfg->channel) {
2239 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
2240 join_params.params_le.chanspec_num = cpu_to_le32(1);
2241 join_params_size += sizeof(join_params.params_le);
2242 }
2243 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
2244 &join_params, join_params_size);
2245 if (err)
2246 bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err);
2247
2248 done:
2249 if (err)
2250 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2251 brcmf_dbg(TRACE, "Exit\n");
2252 return err;
2253 }
2254
2255 static s32
2256 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2257 u16 reason_code)
2258 {
2259 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2260 struct brcmf_if *ifp = netdev_priv(ndev);
2261 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2262 struct brcmf_pub *drvr = cfg->pub;
2263 struct brcmf_scb_val_le scbval;
2264 s32 err = 0;
2265
2266 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
2267 if (!check_vif_up(ifp->vif))
2268 return -EIO;
2269
2270 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2271 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2272 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2273
2274 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2275 scbval.val = cpu_to_le32(reason_code);
2276 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2277 &scbval, sizeof(scbval));
2278 if (err)
2279 bphy_err(drvr, "error (%d)\n", err);
2280
2281 brcmf_dbg(TRACE, "Exit\n");
2282 return err;
2283 }
2284
2285 static s32
2286 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2287 enum nl80211_tx_power_setting type, s32 mbm)
2288 {
2289 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2290 struct net_device *ndev = cfg_to_ndev(cfg);
2291 struct brcmf_if *ifp = netdev_priv(ndev);
2292 struct brcmf_pub *drvr = cfg->pub;
2293 s32 err;
2294 s32 disable;
2295 u32 qdbm = 127;
2296
2297 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
2298 if (!check_vif_up(ifp->vif))
2299 return -EIO;
2300
2301 switch (type) {
2302 case NL80211_TX_POWER_AUTOMATIC:
2303 break;
2304 case NL80211_TX_POWER_LIMITED:
2305 case NL80211_TX_POWER_FIXED:
2306 if (mbm < 0) {
2307 bphy_err(drvr, "TX_POWER_FIXED - dbm is negative\n");
2308 err = -EINVAL;
2309 goto done;
2310 }
2311 qdbm = MBM_TO_DBM(4 * mbm);
2312 if (qdbm > 127)
2313 qdbm = 127;
2314 qdbm |= WL_TXPWR_OVERRIDE;
2315 break;
2316 default:
2317 bphy_err(drvr, "Unsupported type %d\n", type);
2318 err = -EINVAL;
2319 goto done;
2320 }
2321
2322 disable = WL_RADIO_SW_DISABLE << 16;
2323 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2324 if (err)
2325 bphy_err(drvr, "WLC_SET_RADIO error (%d)\n", err);
2326
2327 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2328 if (err)
2329 bphy_err(drvr, "qtxpower error (%d)\n", err);
2330
2331 done:
2332 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2333 return err;
2334 }
2335
2336 static s32
2337 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2338 s32 *dbm)
2339 {
2340 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2341 struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
2342 struct brcmf_pub *drvr = cfg->pub;
2343 s32 qdbm = 0;
2344 s32 err;
2345
2346 brcmf_dbg(TRACE, "Enter\n");
2347 if (!check_vif_up(vif))
2348 return -EIO;
2349
2350 err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
2351 if (err) {
2352 bphy_err(drvr, "error (%d)\n", err);
2353 goto done;
2354 }
2355 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2356
2357 done:
2358 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2359 return err;
2360 }
2361
2362 static s32
2363 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2364 u8 key_idx, bool unicast, bool multicast)
2365 {
2366 struct brcmf_if *ifp = netdev_priv(ndev);
2367 struct brcmf_pub *drvr = ifp->drvr;
2368 u32 index;
2369 u32 wsec;
2370 s32 err = 0;
2371
2372 brcmf_dbg(TRACE, "Enter\n");
2373 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2374 if (!check_vif_up(ifp->vif))
2375 return -EIO;
2376
2377 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2378 if (err) {
2379 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2380 goto done;
2381 }
2382
2383 if (wsec & WEP_ENABLED) {
2384
2385 index = key_idx;
2386 err = brcmf_fil_cmd_int_set(ifp,
2387 BRCMF_C_SET_KEY_PRIMARY, index);
2388 if (err)
2389 bphy_err(drvr, "error (%d)\n", err);
2390 }
2391 done:
2392 brcmf_dbg(TRACE, "Exit\n");
2393 return err;
2394 }
2395
2396 static s32
2397 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2398 u8 key_idx, bool pairwise, const u8 *mac_addr)
2399 {
2400 struct brcmf_if *ifp = netdev_priv(ndev);
2401 struct brcmf_wsec_key *key;
2402 s32 err;
2403
2404 brcmf_dbg(TRACE, "Enter\n");
2405 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2406
2407 if (!check_vif_up(ifp->vif))
2408 return -EIO;
2409
2410 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2411
2412 return -EINVAL;
2413 }
2414
2415 key = &ifp->vif->profile.key[key_idx];
2416
2417 if (key->algo == CRYPTO_ALGO_OFF) {
2418 brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2419 return -EINVAL;
2420 }
2421
2422 memset(key, 0, sizeof(*key));
2423 key->index = (u32)key_idx;
2424 key->flags = BRCMF_PRIMARY_KEY;
2425
2426
2427 err = send_key_to_dongle(ifp, key);
2428
2429 brcmf_dbg(TRACE, "Exit\n");
2430 return err;
2431 }
2432
2433 static s32
2434 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2435 u8 key_idx, bool pairwise, const u8 *mac_addr,
2436 struct key_params *params)
2437 {
2438 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2439 struct brcmf_if *ifp = netdev_priv(ndev);
2440 struct brcmf_pub *drvr = cfg->pub;
2441 struct brcmf_wsec_key *key;
2442 s32 val;
2443 s32 wsec;
2444 s32 err;
2445 u8 keybuf[8];
2446 bool ext_key;
2447
2448 brcmf_dbg(TRACE, "Enter\n");
2449 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2450 if (!check_vif_up(ifp->vif))
2451 return -EIO;
2452
2453 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2454
2455 bphy_err(drvr, "invalid key index (%d)\n", key_idx);
2456 return -EINVAL;
2457 }
2458
2459 if (params->key_len == 0)
2460 return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
2461 mac_addr);
2462
2463 if (params->key_len > sizeof(key->data)) {
2464 bphy_err(drvr, "Too long key length (%u)\n", params->key_len);
2465 return -EINVAL;
2466 }
2467
2468 ext_key = false;
2469 if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2470 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2471 brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2472 ext_key = true;
2473 }
2474
2475 key = &ifp->vif->profile.key[key_idx];
2476 memset(key, 0, sizeof(*key));
2477 if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2478 memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2479 key->len = params->key_len;
2480 key->index = key_idx;
2481 memcpy(key->data, params->key, key->len);
2482 if (!ext_key)
2483 key->flags = BRCMF_PRIMARY_KEY;
2484
2485 if (params->seq && params->seq_len == 6) {
2486
2487 u8 *ivptr;
2488
2489 ivptr = (u8 *)params->seq;
2490 key->rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2491 (ivptr[3] << 8) | ivptr[2];
2492 key->rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2493 key->iv_initialized = true;
2494 }
2495
2496 switch (params->cipher) {
2497 case WLAN_CIPHER_SUITE_WEP40:
2498 key->algo = CRYPTO_ALGO_WEP1;
2499 val = WEP_ENABLED;
2500 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2501 break;
2502 case WLAN_CIPHER_SUITE_WEP104:
2503 key->algo = CRYPTO_ALGO_WEP128;
2504 val = WEP_ENABLED;
2505 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2506 break;
2507 case WLAN_CIPHER_SUITE_TKIP:
2508 if (!brcmf_is_apmode(ifp->vif)) {
2509 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2510 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2511 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2512 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2513 }
2514 key->algo = CRYPTO_ALGO_TKIP;
2515 val = TKIP_ENABLED;
2516 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2517 break;
2518 case WLAN_CIPHER_SUITE_AES_CMAC:
2519 key->algo = CRYPTO_ALGO_AES_CCM;
2520 val = AES_ENABLED;
2521 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2522 break;
2523 case WLAN_CIPHER_SUITE_CCMP:
2524 key->algo = CRYPTO_ALGO_AES_CCM;
2525 val = AES_ENABLED;
2526 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2527 break;
2528 default:
2529 bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher);
2530 err = -EINVAL;
2531 goto done;
2532 }
2533
2534 err = send_key_to_dongle(ifp, key);
2535 if (ext_key || err)
2536 goto done;
2537
2538 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2539 if (err) {
2540 bphy_err(drvr, "get wsec error (%d)\n", err);
2541 goto done;
2542 }
2543 wsec |= val;
2544 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2545 if (err) {
2546 bphy_err(drvr, "set wsec error (%d)\n", err);
2547 goto done;
2548 }
2549
2550 done:
2551 brcmf_dbg(TRACE, "Exit\n");
2552 return err;
2553 }
2554
2555 static s32
2556 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
2557 bool pairwise, const u8 *mac_addr, void *cookie,
2558 void (*callback)(void *cookie,
2559 struct key_params *params))
2560 {
2561 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2562 struct key_params params;
2563 struct brcmf_if *ifp = netdev_priv(ndev);
2564 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2565 struct brcmf_pub *drvr = cfg->pub;
2566 struct brcmf_cfg80211_security *sec;
2567 s32 wsec;
2568 s32 err = 0;
2569
2570 brcmf_dbg(TRACE, "Enter\n");
2571 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2572 if (!check_vif_up(ifp->vif))
2573 return -EIO;
2574
2575 memset(¶ms, 0, sizeof(params));
2576
2577 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2578 if (err) {
2579 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2580
2581 err = -EAGAIN;
2582 goto done;
2583 }
2584 if (wsec & WEP_ENABLED) {
2585 sec = &profile->sec;
2586 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2587 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2588 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2589 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2590 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2591 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2592 }
2593 } else if (wsec & TKIP_ENABLED) {
2594 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2595 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2596 } else if (wsec & AES_ENABLED) {
2597 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2598 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2599 } else {
2600 bphy_err(drvr, "Invalid algo (0x%x)\n", wsec);
2601 err = -EINVAL;
2602 goto done;
2603 }
2604 callback(cookie, ¶ms);
2605
2606 done:
2607 brcmf_dbg(TRACE, "Exit\n");
2608 return err;
2609 }
2610
2611 static s32
2612 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2613 struct net_device *ndev, u8 key_idx)
2614 {
2615 struct brcmf_if *ifp = netdev_priv(ndev);
2616
2617 brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2618
2619 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2620 return 0;
2621
2622 brcmf_dbg(INFO, "Not supported\n");
2623
2624 return -EOPNOTSUPP;
2625 }
2626
2627 static void
2628 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2629 {
2630 struct brcmf_pub *drvr = ifp->drvr;
2631 s32 err;
2632 u8 key_idx;
2633 struct brcmf_wsec_key *key;
2634 s32 wsec;
2635
2636 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2637 key = &ifp->vif->profile.key[key_idx];
2638 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2639 (key->algo == CRYPTO_ALGO_WEP128))
2640 break;
2641 }
2642 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2643 return;
2644
2645 err = send_key_to_dongle(ifp, key);
2646 if (err) {
2647 bphy_err(drvr, "Setting WEP key failed (%d)\n", err);
2648 return;
2649 }
2650 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2651 if (err) {
2652 bphy_err(drvr, "get wsec error (%d)\n", err);
2653 return;
2654 }
2655 wsec |= WEP_ENABLED;
2656 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2657 if (err)
2658 bphy_err(drvr, "set wsec error (%d)\n", err);
2659 }
2660
2661 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2662 {
2663 struct nl80211_sta_flag_update *sfu;
2664
2665 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2666 si->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS);
2667 sfu = &si->sta_flags;
2668 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2669 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2670 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2671 BIT(NL80211_STA_FLAG_AUTHORIZED);
2672 if (fw_sta_flags & BRCMF_STA_WME)
2673 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2674 if (fw_sta_flags & BRCMF_STA_AUTHE)
2675 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2676 if (fw_sta_flags & BRCMF_STA_ASSOC)
2677 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2678 if (fw_sta_flags & BRCMF_STA_AUTHO)
2679 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2680 }
2681
2682 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2683 {
2684 struct brcmf_pub *drvr = ifp->drvr;
2685 struct {
2686 __le32 len;
2687 struct brcmf_bss_info_le bss_le;
2688 } *buf;
2689 u16 capability;
2690 int err;
2691
2692 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2693 if (!buf)
2694 return;
2695
2696 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2697 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2698 WL_BSS_INFO_MAX);
2699 if (err) {
2700 bphy_err(drvr, "Failed to get bss info (%d)\n", err);
2701 goto out_kfree;
2702 }
2703 si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
2704 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2705 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2706 capability = le16_to_cpu(buf->bss_le.capability);
2707 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2708 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2709 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2710 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2711 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2712 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2713
2714 out_kfree:
2715 kfree(buf);
2716 }
2717
2718 static s32
2719 brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
2720 struct station_info *sinfo)
2721 {
2722 struct brcmf_pub *drvr = ifp->drvr;
2723 struct brcmf_scb_val_le scbval;
2724 struct brcmf_pktcnt_le pktcnt;
2725 s32 err;
2726 u32 rate;
2727 u32 rssi;
2728
2729
2730 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2731 if (err < 0) {
2732 bphy_err(drvr, "BRCMF_C_GET_RATE error (%d)\n", err);
2733 return err;
2734 }
2735 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
2736 sinfo->txrate.legacy = rate * 5;
2737
2738 memset(&scbval, 0, sizeof(scbval));
2739 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
2740 sizeof(scbval));
2741 if (err) {
2742 bphy_err(drvr, "BRCMF_C_GET_RSSI error (%d)\n", err);
2743 return err;
2744 }
2745 rssi = le32_to_cpu(scbval.val);
2746 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2747 sinfo->signal = rssi;
2748
2749 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
2750 sizeof(pktcnt));
2751 if (err) {
2752 bphy_err(drvr, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
2753 return err;
2754 }
2755 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
2756 BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
2757 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
2758 BIT_ULL(NL80211_STA_INFO_TX_FAILED);
2759 sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
2760 sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
2761 sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
2762 sinfo->tx_failed = le32_to_cpu(pktcnt.tx_bad_pkt);
2763
2764 return 0;
2765 }
2766
2767 static s32
2768 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2769 const u8 *mac, struct station_info *sinfo)
2770 {
2771 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2772 struct brcmf_if *ifp = netdev_priv(ndev);
2773 struct brcmf_pub *drvr = cfg->pub;
2774 struct brcmf_scb_val_le scb_val;
2775 s32 err = 0;
2776 struct brcmf_sta_info_le sta_info_le;
2777 u32 sta_flags;
2778 u32 is_tdls_peer;
2779 s32 total_rssi_avg = 0;
2780 s32 total_rssi = 0;
2781 s32 count_rssi = 0;
2782 int rssi;
2783 u32 i;
2784
2785 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2786 if (!check_vif_up(ifp->vif))
2787 return -EIO;
2788
2789 if (brcmf_is_ibssmode(ifp->vif))
2790 return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
2791
2792 memset(&sta_info_le, 0, sizeof(sta_info_le));
2793 memcpy(&sta_info_le, mac, ETH_ALEN);
2794 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2795 &sta_info_le,
2796 sizeof(sta_info_le));
2797 is_tdls_peer = !err;
2798 if (err) {
2799 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2800 &sta_info_le,
2801 sizeof(sta_info_le));
2802 if (err < 0) {
2803 bphy_err(drvr, "GET STA INFO failed, %d\n", err);
2804 goto done;
2805 }
2806 }
2807 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2808 sinfo->filled = BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
2809 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2810 sta_flags = le32_to_cpu(sta_info_le.flags);
2811 brcmf_convert_sta_flags(sta_flags, sinfo);
2812 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2813 if (is_tdls_peer)
2814 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2815 else
2816 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2817 if (sta_flags & BRCMF_STA_ASSOC) {
2818 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME);
2819 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2820 brcmf_fill_bss_param(ifp, sinfo);
2821 }
2822 if (sta_flags & BRCMF_STA_SCBSTATS) {
2823 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
2824 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2825 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
2826 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2827 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2828 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
2829 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2830 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2831 if (sinfo->tx_packets) {
2832 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
2833 sinfo->txrate.legacy =
2834 le32_to_cpu(sta_info_le.tx_rate) / 100;
2835 }
2836 if (sinfo->rx_packets) {
2837 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
2838 sinfo->rxrate.legacy =
2839 le32_to_cpu(sta_info_le.rx_rate) / 100;
2840 }
2841 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2842 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES);
2843 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2844 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
2845 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2846 }
2847 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2848 if (sta_info_le.rssi[i] == 0 ||
2849 sta_info_le.rx_lastpkt_rssi[i] == 0)
2850 continue;
2851 sinfo->chains |= BIT(count_rssi);
2852 sinfo->chain_signal[count_rssi] =
2853 sta_info_le.rx_lastpkt_rssi[i];
2854 sinfo->chain_signal_avg[count_rssi] =
2855 sta_info_le.rssi[i];
2856 total_rssi += sta_info_le.rx_lastpkt_rssi[i];
2857 total_rssi_avg += sta_info_le.rssi[i];
2858 count_rssi++;
2859 }
2860 if (count_rssi) {
2861 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2862 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
2863 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
2864 sinfo->filled |=
2865 BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
2866 sinfo->signal = total_rssi / count_rssi;
2867 sinfo->signal_avg = total_rssi_avg / count_rssi;
2868 } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2869 &ifp->vif->sme_state)) {
2870 memset(&scb_val, 0, sizeof(scb_val));
2871 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2872 &scb_val, sizeof(scb_val));
2873 if (err) {
2874 bphy_err(drvr, "Could not get rssi (%d)\n",
2875 err);
2876 goto done;
2877 } else {
2878 rssi = le32_to_cpu(scb_val.val);
2879 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2880 sinfo->signal = rssi;
2881 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2882 }
2883 }
2884 }
2885 done:
2886 brcmf_dbg(TRACE, "Exit\n");
2887 return err;
2888 }
2889
2890 static int
2891 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2892 int idx, u8 *mac, struct station_info *sinfo)
2893 {
2894 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2895 struct brcmf_if *ifp = netdev_priv(ndev);
2896 struct brcmf_pub *drvr = cfg->pub;
2897 s32 err;
2898
2899 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2900
2901 if (idx == 0) {
2902 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2903 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2904 &cfg->assoclist,
2905 sizeof(cfg->assoclist));
2906 if (err) {
2907
2908 if (err == -EBADE)
2909 bphy_info_once(drvr, "BRCMF_C_GET_ASSOCLIST unsupported\n");
2910 else
2911 bphy_err(drvr, "BRCMF_C_GET_ASSOCLIST failed, err=%d\n",
2912 err);
2913
2914 cfg->assoclist.count = 0;
2915 return -EOPNOTSUPP;
2916 }
2917 }
2918 if (idx < le32_to_cpu(cfg->assoclist.count)) {
2919 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2920 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2921 }
2922 return -ENOENT;
2923 }
2924
2925 static s32
2926 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2927 bool enabled, s32 timeout)
2928 {
2929 s32 pm;
2930 s32 err = 0;
2931 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2932 struct brcmf_if *ifp = netdev_priv(ndev);
2933 struct brcmf_pub *drvr = cfg->pub;
2934
2935 brcmf_dbg(TRACE, "Enter\n");
2936
2937
2938
2939
2940
2941
2942
2943
2944 cfg->pwr_save = enabled;
2945 if (!check_vif_up(ifp->vif)) {
2946
2947 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2948 goto done;
2949 }
2950
2951 pm = enabled ? PM_FAST : PM_OFF;
2952
2953 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2954 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2955 pm = PM_OFF;
2956 }
2957 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2958
2959 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2960 if (err) {
2961 if (err == -ENODEV)
2962 bphy_err(drvr, "net_device is not ready yet\n");
2963 else
2964 bphy_err(drvr, "error (%d)\n", err);
2965 }
2966
2967 err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret",
2968 min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS));
2969 if (err)
2970 bphy_err(drvr, "Unable to set pm timeout, (%d)\n", err);
2971
2972 done:
2973 brcmf_dbg(TRACE, "Exit\n");
2974 return err;
2975 }
2976
2977 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2978 struct brcmf_bss_info_le *bi)
2979 {
2980 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2981 struct brcmf_pub *drvr = cfg->pub;
2982 struct cfg80211_bss *bss;
2983 enum nl80211_band band;
2984 struct brcmu_chan ch;
2985 u16 channel;
2986 u32 freq;
2987 u16 notify_capability;
2988 u16 notify_interval;
2989 u8 *notify_ie;
2990 size_t notify_ielen;
2991 struct cfg80211_inform_bss bss_data = {};
2992
2993 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2994 bphy_err(drvr, "Bss info is larger than buffer. Discarding\n");
2995 return -EINVAL;
2996 }
2997
2998 if (!bi->ctl_ch) {
2999 ch.chspec = le16_to_cpu(bi->chanspec);
3000 cfg->d11inf.decchspec(&ch);
3001 bi->ctl_ch = ch.control_ch_num;
3002 }
3003 channel = bi->ctl_ch;
3004
3005 if (channel <= CH_MAX_2G_CHANNEL)
3006 band = NL80211_BAND_2GHZ;
3007 else
3008 band = NL80211_BAND_5GHZ;
3009
3010 freq = ieee80211_channel_to_frequency(channel, band);
3011 bss_data.chan = ieee80211_get_channel(wiphy, freq);
3012 bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
3013 bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
3014
3015 notify_capability = le16_to_cpu(bi->capability);
3016 notify_interval = le16_to_cpu(bi->beacon_period);
3017 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3018 notify_ielen = le32_to_cpu(bi->ie_length);
3019 bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3020
3021 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
3022 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
3023 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
3024 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
3025 brcmf_dbg(CONN, "Signal: %d\n", bss_data.signal);
3026
3027 bss = cfg80211_inform_bss_data(wiphy, &bss_data,
3028 CFG80211_BSS_FTYPE_UNKNOWN,
3029 (const u8 *)bi->BSSID,
3030 0, notify_capability,
3031 notify_interval, notify_ie,
3032 notify_ielen, GFP_KERNEL);
3033
3034 if (!bss)
3035 return -ENOMEM;
3036
3037 cfg80211_put_bss(wiphy, bss);
3038
3039 return 0;
3040 }
3041
3042 static struct brcmf_bss_info_le *
3043 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
3044 {
3045 if (bss == NULL)
3046 return list->bss_info_le;
3047 return (struct brcmf_bss_info_le *)((unsigned long)bss +
3048 le32_to_cpu(bss->length));
3049 }
3050
3051 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
3052 {
3053 struct brcmf_pub *drvr = cfg->pub;
3054 struct brcmf_scan_results *bss_list;
3055 struct brcmf_bss_info_le *bi = NULL;
3056 s32 err = 0;
3057 int i;
3058
3059 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
3060 if (bss_list->count != 0 &&
3061 bss_list->version != BRCMF_BSS_INFO_VERSION) {
3062 bphy_err(drvr, "Version %d != WL_BSS_INFO_VERSION\n",
3063 bss_list->version);
3064 return -EOPNOTSUPP;
3065 }
3066 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
3067 for (i = 0; i < bss_list->count; i++) {
3068 bi = next_bss_le(bss_list, bi);
3069 err = brcmf_inform_single_bss(cfg, bi);
3070 if (err)
3071 break;
3072 }
3073 return err;
3074 }
3075
3076 static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
3077 struct net_device *ndev, const u8 *bssid)
3078 {
3079 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3080 struct brcmf_pub *drvr = cfg->pub;
3081 struct ieee80211_channel *notify_channel;
3082 struct brcmf_bss_info_le *bi = NULL;
3083 struct ieee80211_supported_band *band;
3084 struct cfg80211_bss *bss;
3085 struct brcmu_chan ch;
3086 u8 *buf = NULL;
3087 s32 err = 0;
3088 u32 freq;
3089 u16 notify_capability;
3090 u16 notify_interval;
3091 u8 *notify_ie;
3092 size_t notify_ielen;
3093 s32 notify_signal;
3094
3095 brcmf_dbg(TRACE, "Enter\n");
3096
3097 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3098 if (buf == NULL) {
3099 err = -ENOMEM;
3100 goto CleanUp;
3101 }
3102
3103 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3104
3105 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
3106 buf, WL_BSS_INFO_MAX);
3107 if (err) {
3108 bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err);
3109 goto CleanUp;
3110 }
3111
3112 bi = (struct brcmf_bss_info_le *)(buf + 4);
3113
3114 ch.chspec = le16_to_cpu(bi->chanspec);
3115 cfg->d11inf.decchspec(&ch);
3116
3117 if (ch.band == BRCMU_CHAN_BAND_2G)
3118 band = wiphy->bands[NL80211_BAND_2GHZ];
3119 else
3120 band = wiphy->bands[NL80211_BAND_5GHZ];
3121
3122 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
3123 cfg->channel = freq;
3124 notify_channel = ieee80211_get_channel(wiphy, freq);
3125
3126 notify_capability = le16_to_cpu(bi->capability);
3127 notify_interval = le16_to_cpu(bi->beacon_period);
3128 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3129 notify_ielen = le32_to_cpu(bi->ie_length);
3130 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3131
3132 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
3133 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
3134 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
3135 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
3136
3137 bss = cfg80211_inform_bss(wiphy, notify_channel,
3138 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
3139 notify_capability, notify_interval,
3140 notify_ie, notify_ielen, notify_signal,
3141 GFP_KERNEL);
3142
3143 if (!bss) {
3144 err = -ENOMEM;
3145 goto CleanUp;
3146 }
3147
3148 cfg80211_put_bss(wiphy, bss);
3149
3150 CleanUp:
3151
3152 kfree(buf);
3153
3154 brcmf_dbg(TRACE, "Exit\n");
3155
3156 return err;
3157 }
3158
3159 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
3160 struct brcmf_if *ifp)
3161 {
3162 struct brcmf_pub *drvr = cfg->pub;
3163 struct brcmf_bss_info_le *bi;
3164 const struct brcmf_tlv *tim;
3165 size_t ie_len;
3166 u8 *ie;
3167 s32 err = 0;
3168
3169 brcmf_dbg(TRACE, "Enter\n");
3170 if (brcmf_is_ibssmode(ifp->vif))
3171 return err;
3172
3173 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
3174 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3175 cfg->extra_buf, WL_EXTRA_BUF_MAX);
3176 if (err) {
3177 bphy_err(drvr, "Could not get bss info %d\n", err);
3178 goto update_bss_info_out;
3179 }
3180
3181 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
3182 err = brcmf_inform_single_bss(cfg, bi);
3183 if (err)
3184 goto update_bss_info_out;
3185
3186 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
3187 ie_len = le32_to_cpu(bi->ie_length);
3188
3189 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
3190 if (!tim) {
3191
3192
3193
3194
3195
3196 u32 var;
3197 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
3198 if (err) {
3199 bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err);
3200 goto update_bss_info_out;
3201 }
3202 }
3203
3204 update_bss_info_out:
3205 brcmf_dbg(TRACE, "Exit");
3206 return err;
3207 }
3208
3209 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
3210 {
3211 struct escan_info *escan = &cfg->escan_info;
3212
3213 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3214 if (cfg->int_escan_map || cfg->scan_request) {
3215 escan->escan_state = WL_ESCAN_STATE_IDLE;
3216 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
3217 }
3218 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3219 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3220 }
3221
3222 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
3223 {
3224 struct brcmf_cfg80211_info *cfg =
3225 container_of(work, struct brcmf_cfg80211_info,
3226 escan_timeout_work);
3227
3228 brcmf_inform_bss(cfg);
3229 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
3230 }
3231
3232 static void brcmf_escan_timeout(struct timer_list *t)
3233 {
3234 struct brcmf_cfg80211_info *cfg =
3235 from_timer(cfg, t, escan_timeout);
3236 struct brcmf_pub *drvr = cfg->pub;
3237
3238 if (cfg->int_escan_map || cfg->scan_request) {
3239 bphy_err(drvr, "timer expired\n");
3240 schedule_work(&cfg->escan_timeout_work);
3241 }
3242 }
3243
3244 static s32
3245 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
3246 struct brcmf_bss_info_le *bss,
3247 struct brcmf_bss_info_le *bss_info_le)
3248 {
3249 struct brcmu_chan ch_bss, ch_bss_info_le;
3250
3251 ch_bss.chspec = le16_to_cpu(bss->chanspec);
3252 cfg->d11inf.decchspec(&ch_bss);
3253 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
3254 cfg->d11inf.decchspec(&ch_bss_info_le);
3255
3256 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3257 ch_bss.band == ch_bss_info_le.band &&
3258 bss_info_le->SSID_len == bss->SSID_len &&
3259 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3260 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
3261 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
3262 s16 bss_rssi = le16_to_cpu(bss->RSSI);
3263 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3264
3265
3266
3267
3268 if (bss_info_rssi > bss_rssi)
3269 bss->RSSI = bss_info_le->RSSI;
3270 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
3271 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
3272
3273
3274
3275 bss->RSSI = bss_info_le->RSSI;
3276 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
3277 }
3278 return 1;
3279 }
3280 return 0;
3281 }
3282
3283 static s32
3284 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3285 const struct brcmf_event_msg *e, void *data)
3286 {
3287 struct brcmf_pub *drvr = ifp->drvr;
3288 struct brcmf_cfg80211_info *cfg = drvr->config;
3289 s32 status;
3290 struct brcmf_escan_result_le *escan_result_le;
3291 u32 escan_buflen;
3292 struct brcmf_bss_info_le *bss_info_le;
3293 struct brcmf_bss_info_le *bss = NULL;
3294 u32 bi_length;
3295 struct brcmf_scan_results *list;
3296 u32 i;
3297 bool aborted;
3298
3299 status = e->status;
3300
3301 if (status == BRCMF_E_STATUS_ABORT)
3302 goto exit;
3303
3304 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3305 bphy_err(drvr, "scan not ready, bsscfgidx=%d\n",
3306 ifp->bsscfgidx);
3307 return -EPERM;
3308 }
3309
3310 if (status == BRCMF_E_STATUS_PARTIAL) {
3311 brcmf_dbg(SCAN, "ESCAN Partial result\n");
3312 if (e->datalen < sizeof(*escan_result_le)) {
3313 bphy_err(drvr, "invalid event data length\n");
3314 goto exit;
3315 }
3316 escan_result_le = (struct brcmf_escan_result_le *) data;
3317 if (!escan_result_le) {
3318 bphy_err(drvr, "Invalid escan result (NULL pointer)\n");
3319 goto exit;
3320 }
3321 escan_buflen = le32_to_cpu(escan_result_le->buflen);
3322 if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3323 escan_buflen > e->datalen ||
3324 escan_buflen < sizeof(*escan_result_le)) {
3325 bphy_err(drvr, "Invalid escan buffer length: %d\n",
3326 escan_buflen);
3327 goto exit;
3328 }
3329 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3330 bphy_err(drvr, "Invalid bss_count %d: ignoring\n",
3331 escan_result_le->bss_count);
3332 goto exit;
3333 }
3334 bss_info_le = &escan_result_le->bss_info_le;
3335
3336 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3337 goto exit;
3338
3339 if (!cfg->int_escan_map && !cfg->scan_request) {
3340 brcmf_dbg(SCAN, "result without cfg80211 request\n");
3341 goto exit;
3342 }
3343
3344 bi_length = le32_to_cpu(bss_info_le->length);
3345 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
3346 bphy_err(drvr, "Ignoring invalid bss_info length: %d\n",
3347 bi_length);
3348 goto exit;
3349 }
3350
3351 if (!(cfg_to_wiphy(cfg)->interface_modes &
3352 BIT(NL80211_IFTYPE_ADHOC))) {
3353 if (le16_to_cpu(bss_info_le->capability) &
3354 WLAN_CAPABILITY_IBSS) {
3355 bphy_err(drvr, "Ignoring IBSS result\n");
3356 goto exit;
3357 }
3358 }
3359
3360 list = (struct brcmf_scan_results *)
3361 cfg->escan_info.escan_buf;
3362 if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3363 bphy_err(drvr, "Buffer is too small: ignoring\n");
3364 goto exit;
3365 }
3366
3367 for (i = 0; i < list->count; i++) {
3368 bss = bss ? (struct brcmf_bss_info_le *)
3369 ((unsigned char *)bss +
3370 le32_to_cpu(bss->length)) : list->bss_info_le;
3371 if (brcmf_compare_update_same_bss(cfg, bss,
3372 bss_info_le))
3373 goto exit;
3374 }
3375 memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3376 bi_length);
3377 list->version = le32_to_cpu(bss_info_le->version);
3378 list->buflen += bi_length;
3379 list->count++;
3380 } else {
3381 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3382 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3383 goto exit;
3384 if (cfg->int_escan_map || cfg->scan_request) {
3385 brcmf_inform_bss(cfg);
3386 aborted = status != BRCMF_E_STATUS_SUCCESS;
3387 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3388 } else
3389 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3390 status);
3391 }
3392 exit:
3393 return 0;
3394 }
3395
3396 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3397 {
3398 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3399 brcmf_cfg80211_escan_handler);
3400 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3401
3402 timer_setup(&cfg->escan_timeout, brcmf_escan_timeout, 0);
3403 INIT_WORK(&cfg->escan_timeout_work,
3404 brcmf_cfg80211_escan_timeout_worker);
3405 }
3406
3407 static struct cfg80211_scan_request *
3408 brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3409 struct cfg80211_scan_request *req;
3410 size_t req_size;
3411
3412 req_size = sizeof(*req) +
3413 n_netinfo * sizeof(req->channels[0]) +
3414 n_netinfo * sizeof(*req->ssids);
3415
3416 req = kzalloc(req_size, GFP_KERNEL);
3417 if (req) {
3418 req->wiphy = wiphy;
3419 req->ssids = (void *)(&req->channels[0]) +
3420 n_netinfo * sizeof(req->channels[0]);
3421 }
3422 return req;
3423 }
3424
3425 static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
3426 u8 *ssid, u8 ssid_len, u8 channel)
3427 {
3428 struct ieee80211_channel *chan;
3429 enum nl80211_band band;
3430 int freq, i;
3431
3432 if (channel <= CH_MAX_2G_CHANNEL)
3433 band = NL80211_BAND_2GHZ;
3434 else
3435 band = NL80211_BAND_5GHZ;
3436
3437 freq = ieee80211_channel_to_frequency(channel, band);
3438 if (!freq)
3439 return -EINVAL;
3440
3441 chan = ieee80211_get_channel(req->wiphy, freq);
3442 if (!chan)
3443 return -EINVAL;
3444
3445 for (i = 0; i < req->n_channels; i++) {
3446 if (req->channels[i] == chan)
3447 break;
3448 }
3449 if (i == req->n_channels)
3450 req->channels[req->n_channels++] = chan;
3451
3452 for (i = 0; i < req->n_ssids; i++) {
3453 if (req->ssids[i].ssid_len == ssid_len &&
3454 !memcmp(req->ssids[i].ssid, ssid, ssid_len))
3455 break;
3456 }
3457 if (i == req->n_ssids) {
3458 memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
3459 req->ssids[req->n_ssids++].ssid_len = ssid_len;
3460 }
3461 return 0;
3462 }
3463
3464 static int brcmf_start_internal_escan(struct brcmf_if *ifp, u32 fwmap,
3465 struct cfg80211_scan_request *request)
3466 {
3467 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3468 int err;
3469
3470 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3471 if (cfg->int_escan_map)
3472 brcmf_dbg(SCAN, "aborting internal scan: map=%u\n",
3473 cfg->int_escan_map);
3474
3475 brcmf_abort_scanning(cfg);
3476 }
3477
3478 brcmf_dbg(SCAN, "start internal scan: map=%u\n", fwmap);
3479 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3480 cfg->escan_info.run = brcmf_run_escan;
3481 err = brcmf_do_escan(ifp, request);
3482 if (err) {
3483 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3484 return err;
3485 }
3486 cfg->int_escan_map = fwmap;
3487 return 0;
3488 }
3489
3490 static struct brcmf_pno_net_info_le *
3491 brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
3492 {
3493 struct brcmf_pno_scanresults_v2_le *pfn_v2;
3494 struct brcmf_pno_net_info_le *netinfo;
3495
3496 switch (pfn_v1->version) {
3497 default:
3498 WARN_ON(1);
3499 fallthrough;
3500 case cpu_to_le32(1):
3501 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
3502 break;
3503 case cpu_to_le32(2):
3504 pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
3505 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
3506 break;
3507 }
3508
3509 return netinfo;
3510 }
3511
3512
3513
3514
3515
3516
3517
3518 static s32
3519 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3520 const struct brcmf_event_msg *e, void *data)
3521 {
3522 struct brcmf_pub *drvr = ifp->drvr;
3523 struct brcmf_cfg80211_info *cfg = drvr->config;
3524 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3525 struct cfg80211_scan_request *request = NULL;
3526 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3527 int i, err = 0;
3528 struct brcmf_pno_scanresults_le *pfn_result;
3529 u32 bucket_map;
3530 u32 result_count;
3531 u32 status;
3532 u32 datalen;
3533
3534 brcmf_dbg(SCAN, "Enter\n");
3535
3536 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3537 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3538 return 0;
3539 }
3540
3541 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3542 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3543 return 0;
3544 }
3545
3546 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3547 result_count = le32_to_cpu(pfn_result->count);
3548 status = le32_to_cpu(pfn_result->status);
3549
3550
3551
3552
3553 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3554 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3555 if (!result_count) {
3556 bphy_err(drvr, "FALSE PNO Event. (pfn_count == 0)\n");
3557 goto out_err;
3558 }
3559
3560 netinfo_start = brcmf_get_netinfo_array(pfn_result);
3561 datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
3562 if (datalen < result_count * sizeof(*netinfo)) {
3563 bphy_err(drvr, "insufficient event data\n");
3564 goto out_err;
3565 }
3566
3567 request = brcmf_alloc_internal_escan_request(wiphy,
3568 result_count);
3569 if (!request) {
3570 err = -ENOMEM;
3571 goto out_err;
3572 }
3573
3574 bucket_map = 0;
3575 for (i = 0; i < result_count; i++) {
3576 netinfo = &netinfo_start[i];
3577
3578 if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3579 netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3580 brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3581 netinfo->SSID, netinfo->channel);
3582 bucket_map |= brcmf_pno_get_bucket_map(cfg->pno, netinfo);
3583 err = brcmf_internal_escan_add_info(request,
3584 netinfo->SSID,
3585 netinfo->SSID_len,
3586 netinfo->channel);
3587 if (err)
3588 goto out_err;
3589 }
3590
3591 if (!bucket_map)
3592 goto free_req;
3593
3594 err = brcmf_start_internal_escan(ifp, bucket_map, request);
3595 if (!err)
3596 goto free_req;
3597
3598 out_err:
3599 cfg80211_sched_scan_stopped(wiphy, 0);
3600 free_req:
3601 kfree(request);
3602 return err;
3603 }
3604
3605 static int
3606 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3607 struct net_device *ndev,
3608 struct cfg80211_sched_scan_request *req)
3609 {
3610 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3611 struct brcmf_if *ifp = netdev_priv(ndev);
3612 struct brcmf_pub *drvr = cfg->pub;
3613
3614 brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
3615 req->n_match_sets, req->n_ssids);
3616
3617 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3618 bphy_err(drvr, "Scanning suppressed: status=%lu\n",
3619 cfg->scan_status);
3620 return -EAGAIN;
3621 }
3622
3623 if (req->n_match_sets <= 0) {
3624 brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3625 req->n_match_sets);
3626 return -EINVAL;
3627 }
3628
3629 return brcmf_pno_start_sched_scan(ifp, req);
3630 }
3631
3632 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3633 struct net_device *ndev, u64 reqid)
3634 {
3635 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3636 struct brcmf_if *ifp = netdev_priv(ndev);
3637
3638 brcmf_dbg(SCAN, "enter\n");
3639 brcmf_pno_stop_sched_scan(ifp, reqid);
3640 if (cfg->int_escan_map)
3641 brcmf_notify_escan_complete(cfg, ifp, true, true);
3642 return 0;
3643 }
3644
3645 static __always_inline void brcmf_delay(u32 ms)
3646 {
3647 if (ms < 1000 / HZ) {
3648 cond_resched();
3649 mdelay(ms);
3650 } else {
3651 msleep(ms);
3652 }
3653 }
3654
3655 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3656 u8 *pattern, u32 patternsize, u8 *mask,
3657 u32 packet_offset)
3658 {
3659 struct brcmf_fil_wowl_pattern_le *filter;
3660 u32 masksize;
3661 u32 patternoffset;
3662 u8 *buf;
3663 u32 bufsize;
3664 s32 ret;
3665
3666 masksize = (patternsize + 7) / 8;
3667 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3668
3669 bufsize = sizeof(*filter) + patternsize + masksize;
3670 buf = kzalloc(bufsize, GFP_KERNEL);
3671 if (!buf)
3672 return -ENOMEM;
3673 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3674
3675 memcpy(filter->cmd, cmd, 4);
3676 filter->masksize = cpu_to_le32(masksize);
3677 filter->offset = cpu_to_le32(packet_offset);
3678 filter->patternoffset = cpu_to_le32(patternoffset);
3679 filter->patternsize = cpu_to_le32(patternsize);
3680 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3681
3682 if ((mask) && (masksize))
3683 memcpy(buf + sizeof(*filter), mask, masksize);
3684 if ((pattern) && (patternsize))
3685 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3686
3687 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3688
3689 kfree(buf);
3690 return ret;
3691 }
3692
3693 static s32
3694 brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
3695 void *data)
3696 {
3697 struct brcmf_pub *drvr = ifp->drvr;
3698 struct brcmf_cfg80211_info *cfg = drvr->config;
3699 struct brcmf_pno_scanresults_le *pfn_result;
3700 struct brcmf_pno_net_info_le *netinfo;
3701
3702 brcmf_dbg(SCAN, "Enter\n");
3703
3704 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3705 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3706 return 0;
3707 }
3708
3709 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3710
3711 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3712 brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
3713 return 0;
3714 }
3715
3716 if (le32_to_cpu(pfn_result->count) < 1) {
3717 bphy_err(drvr, "Invalid result count, expected 1 (%d)\n",
3718 le32_to_cpu(pfn_result->count));
3719 return -EINVAL;
3720 }
3721
3722 netinfo = brcmf_get_netinfo_array(pfn_result);
3723 if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3724 netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3725 memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
3726 cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
3727 cfg->wowl.nd->n_channels = 1;
3728 cfg->wowl.nd->channels[0] =
3729 ieee80211_channel_to_frequency(netinfo->channel,
3730 netinfo->channel <= CH_MAX_2G_CHANNEL ?
3731 NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
3732 cfg->wowl.nd_info->n_matches = 1;
3733 cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
3734
3735
3736 cfg->wowl.nd_data_completed = true;
3737 wake_up(&cfg->wowl.nd_data_wait);
3738
3739 return 0;
3740 }
3741
3742 #ifdef CONFIG_PM
3743
3744 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3745 {
3746 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3747 struct brcmf_pub *drvr = cfg->pub;
3748 struct brcmf_wowl_wakeind_le wake_ind_le;
3749 struct cfg80211_wowlan_wakeup wakeup_data;
3750 struct cfg80211_wowlan_wakeup *wakeup;
3751 u32 wakeind;
3752 s32 err;
3753 int timeout;
3754
3755 err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
3756 sizeof(wake_ind_le));
3757 if (err) {
3758 bphy_err(drvr, "Get wowl_wakeind failed, err = %d\n", err);
3759 return;
3760 }
3761
3762 wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
3763 if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
3764 BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
3765 BRCMF_WOWL_PFN_FOUND)) {
3766 wakeup = &wakeup_data;
3767 memset(&wakeup_data, 0, sizeof(wakeup_data));
3768 wakeup_data.pattern_idx = -1;
3769
3770 if (wakeind & BRCMF_WOWL_MAGIC) {
3771 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3772 wakeup_data.magic_pkt = true;
3773 }
3774 if (wakeind & BRCMF_WOWL_DIS) {
3775 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3776 wakeup_data.disconnect = true;
3777 }
3778 if (wakeind & BRCMF_WOWL_BCN) {
3779 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3780 wakeup_data.disconnect = true;
3781 }
3782 if (wakeind & BRCMF_WOWL_RETR) {
3783 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3784 wakeup_data.disconnect = true;
3785 }
3786 if (wakeind & BRCMF_WOWL_NET) {
3787 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3788
3789
3790
3791 wakeup_data.pattern_idx = 0;
3792 }
3793 if (wakeind & BRCMF_WOWL_PFN_FOUND) {
3794 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3795 timeout = wait_event_timeout(cfg->wowl.nd_data_wait,
3796 cfg->wowl.nd_data_completed,
3797 BRCMF_ND_INFO_TIMEOUT);
3798 if (!timeout)
3799 bphy_err(drvr, "No result for wowl net detect\n");
3800 else
3801 wakeup_data.net_detect = cfg->wowl.nd_info;
3802 }
3803 if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
3804 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
3805 wakeup_data.gtk_rekey_failure = true;
3806 }
3807 } else {
3808 wakeup = NULL;
3809 }
3810 cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
3811 }
3812
3813 #else
3814
3815 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3816 {
3817 }
3818
3819 #endif
3820
3821 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3822 {
3823 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3824 struct net_device *ndev = cfg_to_ndev(cfg);
3825 struct brcmf_if *ifp = netdev_priv(ndev);
3826
3827 brcmf_dbg(TRACE, "Enter\n");
3828
3829 if (cfg->wowl.active) {
3830 brcmf_report_wowl_wakeind(wiphy, ifp);
3831 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3832 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3833 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3834 brcmf_configure_arp_nd_offload(ifp, true);
3835 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3836 cfg->wowl.pre_pmmode);
3837 cfg->wowl.active = false;
3838 if (cfg->wowl.nd_enabled) {
3839 brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 0);
3840 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3841 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3842 brcmf_notify_sched_scan_results);
3843 cfg->wowl.nd_enabled = false;
3844 }
3845 }
3846 return 0;
3847 }
3848
3849 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3850 struct brcmf_if *ifp,
3851 struct cfg80211_wowlan *wowl)
3852 {
3853 u32 wowl_config;
3854 struct brcmf_wowl_wakeind_le wowl_wakeind;
3855 u32 i;
3856
3857 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3858
3859 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3860 brcmf_configure_arp_nd_offload(ifp, false);
3861 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
3862 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3863
3864 wowl_config = 0;
3865 if (wowl->disconnect)
3866 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3867 if (wowl->magic_pkt)
3868 wowl_config |= BRCMF_WOWL_MAGIC;
3869 if ((wowl->patterns) && (wowl->n_patterns)) {
3870 wowl_config |= BRCMF_WOWL_NET;
3871 for (i = 0; i < wowl->n_patterns; i++) {
3872 brcmf_config_wowl_pattern(ifp, "add",
3873 (u8 *)wowl->patterns[i].pattern,
3874 wowl->patterns[i].pattern_len,
3875 (u8 *)wowl->patterns[i].mask,
3876 wowl->patterns[i].pkt_offset);
3877 }
3878 }
3879 if (wowl->nd_config) {
3880 brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
3881 wowl->nd_config);
3882 wowl_config |= BRCMF_WOWL_PFN_FOUND;
3883
3884 cfg->wowl.nd_data_completed = false;
3885 cfg->wowl.nd_enabled = true;
3886
3887 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3888 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3889 brcmf_wowl_nd_results);
3890 }
3891 if (wowl->gtk_rekey_failure)
3892 wowl_config |= BRCMF_WOWL_GTK_FAILURE;
3893 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
3894 wowl_config |= BRCMF_WOWL_UNASSOC;
3895
3896 memcpy(&wowl_wakeind, "clear", 6);
3897 brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
3898 sizeof(wowl_wakeind));
3899 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3900 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3901 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3902 cfg->wowl.active = true;
3903 }
3904
3905 static int brcmf_keepalive_start(struct brcmf_if *ifp, unsigned int interval)
3906 {
3907 struct brcmf_mkeep_alive_pkt_le kalive = {0};
3908 int ret = 0;
3909
3910
3911 kalive.version = cpu_to_le16(1);
3912 kalive.period_msec = cpu_to_le32(interval * MSEC_PER_SEC);
3913 kalive.len_bytes = cpu_to_le16(0);
3914 kalive.keep_alive_id = 0;
3915
3916 ret = brcmf_fil_iovar_data_set(ifp, "mkeep_alive", &kalive, sizeof(kalive));
3917 if (ret)
3918 brcmf_err("keep-alive packet config failed, ret=%d\n", ret);
3919
3920 return ret;
3921 }
3922
3923 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3924 struct cfg80211_wowlan *wowl)
3925 {
3926 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3927 struct net_device *ndev = cfg_to_ndev(cfg);
3928 struct brcmf_if *ifp = netdev_priv(ndev);
3929 struct brcmf_cfg80211_vif *vif;
3930
3931 brcmf_dbg(TRACE, "Enter\n");
3932
3933
3934
3935
3936 if (!check_vif_up(ifp->vif))
3937 goto exit;
3938
3939
3940 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
3941 brcmf_cfg80211_sched_scan_stop(wiphy, ndev, 0);
3942
3943
3944 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3945 brcmf_abort_scanning(cfg);
3946
3947 if (wowl == NULL) {
3948 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3949 list_for_each_entry(vif, &cfg->vif_list, list) {
3950 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3951 continue;
3952
3953
3954
3955
3956 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED, true);
3957
3958
3959
3960
3961 brcmf_delay(500);
3962 }
3963
3964 brcmf_set_mpc(ifp, 1);
3965
3966 } else {
3967
3968 brcmf_configure_wowl(cfg, ifp, wowl);
3969
3970
3971 brcmf_keepalive_start(ifp, 30);
3972 }
3973
3974 exit:
3975 brcmf_dbg(TRACE, "Exit\n");
3976
3977 cfg->scan_status = 0;
3978 return 0;
3979 }
3980
3981 static __used s32
3982 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
3983 {
3984 struct brcmf_pmk_list_le *pmk_list;
3985 int i;
3986 u32 npmk;
3987 s32 err;
3988
3989 pmk_list = &cfg->pmk_list;
3990 npmk = le32_to_cpu(pmk_list->npmk);
3991
3992 brcmf_dbg(CONN, "No of elements %d\n", npmk);
3993 for (i = 0; i < npmk; i++)
3994 brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
3995
3996 err = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
3997 sizeof(*pmk_list));
3998
3999 return err;
4000 }
4001
4002 static s32
4003 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
4004 struct cfg80211_pmksa *pmksa)
4005 {
4006 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4007 struct brcmf_if *ifp = netdev_priv(ndev);
4008 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
4009 struct brcmf_pub *drvr = cfg->pub;
4010 s32 err;
4011 u32 npmk, i;
4012
4013 brcmf_dbg(TRACE, "Enter\n");
4014 if (!check_vif_up(ifp->vif))
4015 return -EIO;
4016
4017 npmk = le32_to_cpu(cfg->pmk_list.npmk);
4018 for (i = 0; i < npmk; i++)
4019 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
4020 break;
4021 if (i < BRCMF_MAXPMKID) {
4022 memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
4023 memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
4024 if (i == npmk) {
4025 npmk++;
4026 cfg->pmk_list.npmk = cpu_to_le32(npmk);
4027 }
4028 } else {
4029 bphy_err(drvr, "Too many PMKSA entries cached %d\n", npmk);
4030 return -EINVAL;
4031 }
4032
4033 brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
4034 brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmk[npmk].pmkid);
4035
4036 err = brcmf_update_pmklist(cfg, ifp);
4037
4038 brcmf_dbg(TRACE, "Exit\n");
4039 return err;
4040 }
4041
4042 static s32
4043 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
4044 struct cfg80211_pmksa *pmksa)
4045 {
4046 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4047 struct brcmf_if *ifp = netdev_priv(ndev);
4048 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
4049 struct brcmf_pub *drvr = cfg->pub;
4050 s32 err;
4051 u32 npmk, i;
4052
4053 brcmf_dbg(TRACE, "Enter\n");
4054 if (!check_vif_up(ifp->vif))
4055 return -EIO;
4056
4057 brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
4058
4059 npmk = le32_to_cpu(cfg->pmk_list.npmk);
4060 for (i = 0; i < npmk; i++)
4061 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
4062 break;
4063
4064 if ((npmk > 0) && (i < npmk)) {
4065 for (; i < (npmk - 1); i++) {
4066 memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
4067 memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
4068 WLAN_PMKID_LEN);
4069 }
4070 memset(&pmk[i], 0, sizeof(*pmk));
4071 cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
4072 } else {
4073 bphy_err(drvr, "Cache entry not found\n");
4074 return -EINVAL;
4075 }
4076
4077 err = brcmf_update_pmklist(cfg, ifp);
4078
4079 brcmf_dbg(TRACE, "Exit\n");
4080 return err;
4081
4082 }
4083
4084 static s32
4085 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
4086 {
4087 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4088 struct brcmf_if *ifp = netdev_priv(ndev);
4089 s32 err;
4090
4091 brcmf_dbg(TRACE, "Enter\n");
4092 if (!check_vif_up(ifp->vif))
4093 return -EIO;
4094
4095 memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
4096 err = brcmf_update_pmklist(cfg, ifp);
4097
4098 brcmf_dbg(TRACE, "Exit\n");
4099 return err;
4100
4101 }
4102
4103 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
4104 {
4105 struct brcmf_pub *drvr = ifp->drvr;
4106 s32 err;
4107 s32 wpa_val;
4108
4109
4110 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
4111 if (err < 0) {
4112 bphy_err(drvr, "auth error %d\n", err);
4113 return err;
4114 }
4115
4116 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
4117 if (err < 0) {
4118 bphy_err(drvr, "wsec error %d\n", err);
4119 return err;
4120 }
4121
4122 if (brcmf_is_ibssmode(ifp->vif))
4123 wpa_val = WPA_AUTH_NONE;
4124 else
4125 wpa_val = WPA_AUTH_DISABLED;
4126 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val);
4127 if (err < 0) {
4128 bphy_err(drvr, "wpa_auth error %d\n", err);
4129 return err;
4130 }
4131
4132 return 0;
4133 }
4134
4135 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
4136 {
4137 if (is_rsn_ie)
4138 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
4139
4140 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
4141 }
4142
4143 static s32
4144 brcmf_configure_wpaie(struct brcmf_if *ifp,
4145 const struct brcmf_vs_tlv *wpa_ie,
4146 bool is_rsn_ie)
4147 {
4148 struct brcmf_pub *drvr = ifp->drvr;
4149 u32 auth = 0;
4150 u16 count;
4151 s32 err = 0;
4152 s32 len;
4153 u32 i;
4154 u32 wsec;
4155 u32 pval = 0;
4156 u32 gval = 0;
4157 u32 wpa_auth = 0;
4158 u32 offset;
4159 u8 *data;
4160 u16 rsn_cap;
4161 u32 wme_bss_disable;
4162 u32 mfp;
4163
4164 brcmf_dbg(TRACE, "Enter\n");
4165 if (wpa_ie == NULL)
4166 goto exit;
4167
4168 len = wpa_ie->len + TLV_HDR_LEN;
4169 data = (u8 *)wpa_ie;
4170 offset = TLV_HDR_LEN;
4171 if (!is_rsn_ie)
4172 offset += VS_IE_FIXED_HDR_LEN;
4173 else
4174 offset += WPA_IE_VERSION_LEN;
4175
4176
4177 if (offset + WPA_IE_MIN_OUI_LEN > len) {
4178 err = -EINVAL;
4179 bphy_err(drvr, "no multicast cipher suite\n");
4180 goto exit;
4181 }
4182
4183 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4184 err = -EINVAL;
4185 bphy_err(drvr, "ivalid OUI\n");
4186 goto exit;
4187 }
4188 offset += TLV_OUI_LEN;
4189
4190
4191 switch (data[offset]) {
4192 case WPA_CIPHER_NONE:
4193 gval = 0;
4194 break;
4195 case WPA_CIPHER_WEP_40:
4196 case WPA_CIPHER_WEP_104:
4197 gval = WEP_ENABLED;
4198 break;
4199 case WPA_CIPHER_TKIP:
4200 gval = TKIP_ENABLED;
4201 break;
4202 case WPA_CIPHER_AES_CCM:
4203 gval = AES_ENABLED;
4204 break;
4205 default:
4206 err = -EINVAL;
4207 bphy_err(drvr, "Invalid multi cast cipher info\n");
4208 goto exit;
4209 }
4210
4211 offset++;
4212
4213 count = data[offset] + (data[offset + 1] << 8);
4214 offset += WPA_IE_SUITE_COUNT_LEN;
4215
4216 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4217 err = -EINVAL;
4218 bphy_err(drvr, "no unicast cipher suite\n");
4219 goto exit;
4220 }
4221 for (i = 0; i < count; i++) {
4222 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4223 err = -EINVAL;
4224 bphy_err(drvr, "ivalid OUI\n");
4225 goto exit;
4226 }
4227 offset += TLV_OUI_LEN;
4228 switch (data[offset]) {
4229 case WPA_CIPHER_NONE:
4230 break;
4231 case WPA_CIPHER_WEP_40:
4232 case WPA_CIPHER_WEP_104:
4233 pval |= WEP_ENABLED;
4234 break;
4235 case WPA_CIPHER_TKIP:
4236 pval |= TKIP_ENABLED;
4237 break;
4238 case WPA_CIPHER_AES_CCM:
4239 pval |= AES_ENABLED;
4240 break;
4241 default:
4242 bphy_err(drvr, "Invalid unicast security info\n");
4243 }
4244 offset++;
4245 }
4246
4247 count = data[offset] + (data[offset + 1] << 8);
4248 offset += WPA_IE_SUITE_COUNT_LEN;
4249
4250 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4251 err = -EINVAL;
4252 bphy_err(drvr, "no auth key mgmt suite\n");
4253 goto exit;
4254 }
4255 for (i = 0; i < count; i++) {
4256 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4257 err = -EINVAL;
4258 bphy_err(drvr, "ivalid OUI\n");
4259 goto exit;
4260 }
4261 offset += TLV_OUI_LEN;
4262 switch (data[offset]) {
4263 case RSN_AKM_NONE:
4264 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
4265 wpa_auth |= WPA_AUTH_NONE;
4266 break;
4267 case RSN_AKM_UNSPECIFIED:
4268 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
4269 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
4270 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
4271 break;
4272 case RSN_AKM_PSK:
4273 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
4274 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
4275 (wpa_auth |= WPA_AUTH_PSK);
4276 break;
4277 case RSN_AKM_SHA256_PSK:
4278 brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
4279 wpa_auth |= WPA2_AUTH_PSK_SHA256;
4280 break;
4281 case RSN_AKM_SHA256_1X:
4282 brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
4283 wpa_auth |= WPA2_AUTH_1X_SHA256;
4284 break;
4285 case RSN_AKM_SAE:
4286 brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
4287 wpa_auth |= WPA3_AUTH_SAE_PSK;
4288 break;
4289 default:
4290 bphy_err(drvr, "Invalid key mgmt info\n");
4291 }
4292 offset++;
4293 }
4294
4295 mfp = BRCMF_MFP_NONE;
4296 if (is_rsn_ie) {
4297 wme_bss_disable = 1;
4298 if ((offset + RSN_CAP_LEN) <= len) {
4299 rsn_cap = data[offset] + (data[offset + 1] << 8);
4300 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
4301 wme_bss_disable = 0;
4302 if (rsn_cap & RSN_CAP_MFPR_MASK) {
4303 brcmf_dbg(TRACE, "MFP Required\n");
4304 mfp = BRCMF_MFP_REQUIRED;
4305
4306
4307
4308
4309 if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
4310 WPA2_AUTH_1X_SHA256 |
4311 WPA3_AUTH_SAE_PSK))) {
4312 err = -EINVAL;
4313 goto exit;
4314 }
4315
4316
4317
4318
4319 if (wpa_auth & WPA2_AUTH_PSK_SHA256)
4320 wpa_auth |= WPA2_AUTH_PSK;
4321 else if (wpa_auth & WPA2_AUTH_1X_SHA256)
4322 wpa_auth |= WPA2_AUTH_UNSPECIFIED;
4323 } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
4324 brcmf_dbg(TRACE, "MFP Capable\n");
4325 mfp = BRCMF_MFP_CAPABLE;
4326 }
4327 }
4328 offset += RSN_CAP_LEN;
4329
4330 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
4331 wme_bss_disable);
4332 if (err < 0) {
4333 bphy_err(drvr, "wme_bss_disable error %d\n", err);
4334 goto exit;
4335 }
4336
4337
4338 offset += RSN_PMKID_COUNT_LEN;
4339
4340
4341 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
4342 ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
4343 err = brcmf_fil_bsscfg_data_set(ifp, "bip",
4344 &data[offset],
4345 WPA_IE_MIN_OUI_LEN);
4346 if (err < 0) {
4347 bphy_err(drvr, "bip error %d\n", err);
4348 goto exit;
4349 }
4350 }
4351 }
4352
4353 wsec = (pval | gval | SES_OW_ENABLED);
4354
4355
4356 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
4357 if (err < 0) {
4358 bphy_err(drvr, "auth error %d\n", err);
4359 goto exit;
4360 }
4361
4362 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
4363 if (err < 0) {
4364 bphy_err(drvr, "wsec error %d\n", err);
4365 goto exit;
4366 }
4367
4368
4369
4370 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
4371 err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
4372 if (err < 0) {
4373 bphy_err(drvr, "mfp error %d\n", err);
4374 goto exit;
4375 }
4376 }
4377
4378 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
4379 if (err < 0) {
4380 bphy_err(drvr, "wpa_auth error %d\n", err);
4381 goto exit;
4382 }
4383
4384 exit:
4385 return err;
4386 }
4387
4388 static s32
4389 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
4390 struct parsed_vndr_ies *vndr_ies)
4391 {
4392 struct brcmf_vs_tlv *vndrie;
4393 struct brcmf_tlv *ie;
4394 struct parsed_vndr_ie_info *parsed_info;
4395 s32 remaining_len;
4396
4397 remaining_len = (s32)vndr_ie_len;
4398 memset(vndr_ies, 0, sizeof(*vndr_ies));
4399
4400 ie = (struct brcmf_tlv *)vndr_ie_buf;
4401 while (ie) {
4402 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
4403 goto next;
4404 vndrie = (struct brcmf_vs_tlv *)ie;
4405
4406 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
4407 brcmf_err("invalid vndr ie. length is too small %d\n",
4408 vndrie->len);
4409 goto next;
4410 }
4411
4412 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
4413 ((vndrie->oui_type == WPA_OUI_TYPE) ||
4414 (vndrie->oui_type == WME_OUI_TYPE))) {
4415 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
4416 goto next;
4417 }
4418
4419 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
4420
4421
4422 parsed_info->ie_ptr = (char *)vndrie;
4423 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
4424 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
4425
4426 vndr_ies->count++;
4427
4428 brcmf_dbg(TRACE, "** OUI %3ph, type 0x%02x\n",
4429 parsed_info->vndrie.oui,
4430 parsed_info->vndrie.oui_type);
4431
4432 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
4433 break;
4434 next:
4435 remaining_len -= (ie->len + TLV_HDR_LEN);
4436 if (remaining_len <= TLV_HDR_LEN)
4437 ie = NULL;
4438 else
4439 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4440 TLV_HDR_LEN);
4441 }
4442 return 0;
4443 }
4444
4445 static u32
4446 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4447 {
4448 strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN);
4449
4450 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4451
4452 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4453
4454 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4455
4456 return ie_len + VNDR_IE_HDR_SIZE;
4457 }
4458
4459 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4460 const u8 *vndr_ie_buf, u32 vndr_ie_len)
4461 {
4462 struct brcmf_pub *drvr;
4463 struct brcmf_if *ifp;
4464 struct vif_saved_ie *saved_ie;
4465 s32 err = 0;
4466 u8 *iovar_ie_buf;
4467 u8 *curr_ie_buf;
4468 u8 *mgmt_ie_buf = NULL;
4469 int mgmt_ie_buf_len;
4470 u32 *mgmt_ie_len;
4471 u32 del_add_ie_buf_len = 0;
4472 u32 total_ie_buf_len = 0;
4473 u32 parsed_ie_buf_len = 0;
4474 struct parsed_vndr_ies old_vndr_ies;
4475 struct parsed_vndr_ies new_vndr_ies;
4476 struct parsed_vndr_ie_info *vndrie_info;
4477 s32 i;
4478 u8 *ptr;
4479 int remained_buf_len;
4480
4481 if (!vif)
4482 return -ENODEV;
4483 ifp = vif->ifp;
4484 drvr = ifp->drvr;
4485 saved_ie = &vif->saved_ie;
4486
4487 brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4488 pktflag);
4489 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4490 if (!iovar_ie_buf)
4491 return -ENOMEM;
4492 curr_ie_buf = iovar_ie_buf;
4493 switch (pktflag) {
4494 case BRCMF_VNDR_IE_PRBREQ_FLAG:
4495 mgmt_ie_buf = saved_ie->probe_req_ie;
4496 mgmt_ie_len = &saved_ie->probe_req_ie_len;
4497 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4498 break;
4499 case BRCMF_VNDR_IE_PRBRSP_FLAG:
4500 mgmt_ie_buf = saved_ie->probe_res_ie;
4501 mgmt_ie_len = &saved_ie->probe_res_ie_len;
4502 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4503 break;
4504 case BRCMF_VNDR_IE_BEACON_FLAG:
4505 mgmt_ie_buf = saved_ie->beacon_ie;
4506 mgmt_ie_len = &saved_ie->beacon_ie_len;
4507 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4508 break;
4509 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4510 mgmt_ie_buf = saved_ie->assoc_req_ie;
4511 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4512 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4513 break;
4514 case BRCMF_VNDR_IE_ASSOCRSP_FLAG:
4515 mgmt_ie_buf = saved_ie->assoc_res_ie;
4516 mgmt_ie_len = &saved_ie->assoc_res_ie_len;
4517 mgmt_ie_buf_len = sizeof(saved_ie->assoc_res_ie);
4518 break;
4519 default:
4520 err = -EPERM;
4521 bphy_err(drvr, "not suitable type\n");
4522 goto exit;
4523 }
4524
4525 if (vndr_ie_len > mgmt_ie_buf_len) {
4526 err = -ENOMEM;
4527 bphy_err(drvr, "extra IE size too big\n");
4528 goto exit;
4529 }
4530
4531
4532 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4533 ptr = curr_ie_buf;
4534 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4535 for (i = 0; i < new_vndr_ies.count; i++) {
4536 vndrie_info = &new_vndr_ies.ie_info[i];
4537 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4538 vndrie_info->ie_len);
4539 parsed_ie_buf_len += vndrie_info->ie_len;
4540 }
4541 }
4542
4543 if (mgmt_ie_buf && *mgmt_ie_len) {
4544 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4545 (memcmp(mgmt_ie_buf, curr_ie_buf,
4546 parsed_ie_buf_len) == 0)) {
4547 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4548 goto exit;
4549 }
4550
4551
4552 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4553
4554
4555 for (i = 0; i < old_vndr_ies.count; i++) {
4556 vndrie_info = &old_vndr_ies.ie_info[i];
4557
4558 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%3ph\n",
4559 vndrie_info->vndrie.id,
4560 vndrie_info->vndrie.len,
4561 vndrie_info->vndrie.oui);
4562
4563 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4564 vndrie_info->ie_ptr,
4565 vndrie_info->ie_len,
4566 "del");
4567 curr_ie_buf += del_add_ie_buf_len;
4568 total_ie_buf_len += del_add_ie_buf_len;
4569 }
4570 }
4571
4572 *mgmt_ie_len = 0;
4573
4574 if (mgmt_ie_buf && parsed_ie_buf_len) {
4575 ptr = mgmt_ie_buf;
4576
4577 remained_buf_len = mgmt_ie_buf_len;
4578
4579
4580 for (i = 0; i < new_vndr_ies.count; i++) {
4581 vndrie_info = &new_vndr_ies.ie_info[i];
4582
4583
4584 if (remained_buf_len < (vndrie_info->vndrie.len +
4585 VNDR_IE_VSIE_OFFSET)) {
4586 bphy_err(drvr, "no space in mgmt_ie_buf: len left %d",
4587 remained_buf_len);
4588 break;
4589 }
4590 remained_buf_len -= (vndrie_info->ie_len +
4591 VNDR_IE_VSIE_OFFSET);
4592
4593 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%3ph\n",
4594 vndrie_info->vndrie.id,
4595 vndrie_info->vndrie.len,
4596 vndrie_info->vndrie.oui);
4597
4598 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4599 vndrie_info->ie_ptr,
4600 vndrie_info->ie_len,
4601 "add");
4602
4603
4604 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4605 vndrie_info->ie_len);
4606 *mgmt_ie_len += vndrie_info->ie_len;
4607
4608 curr_ie_buf += del_add_ie_buf_len;
4609 total_ie_buf_len += del_add_ie_buf_len;
4610 }
4611 }
4612 if (total_ie_buf_len) {
4613 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4614 total_ie_buf_len);
4615 if (err)
4616 bphy_err(drvr, "vndr ie set error : %d\n", err);
4617 }
4618
4619 exit:
4620 kfree(iovar_ie_buf);
4621 return err;
4622 }
4623
4624 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4625 {
4626 static const s32 pktflags[] = {
4627 BRCMF_VNDR_IE_PRBREQ_FLAG,
4628 BRCMF_VNDR_IE_PRBRSP_FLAG,
4629 BRCMF_VNDR_IE_BEACON_FLAG
4630 };
4631 int i;
4632
4633 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4634 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4635
4636 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4637 return 0;
4638 }
4639
4640 static s32
4641 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4642 struct cfg80211_beacon_data *beacon)
4643 {
4644 struct brcmf_pub *drvr = vif->ifp->drvr;
4645 s32 err;
4646
4647
4648 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4649 beacon->tail, beacon->tail_len);
4650 if (err) {
4651 bphy_err(drvr, "Set Beacon IE Failed\n");
4652 return err;
4653 }
4654 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4655
4656
4657 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4658 beacon->proberesp_ies,
4659 beacon->proberesp_ies_len);
4660 if (err)
4661 bphy_err(drvr, "Set Probe Resp IE Failed\n");
4662 else
4663 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4664
4665
4666 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_ASSOCRSP_FLAG,
4667 beacon->assocresp_ies,
4668 beacon->assocresp_ies_len);
4669 if (err)
4670 brcmf_err("Set Assoc Resp IE Failed\n");
4671 else
4672 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc Resp\n");
4673
4674 return err;
4675 }
4676
4677 static s32
4678 brcmf_parse_configure_security(struct brcmf_if *ifp,
4679 struct cfg80211_ap_settings *settings,
4680 enum nl80211_iftype dev_role)
4681 {
4682 const struct brcmf_tlv *rsn_ie;
4683 const struct brcmf_vs_tlv *wpa_ie;
4684 s32 err = 0;
4685
4686
4687 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4688 settings->beacon.tail_len, WLAN_EID_RSN);
4689
4690
4691 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4692 settings->beacon.tail_len);
4693
4694 if (wpa_ie || rsn_ie) {
4695 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4696 if (wpa_ie) {
4697
4698 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4699 if (err < 0)
4700 return err;
4701 } else {
4702 struct brcmf_vs_tlv *tmp_ie;
4703
4704 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4705
4706
4707 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4708 if (err < 0)
4709 return err;
4710 }
4711 } else {
4712 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4713 brcmf_configure_opensecurity(ifp);
4714 }
4715
4716 return err;
4717 }
4718
4719 static s32
4720 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4721 struct cfg80211_ap_settings *settings)
4722 {
4723 s32 ie_offset;
4724 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4725 struct brcmf_if *ifp = netdev_priv(ndev);
4726 struct brcmf_pub *drvr = cfg->pub;
4727 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4728 struct cfg80211_crypto_settings *crypto = &settings->crypto;
4729 const struct brcmf_tlv *ssid_ie;
4730 const struct brcmf_tlv *country_ie;
4731 struct brcmf_ssid_le ssid_le;
4732 s32 err = -EPERM;
4733 struct brcmf_join_params join_params;
4734 enum nl80211_iftype dev_role;
4735 struct brcmf_fil_bss_enable_le bss_enable;
4736 u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
4737 bool mbss;
4738 int is_11d;
4739 bool supports_11d;
4740
4741 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4742 settings->chandef.chan->hw_value,
4743 settings->chandef.center_freq1, settings->chandef.width,
4744 settings->beacon_interval, settings->dtim_period);
4745 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4746 settings->ssid, settings->ssid_len, settings->auth_type,
4747 settings->inactivity_timeout);
4748 dev_role = ifp->vif->wdev.iftype;
4749 mbss = ifp->vif->mbss;
4750
4751
4752 if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
4753 &ifp->vif->is_11d)) {
4754 is_11d = supports_11d = false;
4755 } else {
4756 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4757 settings->beacon.tail_len,
4758 WLAN_EID_COUNTRY);
4759 is_11d = country_ie ? 1 : 0;
4760 supports_11d = true;
4761 }
4762
4763 memset(&ssid_le, 0, sizeof(ssid_le));
4764 if (settings->ssid == NULL || settings->ssid_len == 0) {
4765 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4766 ssid_ie = brcmf_parse_tlvs(
4767 (u8 *)&settings->beacon.head[ie_offset],
4768 settings->beacon.head_len - ie_offset,
4769 WLAN_EID_SSID);
4770 if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
4771 return -EINVAL;
4772
4773 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4774 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4775 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4776 } else {
4777 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4778 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4779 }
4780
4781 if (!mbss) {
4782 brcmf_set_mpc(ifp, 0);
4783 brcmf_configure_arp_nd_offload(ifp, false);
4784 }
4785
4786
4787 if (!mbss) {
4788 if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
4789 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4790 is_11d);
4791 if (err < 0) {
4792 bphy_err(drvr, "Regulatory Set Error, %d\n",
4793 err);
4794 goto exit;
4795 }
4796 }
4797 if (settings->beacon_interval) {
4798 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4799 settings->beacon_interval);
4800 if (err < 0) {
4801 bphy_err(drvr, "Beacon Interval Set Error, %d\n",
4802 err);
4803 goto exit;
4804 }
4805 }
4806 if (settings->dtim_period) {
4807 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4808 settings->dtim_period);
4809 if (err < 0) {
4810 bphy_err(drvr, "DTIM Interval Set Error, %d\n",
4811 err);
4812 goto exit;
4813 }
4814 }
4815
4816 if ((dev_role == NL80211_IFTYPE_AP) &&
4817 ((ifp->ifidx == 0) ||
4818 (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB) &&
4819 !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)))) {
4820 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4821 if (err < 0) {
4822 bphy_err(drvr, "BRCMF_C_DOWN error %d\n",
4823 err);
4824 goto exit;
4825 }
4826 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4827 }
4828
4829 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4830 if (err < 0) {
4831 bphy_err(drvr, "SET INFRA error %d\n", err);
4832 goto exit;
4833 }
4834 } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
4835
4836 err = -EINVAL;
4837 goto exit;
4838 }
4839
4840
4841 if (dev_role == NL80211_IFTYPE_AP) {
4842 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4843 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4844
4845 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4846 if (err < 0) {
4847 bphy_err(drvr, "setting AP mode failed %d\n",
4848 err);
4849 goto exit;
4850 }
4851 if (!mbss) {
4852
4853
4854
4855 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4856 if (err < 0) {
4857 bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
4858 chanspec, err);
4859 goto exit;
4860 }
4861 }
4862 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4863 if (err < 0) {
4864 bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err);
4865 goto exit;
4866 }
4867
4868 if (crypto->psk) {
4869 brcmf_dbg(INFO, "using PSK offload\n");
4870 profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_PSK);
4871 err = brcmf_set_pmk(ifp, crypto->psk,
4872 BRCMF_WSEC_MAX_PSK_LEN);
4873 if (err < 0)
4874 goto exit;
4875 }
4876 if (crypto->sae_pwd) {
4877 brcmf_dbg(INFO, "using SAE offload\n");
4878 profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_SAE);
4879 err = brcmf_set_sae_password(ifp, crypto->sae_pwd,
4880 crypto->sae_pwd_len);
4881 if (err < 0)
4882 goto exit;
4883 }
4884 if (profile->use_fwauth == 0)
4885 profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
4886
4887 err = brcmf_parse_configure_security(ifp, settings,
4888 NL80211_IFTYPE_AP);
4889 if (err < 0) {
4890 bphy_err(drvr, "brcmf_parse_configure_security error\n");
4891 goto exit;
4892 }
4893
4894
4895
4896
4897 brcmf_cfg80211_reconfigure_wep(ifp);
4898
4899 memset(&join_params, 0, sizeof(join_params));
4900
4901 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4902
4903 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4904 &join_params, sizeof(join_params));
4905 if (err < 0) {
4906 bphy_err(drvr, "SET SSID error (%d)\n", err);
4907 goto exit;
4908 }
4909
4910 err = brcmf_fil_iovar_int_set(ifp, "closednet",
4911 settings->hidden_ssid);
4912 if (err) {
4913 bphy_err(drvr, "%s closednet error (%d)\n",
4914 settings->hidden_ssid ?
4915 "enabled" : "disabled",
4916 err);
4917 goto exit;
4918 }
4919
4920 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4921 } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
4922 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4923 if (err < 0) {
4924 bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
4925 chanspec, err);
4926 goto exit;
4927 }
4928
4929 err = brcmf_parse_configure_security(ifp, settings,
4930 NL80211_IFTYPE_P2P_GO);
4931 if (err < 0) {
4932 brcmf_err("brcmf_parse_configure_security error\n");
4933 goto exit;
4934 }
4935
4936 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4937 sizeof(ssid_le));
4938 if (err < 0) {
4939 bphy_err(drvr, "setting ssid failed %d\n", err);
4940 goto exit;
4941 }
4942 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4943 bss_enable.enable = cpu_to_le32(1);
4944 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4945 sizeof(bss_enable));
4946 if (err < 0) {
4947 bphy_err(drvr, "bss_enable config failed %d\n", err);
4948 goto exit;
4949 }
4950
4951 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4952 } else {
4953 WARN_ON(1);
4954 }
4955
4956 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4957 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4958 brcmf_net_setcarrier(ifp, true);
4959
4960 exit:
4961 if ((err) && (!mbss)) {
4962 brcmf_set_mpc(ifp, 1);
4963 brcmf_configure_arp_nd_offload(ifp, true);
4964 }
4965 return err;
4966 }
4967
4968 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
4969 unsigned int link_id)
4970 {
4971 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4972 struct brcmf_if *ifp = netdev_priv(ndev);
4973 struct brcmf_pub *drvr = cfg->pub;
4974 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4975 s32 err;
4976 struct brcmf_fil_bss_enable_le bss_enable;
4977 struct brcmf_join_params join_params;
4978
4979 brcmf_dbg(TRACE, "Enter\n");
4980
4981 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4982
4983
4984 msleep(400);
4985
4986 if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) {
4987 if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_PSK))
4988 brcmf_set_pmk(ifp, NULL, 0);
4989 if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_SAE))
4990 brcmf_set_sae_password(ifp, NULL, 0);
4991 profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
4992 }
4993
4994 if (ifp->vif->mbss) {
4995 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4996 return err;
4997 }
4998
4999
5000 if (ifp->bsscfgidx == 0)
5001 brcmf_fil_iovar_int_set(ifp, "closednet", 0);
5002
5003 memset(&join_params, 0, sizeof(join_params));
5004 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
5005 &join_params, sizeof(join_params));
5006 if (err < 0)
5007 bphy_err(drvr, "SET SSID error (%d)\n", err);
5008 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
5009 if (err < 0)
5010 bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
5011 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
5012 if (err < 0)
5013 bphy_err(drvr, "setting AP mode failed %d\n", err);
5014 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
5015 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
5016 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
5017 ifp->vif->is_11d);
5018
5019 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
5020 if (err < 0)
5021 bphy_err(drvr, "BRCMF_C_UP error %d\n", err);
5022
5023 brcmf_vif_clear_mgmt_ies(ifp->vif);
5024 } else {
5025 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
5026 bss_enable.enable = cpu_to_le32(0);
5027 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
5028 sizeof(bss_enable));
5029 if (err < 0)
5030 bphy_err(drvr, "bss_enable config failed %d\n", err);
5031 }
5032 brcmf_set_mpc(ifp, 1);
5033 brcmf_configure_arp_nd_offload(ifp, true);
5034 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
5035 brcmf_net_setcarrier(ifp, false);
5036
5037 return err;
5038 }
5039
5040 static s32
5041 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
5042 struct cfg80211_beacon_data *info)
5043 {
5044 struct brcmf_if *ifp = netdev_priv(ndev);
5045 s32 err;
5046
5047 brcmf_dbg(TRACE, "Enter\n");
5048
5049 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
5050
5051 return err;
5052 }
5053
5054 static int
5055 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
5056 struct station_del_parameters *params)
5057 {
5058 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5059 struct brcmf_pub *drvr = cfg->pub;
5060 struct brcmf_scb_val_le scbval;
5061 struct brcmf_if *ifp = netdev_priv(ndev);
5062 s32 err;
5063
5064 if (!params->mac)
5065 return -EFAULT;
5066
5067 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
5068
5069 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
5070 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
5071 if (!check_vif_up(ifp->vif))
5072 return -EIO;
5073
5074 memcpy(&scbval.ea, params->mac, ETH_ALEN);
5075 scbval.val = cpu_to_le32(params->reason_code);
5076 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
5077 &scbval, sizeof(scbval));
5078 if (err)
5079 bphy_err(drvr, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n",
5080 err);
5081
5082 brcmf_dbg(TRACE, "Exit\n");
5083 return err;
5084 }
5085
5086 static int
5087 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
5088 const u8 *mac, struct station_parameters *params)
5089 {
5090 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5091 struct brcmf_pub *drvr = cfg->pub;
5092 struct brcmf_if *ifp = netdev_priv(ndev);
5093 s32 err;
5094
5095 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
5096 params->sta_flags_mask, params->sta_flags_set);
5097
5098
5099 if (is_zero_ether_addr(mac))
5100 return 0;
5101
5102 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
5103 return 0;
5104
5105 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
5106 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
5107 (void *)mac, ETH_ALEN);
5108 else
5109 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
5110 (void *)mac, ETH_ALEN);
5111 if (err < 0)
5112 bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err);
5113
5114 return err;
5115 }
5116
5117 static void
5118 brcmf_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
5119 struct wireless_dev *wdev,
5120 struct mgmt_frame_regs *upd)
5121 {
5122 struct brcmf_cfg80211_vif *vif;
5123
5124 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5125
5126 vif->mgmt_rx_reg = upd->interface_stypes;
5127 }
5128
5129
5130 static int
5131 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
5132 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
5133 {
5134 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5135 struct ieee80211_channel *chan = params->chan;
5136 struct brcmf_pub *drvr = cfg->pub;
5137 const u8 *buf = params->buf;
5138 size_t len = params->len;
5139 const struct ieee80211_mgmt *mgmt;
5140 struct brcmf_cfg80211_vif *vif;
5141 s32 err = 0;
5142 s32 ie_offset;
5143 s32 ie_len;
5144 struct brcmf_fil_action_frame_le *action_frame;
5145 struct brcmf_fil_af_params_le *af_params;
5146 bool ack;
5147 s32 chan_nr;
5148 u32 freq;
5149
5150 brcmf_dbg(TRACE, "Enter\n");
5151
5152 *cookie = 0;
5153
5154 mgmt = (const struct ieee80211_mgmt *)buf;
5155
5156 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
5157 bphy_err(drvr, "Driver only allows MGMT packet type\n");
5158 return -EPERM;
5159 }
5160
5161 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5162
5163 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175 ie_offset = DOT11_MGMT_HDR_LEN +
5176 DOT11_BCN_PRB_FIXED_LEN;
5177 ie_len = len - ie_offset;
5178 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
5179 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
5180 err = brcmf_vif_set_mgmt_ie(vif,
5181 BRCMF_VNDR_IE_PRBRSP_FLAG,
5182 &buf[ie_offset],
5183 ie_len);
5184 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
5185 GFP_KERNEL);
5186 } else if (ieee80211_is_action(mgmt->frame_control)) {
5187 if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
5188 bphy_err(drvr, "invalid action frame length\n");
5189 err = -EINVAL;
5190 goto exit;
5191 }
5192 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
5193 if (af_params == NULL) {
5194 bphy_err(drvr, "unable to allocate frame\n");
5195 err = -ENOMEM;
5196 goto exit;
5197 }
5198 action_frame = &af_params->action_frame;
5199
5200 action_frame->packet_id = cpu_to_le32(*cookie);
5201
5202 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
5203 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
5204
5205 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
5206
5207
5208
5209 if (chan)
5210 freq = chan->center_freq;
5211 else
5212 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
5213 &freq);
5214 chan_nr = ieee80211_frequency_to_channel(freq);
5215 af_params->channel = cpu_to_le32(chan_nr);
5216 af_params->dwell_time = cpu_to_le32(params->wait);
5217 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
5218 le16_to_cpu(action_frame->len));
5219
5220 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
5221 *cookie, le16_to_cpu(action_frame->len), freq);
5222
5223 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
5224 af_params);
5225
5226 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
5227 GFP_KERNEL);
5228 kfree(af_params);
5229 } else {
5230 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
5231 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
5232 }
5233
5234 exit:
5235 return err;
5236 }
5237
5238 static int brcmf_cfg80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
5239 struct net_device *ndev,
5240 s32 rssi_low, s32 rssi_high)
5241 {
5242 struct brcmf_cfg80211_vif *vif;
5243 struct brcmf_if *ifp;
5244 int err = 0;
5245
5246 brcmf_dbg(TRACE, "low=%d high=%d", rssi_low, rssi_high);
5247
5248 ifp = netdev_priv(ndev);
5249 vif = ifp->vif;
5250
5251 if (rssi_low != vif->cqm_rssi_low || rssi_high != vif->cqm_rssi_high) {
5252
5253
5254
5255
5256
5257
5258 struct brcmf_rssi_event_le config = {
5259 .rate_limit_msec = cpu_to_le32(0),
5260 .rssi_level_num = 3,
5261 .rssi_levels = {
5262 clamp_val(rssi_low, S8_MIN, S8_MAX - 2),
5263 clamp_val(rssi_high, S8_MIN + 1, S8_MAX - 1),
5264 S8_MAX,
5265 },
5266 };
5267
5268 err = brcmf_fil_iovar_data_set(ifp, "rssi_event", &config,
5269 sizeof(config));
5270 if (err) {
5271 err = -EINVAL;
5272 } else {
5273 vif->cqm_rssi_low = rssi_low;
5274 vif->cqm_rssi_high = rssi_high;
5275 }
5276 }
5277
5278 return err;
5279 }
5280
5281 static int
5282 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
5283 struct wireless_dev *wdev,
5284 u64 cookie)
5285 {
5286 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5287 struct brcmf_pub *drvr = cfg->pub;
5288 struct brcmf_cfg80211_vif *vif;
5289 int err = 0;
5290
5291 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
5292
5293 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
5294 if (vif == NULL) {
5295 bphy_err(drvr, "No p2p device available for probe response\n");
5296 err = -ENODEV;
5297 goto exit;
5298 }
5299 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
5300 exit:
5301 return err;
5302 }
5303
5304 static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
5305 struct wireless_dev *wdev,
5306 unsigned int link_id,
5307 struct cfg80211_chan_def *chandef)
5308 {
5309 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5310 struct net_device *ndev = wdev->netdev;
5311 struct brcmf_pub *drvr = cfg->pub;
5312 struct brcmu_chan ch;
5313 enum nl80211_band band = 0;
5314 enum nl80211_chan_width width = 0;
5315 u32 chanspec;
5316 int freq, err;
5317
5318 if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP)
5319 return -ENODEV;
5320
5321 err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec);
5322 if (err) {
5323 bphy_err(drvr, "chanspec failed (%d)\n", err);
5324 return err;
5325 }
5326
5327 ch.chspec = chanspec;
5328 cfg->d11inf.decchspec(&ch);
5329
5330 switch (ch.band) {
5331 case BRCMU_CHAN_BAND_2G:
5332 band = NL80211_BAND_2GHZ;
5333 break;
5334 case BRCMU_CHAN_BAND_5G:
5335 band = NL80211_BAND_5GHZ;
5336 break;
5337 }
5338
5339 switch (ch.bw) {
5340 case BRCMU_CHAN_BW_80:
5341 width = NL80211_CHAN_WIDTH_80;
5342 break;
5343 case BRCMU_CHAN_BW_40:
5344 width = NL80211_CHAN_WIDTH_40;
5345 break;
5346 case BRCMU_CHAN_BW_20:
5347 width = NL80211_CHAN_WIDTH_20;
5348 break;
5349 case BRCMU_CHAN_BW_80P80:
5350 width = NL80211_CHAN_WIDTH_80P80;
5351 break;
5352 case BRCMU_CHAN_BW_160:
5353 width = NL80211_CHAN_WIDTH_160;
5354 break;
5355 }
5356
5357 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
5358 chandef->chan = ieee80211_get_channel(wiphy, freq);
5359 chandef->width = width;
5360 chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
5361 chandef->center_freq2 = 0;
5362
5363 return 0;
5364 }
5365
5366 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
5367 struct wireless_dev *wdev,
5368 enum nl80211_crit_proto_id proto,
5369 u16 duration)
5370 {
5371 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5372 struct brcmf_cfg80211_vif *vif;
5373
5374 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5375
5376
5377 if (proto != NL80211_CRIT_PROTO_DHCP)
5378 return -EINVAL;
5379
5380
5381 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5382 brcmf_abort_scanning(cfg);
5383
5384 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
5385 }
5386
5387 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
5388 struct wireless_dev *wdev)
5389 {
5390 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5391 struct brcmf_cfg80211_vif *vif;
5392
5393 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5394
5395 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
5396 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5397 }
5398
5399 static s32
5400 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
5401 const struct brcmf_event_msg *e, void *data)
5402 {
5403 switch (e->reason) {
5404 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
5405 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
5406 break;
5407 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
5408 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
5409 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5410 break;
5411 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
5412 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
5413 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5414 break;
5415 }
5416
5417 return 0;
5418 }
5419
5420 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
5421 {
5422 int ret;
5423
5424 switch (oper) {
5425 case NL80211_TDLS_DISCOVERY_REQ:
5426 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
5427 break;
5428 case NL80211_TDLS_SETUP:
5429 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
5430 break;
5431 case NL80211_TDLS_TEARDOWN:
5432 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
5433 break;
5434 default:
5435 brcmf_err("unsupported operation: %d\n", oper);
5436 ret = -EOPNOTSUPP;
5437 }
5438 return ret;
5439 }
5440
5441 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
5442 struct net_device *ndev, const u8 *peer,
5443 enum nl80211_tdls_operation oper)
5444 {
5445 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5446 struct brcmf_pub *drvr = cfg->pub;
5447 struct brcmf_if *ifp;
5448 struct brcmf_tdls_iovar_le info;
5449 int ret = 0;
5450
5451 ret = brcmf_convert_nl80211_tdls_oper(oper);
5452 if (ret < 0)
5453 return ret;
5454
5455 ifp = netdev_priv(ndev);
5456 memset(&info, 0, sizeof(info));
5457 info.mode = (u8)ret;
5458 if (peer)
5459 memcpy(info.ea, peer, ETH_ALEN);
5460
5461 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
5462 &info, sizeof(info));
5463 if (ret < 0)
5464 bphy_err(drvr, "tdls_endpoint iovar failed: ret=%d\n", ret);
5465
5466 return ret;
5467 }
5468
5469 static int
5470 brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
5471 struct net_device *ndev,
5472 struct cfg80211_connect_params *sme,
5473 u32 changed)
5474 {
5475 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5476 struct brcmf_pub *drvr = cfg->pub;
5477 struct brcmf_if *ifp;
5478 int err;
5479
5480 if (!(changed & UPDATE_ASSOC_IES))
5481 return 0;
5482
5483 ifp = netdev_priv(ndev);
5484 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
5485 sme->ie, sme->ie_len);
5486 if (err)
5487 bphy_err(drvr, "Set Assoc REQ IE Failed\n");
5488 else
5489 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
5490
5491 return err;
5492 }
5493
5494 #ifdef CONFIG_PM
5495 static int
5496 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
5497 struct cfg80211_gtk_rekey_data *gtk)
5498 {
5499 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5500 struct brcmf_pub *drvr = cfg->pub;
5501 struct brcmf_if *ifp = netdev_priv(ndev);
5502 struct brcmf_gtk_keyinfo_le gtk_le;
5503 int ret;
5504
5505 brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
5506
5507 memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
5508 memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
5509 memcpy(gtk_le.replay_counter, gtk->replay_ctr,
5510 sizeof(gtk_le.replay_counter));
5511
5512 ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le,
5513 sizeof(gtk_le));
5514 if (ret < 0)
5515 bphy_err(drvr, "gtk_key_info iovar failed: ret=%d\n", ret);
5516
5517 return ret;
5518 }
5519 #endif
5520
5521 static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
5522 const struct cfg80211_pmk_conf *conf)
5523 {
5524 struct brcmf_if *ifp;
5525
5526 brcmf_dbg(TRACE, "enter\n");
5527
5528
5529 ifp = netdev_priv(dev);
5530 if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5531 return -EINVAL;
5532
5533 if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN)
5534 return -ERANGE;
5535
5536 return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len);
5537 }
5538
5539 static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
5540 const u8 *aa)
5541 {
5542 struct brcmf_if *ifp;
5543
5544 brcmf_dbg(TRACE, "enter\n");
5545 ifp = netdev_priv(dev);
5546 if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5547 return -EINVAL;
5548
5549 return brcmf_set_pmk(ifp, NULL, 0);
5550 }
5551
5552 static struct cfg80211_ops brcmf_cfg80211_ops = {
5553 .add_virtual_intf = brcmf_cfg80211_add_iface,
5554 .del_virtual_intf = brcmf_cfg80211_del_iface,
5555 .change_virtual_intf = brcmf_cfg80211_change_iface,
5556 .scan = brcmf_cfg80211_scan,
5557 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
5558 .join_ibss = brcmf_cfg80211_join_ibss,
5559 .leave_ibss = brcmf_cfg80211_leave_ibss,
5560 .get_station = brcmf_cfg80211_get_station,
5561 .dump_station = brcmf_cfg80211_dump_station,
5562 .set_tx_power = brcmf_cfg80211_set_tx_power,
5563 .get_tx_power = brcmf_cfg80211_get_tx_power,
5564 .add_key = brcmf_cfg80211_add_key,
5565 .del_key = brcmf_cfg80211_del_key,
5566 .get_key = brcmf_cfg80211_get_key,
5567 .set_default_key = brcmf_cfg80211_config_default_key,
5568 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
5569 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
5570 .connect = brcmf_cfg80211_connect,
5571 .disconnect = brcmf_cfg80211_disconnect,
5572 .suspend = brcmf_cfg80211_suspend,
5573 .resume = brcmf_cfg80211_resume,
5574 .set_pmksa = brcmf_cfg80211_set_pmksa,
5575 .del_pmksa = brcmf_cfg80211_del_pmksa,
5576 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
5577 .start_ap = brcmf_cfg80211_start_ap,
5578 .stop_ap = brcmf_cfg80211_stop_ap,
5579 .change_beacon = brcmf_cfg80211_change_beacon,
5580 .del_station = brcmf_cfg80211_del_station,
5581 .change_station = brcmf_cfg80211_change_station,
5582 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
5583 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
5584 .update_mgmt_frame_registrations =
5585 brcmf_cfg80211_update_mgmt_frame_registrations,
5586 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
5587 .set_cqm_rssi_range_config = brcmf_cfg80211_set_cqm_rssi_range_config,
5588 .remain_on_channel = brcmf_p2p_remain_on_channel,
5589 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
5590 .get_channel = brcmf_cfg80211_get_channel,
5591 .start_p2p_device = brcmf_p2p_start_device,
5592 .stop_p2p_device = brcmf_p2p_stop_device,
5593 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
5594 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
5595 .tdls_oper = brcmf_cfg80211_tdls_oper,
5596 .update_connect_params = brcmf_cfg80211_update_conn_params,
5597 .set_pmk = brcmf_cfg80211_set_pmk,
5598 .del_pmk = brcmf_cfg80211_del_pmk,
5599 };
5600
5601 struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
5602 {
5603 struct cfg80211_ops *ops;
5604
5605 ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
5606 GFP_KERNEL);
5607
5608 if (ops && settings->roamoff)
5609 ops->update_connect_params = NULL;
5610
5611 return ops;
5612 }
5613
5614 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
5615 enum nl80211_iftype type)
5616 {
5617 struct brcmf_cfg80211_vif *vif_walk;
5618 struct brcmf_cfg80211_vif *vif;
5619 bool mbss;
5620 struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
5621
5622 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
5623 sizeof(*vif));
5624 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
5625 if (!vif)
5626 return ERR_PTR(-ENOMEM);
5627
5628 vif->wdev.wiphy = cfg->wiphy;
5629 vif->wdev.iftype = type;
5630
5631 brcmf_init_prof(&vif->profile);
5632
5633 if (type == NL80211_IFTYPE_AP &&
5634 brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
5635 mbss = false;
5636 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
5637 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
5638 mbss = true;
5639 break;
5640 }
5641 }
5642 vif->mbss = mbss;
5643 }
5644
5645 list_add_tail(&vif->list, &cfg->vif_list);
5646 return vif;
5647 }
5648
5649 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
5650 {
5651 list_del(&vif->list);
5652 kfree(vif);
5653 }
5654
5655 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
5656 {
5657 struct brcmf_cfg80211_vif *vif;
5658 struct brcmf_if *ifp;
5659
5660 ifp = netdev_priv(ndev);
5661 vif = ifp->vif;
5662
5663 if (vif)
5664 brcmf_free_vif(vif);
5665 }
5666
5667 static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
5668 const struct brcmf_event_msg *e)
5669 {
5670 u32 event = e->event_code;
5671 u32 status = e->status;
5672
5673 if ((vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_PSK ||
5674 vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_SAE) &&
5675 event == BRCMF_E_PSK_SUP &&
5676 status == BRCMF_E_STATUS_FWSUP_COMPLETED)
5677 set_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
5678 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
5679 brcmf_dbg(CONN, "Processing set ssid\n");
5680 memcpy(vif->profile.bssid, e->addr, ETH_ALEN);
5681 if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK &&
5682 vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_SAE)
5683 return true;
5684
5685 set_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
5686 }
5687
5688 if (test_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state) &&
5689 test_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state)) {
5690 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
5691 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
5692 return true;
5693 }
5694 return false;
5695 }
5696
5697 static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif,
5698 const struct brcmf_event_msg *e)
5699 {
5700 u32 event = e->event_code;
5701 u16 flags = e->flags;
5702
5703 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
5704 (event == BRCMF_E_DISASSOC_IND) ||
5705 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
5706 brcmf_dbg(CONN, "Processing link down\n");
5707 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
5708 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
5709 return true;
5710 }
5711 return false;
5712 }
5713
5714 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
5715 const struct brcmf_event_msg *e)
5716 {
5717 u32 event = e->event_code;
5718 u32 status = e->status;
5719
5720 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
5721 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
5722 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
5723 return true;
5724 }
5725
5726 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
5727 brcmf_dbg(CONN, "Processing connecting & no network found\n");
5728 return true;
5729 }
5730
5731 if (event == BRCMF_E_PSK_SUP &&
5732 status != BRCMF_E_STATUS_FWSUP_COMPLETED) {
5733 brcmf_dbg(CONN, "Processing failed supplicant state: %u\n",
5734 status);
5735 return true;
5736 }
5737
5738 return false;
5739 }
5740
5741 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
5742 {
5743 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5744
5745 kfree(conn_info->req_ie);
5746 conn_info->req_ie = NULL;
5747 conn_info->req_ie_len = 0;
5748 kfree(conn_info->resp_ie);
5749 conn_info->resp_ie = NULL;
5750 conn_info->resp_ie_len = 0;
5751 }
5752
5753 u8 brcmf_map_prio_to_prec(void *config, u8 prio)
5754 {
5755 struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
5756
5757 if (!cfg)
5758 return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
5759 (prio ^ 2) : prio;
5760
5761
5762
5763
5764 if (prio > PRIO_8021D_EE &&
5765 cfg->ac_priority[prio] == cfg->ac_priority[PRIO_8021D_BE])
5766 return cfg->ac_priority[prio] * 2;
5767
5768
5769 if (prio == PRIO_8021D_BE || prio == PRIO_8021D_BK ||
5770 prio == PRIO_8021D_CL || prio == PRIO_8021D_VO)
5771 return cfg->ac_priority[prio] * 2;
5772 else
5773 return cfg->ac_priority[prio] * 2 + 1;
5774 }
5775
5776 u8 brcmf_map_prio_to_aci(void *config, u8 prio)
5777 {
5778
5779
5780
5781
5782 struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
5783
5784 if (cfg)
5785 return cfg->ac_priority[prio];
5786
5787 return prio;
5788 }
5789
5790 static void brcmf_init_wmm_prio(u8 *priority)
5791 {
5792
5793
5794
5795
5796
5797
5798
5799 priority[0] = BRCMF_FWS_FIFO_AC_BE;
5800 priority[3] = BRCMF_FWS_FIFO_AC_BE;
5801 priority[1] = BRCMF_FWS_FIFO_AC_BK;
5802 priority[2] = BRCMF_FWS_FIFO_AC_BK;
5803 priority[4] = BRCMF_FWS_FIFO_AC_VI;
5804 priority[5] = BRCMF_FWS_FIFO_AC_VI;
5805 priority[6] = BRCMF_FWS_FIFO_AC_VO;
5806 priority[7] = BRCMF_FWS_FIFO_AC_VO;
5807 }
5808
5809 static void brcmf_wifi_prioritize_acparams(const
5810 struct brcmf_cfg80211_edcf_acparam *acp, u8 *priority)
5811 {
5812 u8 aci;
5813 u8 aifsn;
5814 u8 ecwmin;
5815 u8 ecwmax;
5816 u8 acm;
5817 u8 ranking_basis[EDCF_AC_COUNT];
5818 u8 aci_prio[EDCF_AC_COUNT];
5819 u8 index;
5820
5821 for (aci = 0; aci < EDCF_AC_COUNT; aci++, acp++) {
5822 aifsn = acp->ACI & EDCF_AIFSN_MASK;
5823 acm = (acp->ACI & EDCF_ACM_MASK) ? 1 : 0;
5824 ecwmin = acp->ECW & EDCF_ECWMIN_MASK;
5825 ecwmax = (acp->ECW & EDCF_ECWMAX_MASK) >> EDCF_ECWMAX_SHIFT;
5826 brcmf_dbg(CONN, "ACI %d aifsn %d acm %d ecwmin %d ecwmax %d\n",
5827 aci, aifsn, acm, ecwmin, ecwmax);
5828
5829 ranking_basis[aci] = aifsn + ecwmin + ecwmax;
5830
5831 aci_prio[aci] = 0;
5832
5833
5834
5835
5836 if (aci != AC_BE && aci != AC_BK && acm == 1)
5837 ranking_basis[aci] = ranking_basis[AC_BE];
5838 }
5839
5840
5841
5842
5843
5844 for (aci = 0; aci < EDCF_AC_COUNT; aci++) {
5845 for (index = 0; index < EDCF_AC_COUNT; index++) {
5846 if (index != aci) {
5847
5848
5849
5850
5851 if (ranking_basis[aci] < ranking_basis[index])
5852 aci_prio[aci]++;
5853 }
5854 }
5855 }
5856
5857
5858
5859
5860
5861 if (!(aci_prio[AC_BE] == aci_prio[AC_BK] &&
5862 aci_prio[AC_BK] == aci_prio[AC_VI] &&
5863 aci_prio[AC_VI] == aci_prio[AC_VO])) {
5864
5865 priority[0] = aci_prio[AC_BE];
5866 priority[3] = aci_prio[AC_BE];
5867
5868
5869 priority[1] = aci_prio[AC_BK];
5870 priority[2] = aci_prio[AC_BK];
5871
5872
5873 priority[4] = aci_prio[AC_VI];
5874 priority[5] = aci_prio[AC_VI];
5875
5876
5877 priority[6] = aci_prio[AC_VO];
5878 priority[7] = aci_prio[AC_VO];
5879 } else {
5880
5881 brcmf_init_wmm_prio(priority);
5882 }
5883
5884 brcmf_dbg(CONN, "Adj prio BE 0->%d, BK 1->%d, BK 2->%d, BE 3->%d\n",
5885 priority[0], priority[1], priority[2], priority[3]);
5886
5887 brcmf_dbg(CONN, "Adj prio VI 4->%d, VI 5->%d, VO 6->%d, VO 7->%d\n",
5888 priority[4], priority[5], priority[6], priority[7]);
5889 }
5890
5891 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
5892 struct brcmf_if *ifp)
5893 {
5894 struct brcmf_pub *drvr = cfg->pub;
5895 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
5896 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5897 struct brcmf_cfg80211_edcf_acparam edcf_acparam_info[EDCF_AC_COUNT];
5898 u32 req_len;
5899 u32 resp_len;
5900 s32 err = 0;
5901
5902 brcmf_clear_assoc_ies(cfg);
5903
5904 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
5905 cfg->extra_buf, WL_ASSOC_INFO_MAX);
5906 if (err) {
5907 bphy_err(drvr, "could not get assoc info (%d)\n", err);
5908 return err;
5909 }
5910 assoc_info =
5911 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
5912 req_len = le32_to_cpu(assoc_info->req_len);
5913 resp_len = le32_to_cpu(assoc_info->resp_len);
5914 if (req_len) {
5915 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
5916 cfg->extra_buf,
5917 WL_ASSOC_INFO_MAX);
5918 if (err) {
5919 bphy_err(drvr, "could not get assoc req (%d)\n", err);
5920 return err;
5921 }
5922 conn_info->req_ie_len = req_len;
5923 conn_info->req_ie =
5924 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
5925 GFP_KERNEL);
5926 if (!conn_info->req_ie)
5927 conn_info->req_ie_len = 0;
5928 } else {
5929 conn_info->req_ie_len = 0;
5930 conn_info->req_ie = NULL;
5931 }
5932 if (resp_len) {
5933 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
5934 cfg->extra_buf,
5935 WL_ASSOC_INFO_MAX);
5936 if (err) {
5937 bphy_err(drvr, "could not get assoc resp (%d)\n", err);
5938 return err;
5939 }
5940 conn_info->resp_ie_len = resp_len;
5941 conn_info->resp_ie =
5942 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
5943 GFP_KERNEL);
5944 if (!conn_info->resp_ie)
5945 conn_info->resp_ie_len = 0;
5946
5947 err = brcmf_fil_iovar_data_get(ifp, "wme_ac_sta",
5948 edcf_acparam_info,
5949 sizeof(edcf_acparam_info));
5950 if (err) {
5951 brcmf_err("could not get wme_ac_sta (%d)\n", err);
5952 return err;
5953 }
5954
5955 brcmf_wifi_prioritize_acparams(edcf_acparam_info,
5956 cfg->ac_priority);
5957 } else {
5958 conn_info->resp_ie_len = 0;
5959 conn_info->resp_ie = NULL;
5960 }
5961 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
5962 conn_info->req_ie_len, conn_info->resp_ie_len);
5963
5964 return err;
5965 }
5966
5967 static s32
5968 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
5969 struct net_device *ndev,
5970 const struct brcmf_event_msg *e)
5971 {
5972 struct brcmf_if *ifp = netdev_priv(ndev);
5973 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5974 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5975 struct wiphy *wiphy = cfg_to_wiphy(cfg);
5976 struct ieee80211_channel *notify_channel = NULL;
5977 struct ieee80211_supported_band *band;
5978 struct brcmf_bss_info_le *bi;
5979 struct brcmu_chan ch;
5980 struct cfg80211_roam_info roam_info = {};
5981 u32 freq;
5982 s32 err = 0;
5983 u8 *buf;
5984
5985 brcmf_dbg(TRACE, "Enter\n");
5986
5987 brcmf_get_assoc_ies(cfg, ifp);
5988 memcpy(profile->bssid, e->addr, ETH_ALEN);
5989 brcmf_update_bss_info(cfg, ifp);
5990
5991 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
5992 if (buf == NULL) {
5993 err = -ENOMEM;
5994 goto done;
5995 }
5996
5997
5998 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
5999 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
6000 buf, WL_BSS_INFO_MAX);
6001
6002 if (err)
6003 goto done;
6004
6005 bi = (struct brcmf_bss_info_le *)(buf + 4);
6006 ch.chspec = le16_to_cpu(bi->chanspec);
6007 cfg->d11inf.decchspec(&ch);
6008
6009 if (ch.band == BRCMU_CHAN_BAND_2G)
6010 band = wiphy->bands[NL80211_BAND_2GHZ];
6011 else
6012 band = wiphy->bands[NL80211_BAND_5GHZ];
6013
6014 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
6015 notify_channel = ieee80211_get_channel(wiphy, freq);
6016
6017 done:
6018 kfree(buf);
6019
6020 roam_info.links[0].channel = notify_channel;
6021 roam_info.links[0].bssid = profile->bssid;
6022 roam_info.req_ie = conn_info->req_ie;
6023 roam_info.req_ie_len = conn_info->req_ie_len;
6024 roam_info.resp_ie = conn_info->resp_ie;
6025 roam_info.resp_ie_len = conn_info->resp_ie_len;
6026
6027 cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
6028 brcmf_dbg(CONN, "Report roaming result\n");
6029
6030 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
6031 cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL);
6032 brcmf_dbg(CONN, "Report port authorized\n");
6033 }
6034
6035 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
6036 brcmf_dbg(TRACE, "Exit\n");
6037 return err;
6038 }
6039
6040 static s32
6041 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
6042 struct net_device *ndev, const struct brcmf_event_msg *e,
6043 bool completed)
6044 {
6045 struct brcmf_if *ifp = netdev_priv(ndev);
6046 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6047 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6048 struct cfg80211_connect_resp_params conn_params;
6049
6050 brcmf_dbg(TRACE, "Enter\n");
6051
6052 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6053 &ifp->vif->sme_state)) {
6054 memset(&conn_params, 0, sizeof(conn_params));
6055 if (completed) {
6056 brcmf_get_assoc_ies(cfg, ifp);
6057 brcmf_update_bss_info(cfg, ifp);
6058 set_bit(BRCMF_VIF_STATUS_CONNECTED,
6059 &ifp->vif->sme_state);
6060 conn_params.status = WLAN_STATUS_SUCCESS;
6061 } else {
6062 conn_params.status = WLAN_STATUS_AUTH_TIMEOUT;
6063 }
6064 conn_params.links[0].bssid = profile->bssid;
6065 conn_params.req_ie = conn_info->req_ie;
6066 conn_params.req_ie_len = conn_info->req_ie_len;
6067 conn_params.resp_ie = conn_info->resp_ie;
6068 conn_params.resp_ie_len = conn_info->resp_ie_len;
6069 cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
6070 brcmf_dbg(CONN, "Report connect result - connection %s\n",
6071 completed ? "succeeded" : "failed");
6072 }
6073 brcmf_dbg(TRACE, "Exit\n");
6074 return 0;
6075 }
6076
6077 static s32
6078 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
6079 struct net_device *ndev,
6080 const struct brcmf_event_msg *e, void *data)
6081 {
6082 struct brcmf_pub *drvr = cfg->pub;
6083 static int generation;
6084 u32 event = e->event_code;
6085 u32 reason = e->reason;
6086 struct station_info *sinfo;
6087
6088 brcmf_dbg(CONN, "event %s (%u), reason %d\n",
6089 brcmf_fweh_event_name(event), event, reason);
6090 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
6091 ndev != cfg_to_ndev(cfg)) {
6092 brcmf_dbg(CONN, "AP mode link down\n");
6093 complete(&cfg->vif_disabled);
6094 return 0;
6095 }
6096
6097 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
6098 (reason == BRCMF_E_STATUS_SUCCESS)) {
6099 if (!data) {
6100 bphy_err(drvr, "No IEs present in ASSOC/REASSOC_IND\n");
6101 return -EINVAL;
6102 }
6103
6104 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
6105 if (!sinfo)
6106 return -ENOMEM;
6107
6108 sinfo->assoc_req_ies = data;
6109 sinfo->assoc_req_ies_len = e->datalen;
6110 generation++;
6111 sinfo->generation = generation;
6112 cfg80211_new_sta(ndev, e->addr, sinfo, GFP_KERNEL);
6113
6114 kfree(sinfo);
6115 } else if ((event == BRCMF_E_DISASSOC_IND) ||
6116 (event == BRCMF_E_DEAUTH_IND) ||
6117 (event == BRCMF_E_DEAUTH)) {
6118 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
6119 }
6120 return 0;
6121 }
6122
6123 static s32
6124 brcmf_notify_connect_status(struct brcmf_if *ifp,
6125 const struct brcmf_event_msg *e, void *data)
6126 {
6127 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6128 struct net_device *ndev = ifp->ndev;
6129 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6130 struct ieee80211_channel *chan;
6131 s32 err = 0;
6132
6133 if ((e->event_code == BRCMF_E_DEAUTH) ||
6134 (e->event_code == BRCMF_E_DEAUTH_IND) ||
6135 (e->event_code == BRCMF_E_DISASSOC_IND) ||
6136 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
6137 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
6138 }
6139
6140 if (brcmf_is_apmode(ifp->vif)) {
6141 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
6142 } else if (brcmf_is_linkup(ifp->vif, e)) {
6143 brcmf_dbg(CONN, "Linkup\n");
6144 if (brcmf_is_ibssmode(ifp->vif)) {
6145 brcmf_inform_ibss(cfg, ndev, e->addr);
6146 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
6147 memcpy(profile->bssid, e->addr, ETH_ALEN);
6148 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
6149 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6150 &ifp->vif->sme_state);
6151 set_bit(BRCMF_VIF_STATUS_CONNECTED,
6152 &ifp->vif->sme_state);
6153 } else
6154 brcmf_bss_connect_done(cfg, ndev, e, true);
6155 brcmf_net_setcarrier(ifp, true);
6156 } else if (brcmf_is_linkdown(ifp->vif, e)) {
6157 brcmf_dbg(CONN, "Linkdown\n");
6158 if (!brcmf_is_ibssmode(ifp->vif) &&
6159 test_bit(BRCMF_VIF_STATUS_CONNECTED,
6160 &ifp->vif->sme_state)) {
6161 if (memcmp(profile->bssid, e->addr, ETH_ALEN))
6162 return err;
6163
6164 brcmf_bss_connect_done(cfg, ndev, e, false);
6165 brcmf_link_down(ifp->vif,
6166 brcmf_map_fw_linkdown_reason(e),
6167 e->event_code &
6168 (BRCMF_E_DEAUTH_IND |
6169 BRCMF_E_DISASSOC_IND)
6170 ? false : true);
6171 brcmf_init_prof(ndev_to_prof(ndev));
6172 if (ndev != cfg_to_ndev(cfg))
6173 complete(&cfg->vif_disabled);
6174 brcmf_net_setcarrier(ifp, false);
6175 }
6176 } else if (brcmf_is_nonetwork(cfg, e)) {
6177 if (brcmf_is_ibssmode(ifp->vif))
6178 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6179 &ifp->vif->sme_state);
6180 else
6181 brcmf_bss_connect_done(cfg, ndev, e, false);
6182 }
6183
6184 return err;
6185 }
6186
6187 static s32
6188 brcmf_notify_roaming_status(struct brcmf_if *ifp,
6189 const struct brcmf_event_msg *e, void *data)
6190 {
6191 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6192 u32 event = e->event_code;
6193 u32 status = e->status;
6194
6195 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
6196 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
6197 &ifp->vif->sme_state)) {
6198 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
6199 } else {
6200 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
6201 brcmf_net_setcarrier(ifp, true);
6202 }
6203 }
6204
6205 return 0;
6206 }
6207
6208 static s32
6209 brcmf_notify_mic_status(struct brcmf_if *ifp,
6210 const struct brcmf_event_msg *e, void *data)
6211 {
6212 u16 flags = e->flags;
6213 enum nl80211_key_type key_type;
6214
6215 if (flags & BRCMF_EVENT_MSG_GROUP)
6216 key_type = NL80211_KEYTYPE_GROUP;
6217 else
6218 key_type = NL80211_KEYTYPE_PAIRWISE;
6219
6220 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
6221 NULL, GFP_KERNEL);
6222
6223 return 0;
6224 }
6225
6226 static s32 brcmf_notify_rssi(struct brcmf_if *ifp,
6227 const struct brcmf_event_msg *e, void *data)
6228 {
6229 struct brcmf_cfg80211_vif *vif = ifp->vif;
6230 struct brcmf_rssi_be *info = data;
6231 s32 rssi, snr, noise;
6232 s32 low, high, last;
6233
6234 if (e->datalen < sizeof(*info)) {
6235 brcmf_err("insufficient RSSI event data\n");
6236 return 0;
6237 }
6238
6239 rssi = be32_to_cpu(info->rssi);
6240 snr = be32_to_cpu(info->snr);
6241 noise = be32_to_cpu(info->noise);
6242
6243 low = vif->cqm_rssi_low;
6244 high = vif->cqm_rssi_high;
6245 last = vif->cqm_rssi_last;
6246
6247 brcmf_dbg(TRACE, "rssi=%d snr=%d noise=%d low=%d high=%d last=%d\n",
6248 rssi, snr, noise, low, high, last);
6249
6250 vif->cqm_rssi_last = rssi;
6251
6252 if (rssi <= low || rssi == 0) {
6253 brcmf_dbg(INFO, "LOW rssi=%d\n", rssi);
6254 cfg80211_cqm_rssi_notify(ifp->ndev,
6255 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
6256 rssi, GFP_KERNEL);
6257 } else if (rssi > high) {
6258 brcmf_dbg(INFO, "HIGH rssi=%d\n", rssi);
6259 cfg80211_cqm_rssi_notify(ifp->ndev,
6260 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
6261 rssi, GFP_KERNEL);
6262 }
6263
6264 return 0;
6265 }
6266
6267 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
6268 const struct brcmf_event_msg *e, void *data)
6269 {
6270 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6271 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
6272 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6273 struct brcmf_cfg80211_vif *vif;
6274
6275 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
6276 ifevent->action, ifevent->flags, ifevent->ifidx,
6277 ifevent->bsscfgidx);
6278
6279 spin_lock(&event->vif_event_lock);
6280 event->action = ifevent->action;
6281 vif = event->vif;
6282
6283 switch (ifevent->action) {
6284 case BRCMF_E_IF_ADD:
6285
6286 if (!cfg->vif_event.vif) {
6287 spin_unlock(&event->vif_event_lock);
6288 return -EBADF;
6289 }
6290
6291 ifp->vif = vif;
6292 vif->ifp = ifp;
6293 if (ifp->ndev) {
6294 vif->wdev.netdev = ifp->ndev;
6295 ifp->ndev->ieee80211_ptr = &vif->wdev;
6296 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
6297 }
6298 spin_unlock(&event->vif_event_lock);
6299 wake_up(&event->vif_wq);
6300 return 0;
6301
6302 case BRCMF_E_IF_DEL:
6303 spin_unlock(&event->vif_event_lock);
6304
6305 if (brcmf_cfg80211_vif_event_armed(cfg))
6306 wake_up(&event->vif_wq);
6307 return 0;
6308
6309 case BRCMF_E_IF_CHANGE:
6310 spin_unlock(&event->vif_event_lock);
6311 wake_up(&event->vif_wq);
6312 return 0;
6313
6314 default:
6315 spin_unlock(&event->vif_event_lock);
6316 break;
6317 }
6318 return -EINVAL;
6319 }
6320
6321 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
6322 {
6323 conf->frag_threshold = (u32)-1;
6324 conf->rts_threshold = (u32)-1;
6325 conf->retry_short = (u32)-1;
6326 conf->retry_long = (u32)-1;
6327 }
6328
6329 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
6330 {
6331 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
6332 brcmf_notify_connect_status);
6333 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
6334 brcmf_notify_connect_status);
6335 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
6336 brcmf_notify_connect_status);
6337 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
6338 brcmf_notify_connect_status);
6339 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
6340 brcmf_notify_connect_status);
6341 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
6342 brcmf_notify_connect_status);
6343 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
6344 brcmf_notify_roaming_status);
6345 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
6346 brcmf_notify_mic_status);
6347 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
6348 brcmf_notify_connect_status);
6349 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
6350 brcmf_notify_sched_scan_results);
6351 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
6352 brcmf_notify_vif_event);
6353 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
6354 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
6355 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
6356 brcmf_p2p_notify_listen_complete);
6357 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
6358 brcmf_p2p_notify_action_frame_rx);
6359 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
6360 brcmf_p2p_notify_action_tx_complete);
6361 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
6362 brcmf_p2p_notify_action_tx_complete);
6363 brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
6364 brcmf_notify_connect_status);
6365 brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, brcmf_notify_rssi);
6366 }
6367
6368 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
6369 {
6370 kfree(cfg->conf);
6371 cfg->conf = NULL;
6372 kfree(cfg->extra_buf);
6373 cfg->extra_buf = NULL;
6374 kfree(cfg->wowl.nd);
6375 cfg->wowl.nd = NULL;
6376 kfree(cfg->wowl.nd_info);
6377 cfg->wowl.nd_info = NULL;
6378 kfree(cfg->escan_info.escan_buf);
6379 cfg->escan_info.escan_buf = NULL;
6380 }
6381
6382 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
6383 {
6384 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
6385 if (!cfg->conf)
6386 goto init_priv_mem_out;
6387 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
6388 if (!cfg->extra_buf)
6389 goto init_priv_mem_out;
6390 cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
6391 if (!cfg->wowl.nd)
6392 goto init_priv_mem_out;
6393 cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
6394 sizeof(struct cfg80211_wowlan_nd_match *),
6395 GFP_KERNEL);
6396 if (!cfg->wowl.nd_info)
6397 goto init_priv_mem_out;
6398 cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
6399 if (!cfg->escan_info.escan_buf)
6400 goto init_priv_mem_out;
6401
6402 return 0;
6403
6404 init_priv_mem_out:
6405 brcmf_deinit_priv_mem(cfg);
6406
6407 return -ENOMEM;
6408 }
6409
6410 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
6411 {
6412 s32 err = 0;
6413
6414 cfg->scan_request = NULL;
6415 cfg->pwr_save = true;
6416 cfg->dongle_up = false;
6417 err = brcmf_init_priv_mem(cfg);
6418 if (err)
6419 return err;
6420 brcmf_register_event_handlers(cfg);
6421 mutex_init(&cfg->usr_sync);
6422 brcmf_init_escan(cfg);
6423 brcmf_init_conf(cfg->conf);
6424 brcmf_init_wmm_prio(cfg->ac_priority);
6425 init_completion(&cfg->vif_disabled);
6426 return err;
6427 }
6428
6429 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
6430 {
6431 cfg->dongle_up = false;
6432 brcmf_abort_scanning(cfg);
6433 brcmf_deinit_priv_mem(cfg);
6434 }
6435
6436 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
6437 {
6438 init_waitqueue_head(&event->vif_wq);
6439 spin_lock_init(&event->vif_event_lock);
6440 }
6441
6442 static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
6443 {
6444 struct brcmf_pub *drvr = ifp->drvr;
6445 s32 err;
6446 u32 bcn_timeout;
6447 __le32 roamtrigger[2];
6448 __le32 roam_delta[2];
6449
6450
6451 if (ifp->drvr->settings->roamoff)
6452 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
6453 else
6454 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
6455 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
6456 if (err) {
6457 bphy_err(drvr, "bcn_timeout error (%d)\n", err);
6458 goto roam_setup_done;
6459 }
6460
6461
6462
6463
6464 brcmf_dbg(INFO, "Internal Roaming = %s\n",
6465 ifp->drvr->settings->roamoff ? "Off" : "On");
6466 err = brcmf_fil_iovar_int_set(ifp, "roam_off",
6467 ifp->drvr->settings->roamoff);
6468 if (err) {
6469 bphy_err(drvr, "roam_off error (%d)\n", err);
6470 goto roam_setup_done;
6471 }
6472
6473 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
6474 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
6475 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
6476 (void *)roamtrigger, sizeof(roamtrigger));
6477 if (err)
6478 bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
6479
6480 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
6481 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
6482 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
6483 (void *)roam_delta, sizeof(roam_delta));
6484 if (err)
6485 bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err);
6486
6487 return 0;
6488
6489 roam_setup_done:
6490 return err;
6491 }
6492
6493 static s32
6494 brcmf_dongle_scantime(struct brcmf_if *ifp)
6495 {
6496 struct brcmf_pub *drvr = ifp->drvr;
6497 s32 err = 0;
6498
6499 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
6500 BRCMF_SCAN_CHANNEL_TIME);
6501 if (err) {
6502 bphy_err(drvr, "Scan assoc time error (%d)\n", err);
6503 goto dongle_scantime_out;
6504 }
6505 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
6506 BRCMF_SCAN_UNASSOC_TIME);
6507 if (err) {
6508 bphy_err(drvr, "Scan unassoc time error (%d)\n", err);
6509 goto dongle_scantime_out;
6510 }
6511
6512 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
6513 BRCMF_SCAN_PASSIVE_TIME);
6514 if (err) {
6515 bphy_err(drvr, "Scan passive time error (%d)\n", err);
6516 goto dongle_scantime_out;
6517 }
6518
6519 dongle_scantime_out:
6520 return err;
6521 }
6522
6523 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
6524 struct brcmu_chan *ch)
6525 {
6526 u32 ht40_flag;
6527
6528 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
6529 if (ch->sb == BRCMU_CHAN_SB_U) {
6530 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6531 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6532 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
6533 } else {
6534
6535
6536
6537
6538 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6539 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6540 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
6541 }
6542 }
6543
6544 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
6545 u32 bw_cap[])
6546 {
6547 struct wiphy *wiphy = cfg_to_wiphy(cfg);
6548 struct brcmf_pub *drvr = cfg->pub;
6549 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
6550 struct ieee80211_supported_band *band;
6551 struct ieee80211_channel *channel;
6552 struct brcmf_chanspec_list *list;
6553 struct brcmu_chan ch;
6554 int err;
6555 u8 *pbuf;
6556 u32 i, j;
6557 u32 total;
6558 u32 chaninfo;
6559
6560 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
6561
6562 if (pbuf == NULL)
6563 return -ENOMEM;
6564
6565 list = (struct brcmf_chanspec_list *)pbuf;
6566
6567 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
6568 BRCMF_DCMD_MEDLEN);
6569 if (err) {
6570 bphy_err(drvr, "get chanspecs error (%d)\n", err);
6571 goto fail_pbuf;
6572 }
6573
6574 band = wiphy->bands[NL80211_BAND_2GHZ];
6575 if (band)
6576 for (i = 0; i < band->n_channels; i++)
6577 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
6578 band = wiphy->bands[NL80211_BAND_5GHZ];
6579 if (band)
6580 for (i = 0; i < band->n_channels; i++)
6581 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
6582
6583 total = le32_to_cpu(list->count);
6584 for (i = 0; i < total; i++) {
6585 ch.chspec = (u16)le32_to_cpu(list->element[i]);
6586 cfg->d11inf.decchspec(&ch);
6587
6588 if (ch.band == BRCMU_CHAN_BAND_2G) {
6589 band = wiphy->bands[NL80211_BAND_2GHZ];
6590 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
6591 band = wiphy->bands[NL80211_BAND_5GHZ];
6592 } else {
6593 bphy_err(drvr, "Invalid channel Spec. 0x%x.\n",
6594 ch.chspec);
6595 continue;
6596 }
6597 if (!band)
6598 continue;
6599 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
6600 ch.bw == BRCMU_CHAN_BW_40)
6601 continue;
6602 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
6603 ch.bw == BRCMU_CHAN_BW_80)
6604 continue;
6605
6606 channel = NULL;
6607 for (j = 0; j < band->n_channels; j++) {
6608 if (band->channels[j].hw_value == ch.control_ch_num) {
6609 channel = &band->channels[j];
6610 break;
6611 }
6612 }
6613 if (!channel) {
6614
6615
6616
6617 bphy_err(drvr, "Ignoring unexpected firmware channel %d\n",
6618 ch.control_ch_num);
6619 continue;
6620 }
6621
6622 if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
6623 continue;
6624
6625
6626
6627
6628 switch (ch.bw) {
6629 case BRCMU_CHAN_BW_160:
6630 channel->flags &= ~IEEE80211_CHAN_NO_160MHZ;
6631 break;
6632 case BRCMU_CHAN_BW_80:
6633 channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
6634 break;
6635 case BRCMU_CHAN_BW_40:
6636 brcmf_update_bw40_channel_flag(channel, &ch);
6637 break;
6638 default:
6639 wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n",
6640 ch.bw);
6641 fallthrough;
6642 case BRCMU_CHAN_BW_20:
6643
6644
6645
6646
6647 channel->flags = IEEE80211_CHAN_NO_HT40 |
6648 IEEE80211_CHAN_NO_80MHZ |
6649 IEEE80211_CHAN_NO_160MHZ;
6650 ch.bw = BRCMU_CHAN_BW_20;
6651 cfg->d11inf.encchspec(&ch);
6652 chaninfo = ch.chspec;
6653 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
6654 &chaninfo);
6655 if (!err) {
6656 if (chaninfo & WL_CHAN_RADAR)
6657 channel->flags |=
6658 (IEEE80211_CHAN_RADAR |
6659 IEEE80211_CHAN_NO_IR);
6660 if (chaninfo & WL_CHAN_PASSIVE)
6661 channel->flags |=
6662 IEEE80211_CHAN_NO_IR;
6663 }
6664 }
6665 }
6666
6667 fail_pbuf:
6668 kfree(pbuf);
6669 return err;
6670 }
6671
6672 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
6673 {
6674 struct brcmf_pub *drvr = cfg->pub;
6675 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
6676 struct ieee80211_supported_band *band;
6677 struct brcmf_fil_bwcap_le band_bwcap;
6678 struct brcmf_chanspec_list *list;
6679 u8 *pbuf;
6680 u32 val;
6681 int err;
6682 struct brcmu_chan ch;
6683 u32 num_chan;
6684 int i, j;
6685
6686
6687 val = WLC_BAND_5G;
6688 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
6689
6690 if (!err) {
6691
6692 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
6693 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
6694 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
6695 sizeof(band_bwcap));
6696 } else {
6697 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
6698 val = WLC_N_BW_40ALL;
6699 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
6700 }
6701
6702 if (!err) {
6703
6704 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
6705
6706 if (pbuf == NULL)
6707 return -ENOMEM;
6708
6709 ch.band = BRCMU_CHAN_BAND_2G;
6710 ch.bw = BRCMU_CHAN_BW_40;
6711 ch.sb = BRCMU_CHAN_SB_NONE;
6712 ch.chnum = 0;
6713 cfg->d11inf.encchspec(&ch);
6714
6715
6716 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
6717
6718 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
6719 BRCMF_DCMD_MEDLEN);
6720 if (err) {
6721 bphy_err(drvr, "get chanspecs error (%d)\n", err);
6722 kfree(pbuf);
6723 return err;
6724 }
6725
6726 band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
6727 list = (struct brcmf_chanspec_list *)pbuf;
6728 num_chan = le32_to_cpu(list->count);
6729 for (i = 0; i < num_chan; i++) {
6730 ch.chspec = (u16)le32_to_cpu(list->element[i]);
6731 cfg->d11inf.decchspec(&ch);
6732 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
6733 continue;
6734 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
6735 continue;
6736 for (j = 0; j < band->n_channels; j++) {
6737 if (band->channels[j].hw_value == ch.control_ch_num)
6738 break;
6739 }
6740 if (WARN_ON(j == band->n_channels))
6741 continue;
6742
6743 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
6744 }
6745 kfree(pbuf);
6746 }
6747 return err;
6748 }
6749
6750 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
6751 {
6752 struct brcmf_pub *drvr = ifp->drvr;
6753 u32 band, mimo_bwcap;
6754 int err;
6755
6756 band = WLC_BAND_2G;
6757 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6758 if (!err) {
6759 bw_cap[NL80211_BAND_2GHZ] = band;
6760 band = WLC_BAND_5G;
6761 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6762 if (!err) {
6763 bw_cap[NL80211_BAND_5GHZ] = band;
6764 return;
6765 }
6766 WARN_ON(1);
6767 return;
6768 }
6769 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
6770 mimo_bwcap = 0;
6771 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
6772 if (err)
6773
6774 mimo_bwcap = WLC_N_BW_20ALL;
6775
6776 switch (mimo_bwcap) {
6777 case WLC_N_BW_40ALL:
6778 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
6779 fallthrough;
6780 case WLC_N_BW_20IN2G_40IN5G:
6781 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
6782 fallthrough;
6783 case WLC_N_BW_20ALL:
6784 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
6785 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
6786 break;
6787 default:
6788 bphy_err(drvr, "invalid mimo_bw_cap value\n");
6789 }
6790 }
6791
6792 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
6793 u32 bw_cap[2], u32 nchain)
6794 {
6795 band->ht_cap.ht_supported = true;
6796 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
6797 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
6798 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6799 }
6800 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
6801 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
6802 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
6803 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
6804 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
6805 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
6806 }
6807
6808 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
6809 {
6810 u16 mcs_map;
6811 int i;
6812
6813 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
6814 mcs_map = (mcs_map << 2) | supp;
6815
6816 return cpu_to_le16(mcs_map);
6817 }
6818
6819 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
6820 u32 bw_cap[2], u32 nchain, u32 txstreams,
6821 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
6822 {
6823 __le16 mcs_map;
6824
6825
6826 if (band->band == NL80211_BAND_2GHZ)
6827 return;
6828
6829 band->vht_cap.vht_supported = true;
6830
6831 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
6832 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
6833 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
6834 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
6835 }
6836
6837 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
6838 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
6839 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
6840
6841
6842 if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
6843 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
6844 if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
6845 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
6846 if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
6847 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
6848 if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
6849 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
6850
6851 if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
6852 band->vht_cap.cap |=
6853 (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
6854 band->vht_cap.cap |= ((txstreams - 1) <<
6855 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
6856 band->vht_cap.cap |=
6857 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
6858 }
6859 }
6860
6861 static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
6862 {
6863 struct brcmf_pub *drvr = cfg->pub;
6864 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
6865 struct wiphy *wiphy = cfg_to_wiphy(cfg);
6866 u32 nmode = 0;
6867 u32 vhtmode = 0;
6868 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
6869 u32 rxchain;
6870 u32 nchain;
6871 int err;
6872 s32 i;
6873 struct ieee80211_supported_band *band;
6874 u32 txstreams = 0;
6875 u32 txbf_bfe_cap = 0;
6876 u32 txbf_bfr_cap = 0;
6877
6878 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
6879 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
6880 if (err) {
6881 bphy_err(drvr, "nmode error (%d)\n", err);
6882 } else {
6883 brcmf_get_bwcap(ifp, bw_cap);
6884 }
6885 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
6886 nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ],
6887 bw_cap[NL80211_BAND_5GHZ]);
6888
6889 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
6890 if (err) {
6891
6892 if (err == -EBADE)
6893 bphy_info_once(drvr, "rxchain unsupported\n");
6894 else
6895 bphy_err(drvr, "rxchain error (%d)\n", err);
6896
6897 nchain = 1;
6898 } else {
6899 for (nchain = 0; rxchain; nchain++)
6900 rxchain = rxchain & (rxchain - 1);
6901 }
6902 brcmf_dbg(INFO, "nchain=%d\n", nchain);
6903
6904 err = brcmf_construct_chaninfo(cfg, bw_cap);
6905 if (err) {
6906 bphy_err(drvr, "brcmf_construct_chaninfo failed (%d)\n", err);
6907 return err;
6908 }
6909
6910 if (vhtmode) {
6911 (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
6912 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
6913 &txbf_bfe_cap);
6914 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
6915 &txbf_bfr_cap);
6916 }
6917
6918 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
6919 band = wiphy->bands[i];
6920 if (band == NULL)
6921 continue;
6922
6923 if (nmode)
6924 brcmf_update_ht_cap(band, bw_cap, nchain);
6925 if (vhtmode)
6926 brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
6927 txbf_bfe_cap, txbf_bfr_cap);
6928 }
6929
6930 return 0;
6931 }
6932
6933 static const struct ieee80211_txrx_stypes
6934 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
6935 [NL80211_IFTYPE_STATION] = {
6936 .tx = 0xffff,
6937 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6938 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6939 },
6940 [NL80211_IFTYPE_P2P_CLIENT] = {
6941 .tx = 0xffff,
6942 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6943 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6944 },
6945 [NL80211_IFTYPE_P2P_GO] = {
6946 .tx = 0xffff,
6947 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
6948 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
6949 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
6950 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
6951 BIT(IEEE80211_STYPE_AUTH >> 4) |
6952 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
6953 BIT(IEEE80211_STYPE_ACTION >> 4)
6954 },
6955 [NL80211_IFTYPE_P2P_DEVICE] = {
6956 .tx = 0xffff,
6957 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6958 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6959 },
6960 [NL80211_IFTYPE_AP] = {
6961 .tx = 0xffff,
6962 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
6963 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
6964 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
6965 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
6966 BIT(IEEE80211_STYPE_AUTH >> 4) |
6967 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
6968 BIT(IEEE80211_STYPE_ACTION >> 4)
6969 }
6970 };
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
7010 {
7011 struct ieee80211_iface_combination *combo = NULL;
7012 struct ieee80211_iface_limit *c0_limits = NULL;
7013 struct ieee80211_iface_limit *p2p_limits = NULL;
7014 struct ieee80211_iface_limit *mbss_limits = NULL;
7015 bool mon_flag, mbss, p2p, rsdb, mchan;
7016 int i, c, n_combos, n_limits;
7017
7018 mon_flag = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FLAG);
7019 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
7020 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
7021 rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
7022 mchan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN);
7023
7024 n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
7025 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
7026 if (!combo)
7027 goto err;
7028
7029 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
7030 BIT(NL80211_IFTYPE_ADHOC) |
7031 BIT(NL80211_IFTYPE_AP);
7032 if (mon_flag)
7033 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7034 if (p2p)
7035 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
7036 BIT(NL80211_IFTYPE_P2P_GO) |
7037 BIT(NL80211_IFTYPE_P2P_DEVICE);
7038
7039 c = 0;
7040 i = 0;
7041 n_limits = 1 + mon_flag + (p2p ? 2 : 0) + (rsdb || !p2p);
7042 c0_limits = kcalloc(n_limits, sizeof(*c0_limits), GFP_KERNEL);
7043 if (!c0_limits)
7044 goto err;
7045
7046 combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
7047 c0_limits[i].max = 1;
7048 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
7049 if (mon_flag) {
7050 c0_limits[i].max = 1;
7051 c0_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
7052 }
7053 if (p2p) {
7054 c0_limits[i].max = 1;
7055 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
7056 c0_limits[i].max = 1 + rsdb;
7057 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
7058 BIT(NL80211_IFTYPE_P2P_GO);
7059 }
7060 if (p2p && rsdb) {
7061 c0_limits[i].max = 2;
7062 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7063 combo[c].max_interfaces = 4;
7064 } else if (p2p) {
7065 combo[c].max_interfaces = i;
7066 } else if (rsdb) {
7067 c0_limits[i].max = 2;
7068 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7069 combo[c].max_interfaces = 3;
7070 } else {
7071 c0_limits[i].max = 1;
7072 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7073 combo[c].max_interfaces = i;
7074 }
7075 combo[c].n_limits = i;
7076 combo[c].limits = c0_limits;
7077
7078 if (p2p && !rsdb) {
7079 c++;
7080 i = 0;
7081 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
7082 if (!p2p_limits)
7083 goto err;
7084 p2p_limits[i].max = 1;
7085 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
7086 p2p_limits[i].max = 1;
7087 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7088 p2p_limits[i].max = 1;
7089 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
7090 p2p_limits[i].max = 1;
7091 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
7092 combo[c].num_different_channels = 1;
7093 combo[c].max_interfaces = i;
7094 combo[c].n_limits = i;
7095 combo[c].limits = p2p_limits;
7096 }
7097
7098 if (mbss) {
7099 c++;
7100 i = 0;
7101 n_limits = 1 + mon_flag;
7102 mbss_limits = kcalloc(n_limits, sizeof(*mbss_limits),
7103 GFP_KERNEL);
7104 if (!mbss_limits)
7105 goto err;
7106 mbss_limits[i].max = 4;
7107 mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7108 if (mon_flag) {
7109 mbss_limits[i].max = 1;
7110 mbss_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
7111 }
7112 combo[c].beacon_int_infra_match = true;
7113 combo[c].num_different_channels = 1;
7114 combo[c].max_interfaces = 4 + mon_flag;
7115 combo[c].n_limits = i;
7116 combo[c].limits = mbss_limits;
7117 }
7118
7119 wiphy->n_iface_combinations = n_combos;
7120 wiphy->iface_combinations = combo;
7121 return 0;
7122
7123 err:
7124 kfree(c0_limits);
7125 kfree(p2p_limits);
7126 kfree(mbss_limits);
7127 kfree(combo);
7128 return -ENOMEM;
7129 }
7130
7131 #ifdef CONFIG_PM
7132 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
7133 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
7134 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
7135 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
7136 .pattern_min_len = 1,
7137 .max_pkt_offset = 1500,
7138 };
7139 #endif
7140
7141 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
7142 {
7143 #ifdef CONFIG_PM
7144 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
7145 struct brcmf_pub *drvr = cfg->pub;
7146 struct wiphy_wowlan_support *wowl;
7147
7148 wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
7149 GFP_KERNEL);
7150 if (!wowl) {
7151 bphy_err(drvr, "only support basic wowlan features\n");
7152 wiphy->wowlan = &brcmf_wowlan_support;
7153 return;
7154 }
7155
7156 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
7157 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
7158 wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
7159 wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
7160 init_waitqueue_head(&cfg->wowl.nd_data_wait);
7161 }
7162 }
7163 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
7164 wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
7165 wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
7166 }
7167
7168 wiphy->wowlan = wowl;
7169 #endif
7170 }
7171
7172 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
7173 {
7174 struct brcmf_pub *drvr = ifp->drvr;
7175 const struct ieee80211_iface_combination *combo;
7176 struct ieee80211_supported_band *band;
7177 u16 max_interfaces = 0;
7178 bool gscan;
7179 __le32 bandlist[3];
7180 u32 n_bands;
7181 int err, i;
7182
7183 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
7184 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
7185 wiphy->max_num_pmkids = BRCMF_MAXPMKID;
7186
7187 err = brcmf_setup_ifmodes(wiphy, ifp);
7188 if (err)
7189 return err;
7190
7191 for (i = 0, combo = wiphy->iface_combinations;
7192 i < wiphy->n_iface_combinations; i++, combo++) {
7193 max_interfaces = max(max_interfaces, combo->max_interfaces);
7194 }
7195
7196 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
7197 i++) {
7198 u8 *addr = drvr->addresses[i].addr;
7199
7200 memcpy(addr, drvr->mac, ETH_ALEN);
7201 if (i) {
7202 addr[0] |= BIT(1);
7203 addr[ETH_ALEN - 1] ^= i;
7204 }
7205 }
7206 wiphy->addresses = drvr->addresses;
7207 wiphy->n_addresses = i;
7208
7209 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
7210 wiphy->cipher_suites = brcmf_cipher_suites;
7211 wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
7212 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
7213 wiphy->n_cipher_suites--;
7214 wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
7215 BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
7216 BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
7217
7218 wiphy->flags |= WIPHY_FLAG_NETNS_OK |
7219 WIPHY_FLAG_PS_ON_BY_DEFAULT |
7220 WIPHY_FLAG_HAVE_AP_SME |
7221 WIPHY_FLAG_OFFCHAN_TX |
7222 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
7223 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
7224 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7225 if (!ifp->drvr->settings->roamoff)
7226 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7227 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
7228 wiphy_ext_feature_set(wiphy,
7229 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
7230 wiphy_ext_feature_set(wiphy,
7231 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X);
7232 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
7233 wiphy_ext_feature_set(wiphy,
7234 NL80211_EXT_FEATURE_SAE_OFFLOAD);
7235 }
7236 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWAUTH)) {
7237 wiphy_ext_feature_set(wiphy,
7238 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK);
7239 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
7240 wiphy_ext_feature_set(wiphy,
7241 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP);
7242 }
7243 wiphy->mgmt_stypes = brcmf_txrx_stypes;
7244 wiphy->max_remain_on_channel_duration = 5000;
7245 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
7246 gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN);
7247 brcmf_pno_wiphy_params(wiphy, gscan);
7248 }
7249
7250 wiphy->vendor_commands = brcmf_vendor_cmds;
7251 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
7252
7253 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
7254 brcmf_wiphy_wowl_params(wiphy, ifp);
7255 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
7256 sizeof(bandlist));
7257 if (err) {
7258 bphy_err(drvr, "could not obtain band info: err=%d\n", err);
7259 return err;
7260 }
7261
7262 n_bands = le32_to_cpu(bandlist[0]);
7263 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
7264 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
7265 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
7266 GFP_KERNEL);
7267 if (!band)
7268 return -ENOMEM;
7269
7270 band->channels = kmemdup(&__wl_2ghz_channels,
7271 sizeof(__wl_2ghz_channels),
7272 GFP_KERNEL);
7273 if (!band->channels) {
7274 kfree(band);
7275 return -ENOMEM;
7276 }
7277
7278 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
7279 wiphy->bands[NL80211_BAND_2GHZ] = band;
7280 }
7281 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
7282 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
7283 GFP_KERNEL);
7284 if (!band)
7285 return -ENOMEM;
7286
7287 band->channels = kmemdup(&__wl_5ghz_channels,
7288 sizeof(__wl_5ghz_channels),
7289 GFP_KERNEL);
7290 if (!band->channels) {
7291 kfree(band);
7292 return -ENOMEM;
7293 }
7294
7295 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
7296 wiphy->bands[NL80211_BAND_5GHZ] = band;
7297 }
7298 }
7299
7300 if (wiphy->bands[NL80211_BAND_5GHZ] &&
7301 brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DOT11H))
7302 wiphy_ext_feature_set(wiphy,
7303 NL80211_EXT_FEATURE_DFS_OFFLOAD);
7304
7305 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
7306
7307 wiphy_read_of_freq_limits(wiphy);
7308
7309 return 0;
7310 }
7311
7312 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
7313 {
7314 struct brcmf_pub *drvr = cfg->pub;
7315 struct net_device *ndev;
7316 struct wireless_dev *wdev;
7317 struct brcmf_if *ifp;
7318 s32 power_mode;
7319 s32 err = 0;
7320
7321 if (cfg->dongle_up)
7322 return err;
7323
7324 ndev = cfg_to_ndev(cfg);
7325 wdev = ndev->ieee80211_ptr;
7326 ifp = netdev_priv(ndev);
7327
7328
7329 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
7330
7331 brcmf_dongle_scantime(ifp);
7332
7333 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
7334 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
7335 if (err)
7336 goto default_conf_out;
7337 brcmf_dbg(INFO, "power save set to %s\n",
7338 (power_mode ? "enabled" : "disabled"));
7339
7340 err = brcmf_dongle_roam(ifp);
7341 if (err)
7342 goto default_conf_out;
7343 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
7344 NULL);
7345 if (err)
7346 goto default_conf_out;
7347
7348 brcmf_configure_arp_nd_offload(ifp, true);
7349
7350 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
7351 if (err) {
7352 bphy_err(drvr, "failed to set frameburst mode\n");
7353 goto default_conf_out;
7354 }
7355
7356 cfg->dongle_up = true;
7357 default_conf_out:
7358
7359 return err;
7360
7361 }
7362
7363 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
7364 {
7365 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
7366
7367 return brcmf_config_dongle(ifp->drvr->config);
7368 }
7369
7370 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
7371 {
7372 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7373
7374
7375
7376
7377
7378 if (check_vif_up(ifp->vif)) {
7379 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED, true);
7380
7381
7382
7383
7384
7385 brcmf_delay(500);
7386 }
7387
7388 brcmf_abort_scanning(cfg);
7389 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
7390
7391 return 0;
7392 }
7393
7394 s32 brcmf_cfg80211_up(struct net_device *ndev)
7395 {
7396 struct brcmf_if *ifp = netdev_priv(ndev);
7397 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7398 s32 err = 0;
7399
7400 mutex_lock(&cfg->usr_sync);
7401 err = __brcmf_cfg80211_up(ifp);
7402 mutex_unlock(&cfg->usr_sync);
7403
7404 return err;
7405 }
7406
7407 s32 brcmf_cfg80211_down(struct net_device *ndev)
7408 {
7409 struct brcmf_if *ifp = netdev_priv(ndev);
7410 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7411 s32 err = 0;
7412
7413 mutex_lock(&cfg->usr_sync);
7414 err = __brcmf_cfg80211_down(ifp);
7415 mutex_unlock(&cfg->usr_sync);
7416
7417 return err;
7418 }
7419
7420 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
7421 {
7422 struct wireless_dev *wdev = &ifp->vif->wdev;
7423
7424 return wdev->iftype;
7425 }
7426
7427 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
7428 unsigned long state)
7429 {
7430 struct brcmf_cfg80211_vif *vif;
7431
7432 list_for_each_entry(vif, &cfg->vif_list, list) {
7433 if (test_bit(state, &vif->sme_state))
7434 return true;
7435 }
7436 return false;
7437 }
7438
7439 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
7440 u8 action)
7441 {
7442 u8 evt_action;
7443
7444 spin_lock(&event->vif_event_lock);
7445 evt_action = event->action;
7446 spin_unlock(&event->vif_event_lock);
7447 return evt_action == action;
7448 }
7449
7450 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
7451 struct brcmf_cfg80211_vif *vif)
7452 {
7453 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7454
7455 spin_lock(&event->vif_event_lock);
7456 event->vif = vif;
7457 event->action = 0;
7458 spin_unlock(&event->vif_event_lock);
7459 }
7460
7461 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
7462 {
7463 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7464 bool armed;
7465
7466 spin_lock(&event->vif_event_lock);
7467 armed = event->vif != NULL;
7468 spin_unlock(&event->vif_event_lock);
7469
7470 return armed;
7471 }
7472
7473 int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
7474 u8 action, ulong timeout)
7475 {
7476 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7477
7478 return wait_event_timeout(event->vif_wq,
7479 vif_event_equals(event, action), timeout);
7480 }
7481
7482 static bool brmcf_use_iso3166_ccode_fallback(struct brcmf_pub *drvr)
7483 {
7484 if (drvr->settings->trivial_ccode_map)
7485 return true;
7486
7487 switch (drvr->bus_if->chip) {
7488 case BRCM_CC_4345_CHIP_ID:
7489 case BRCM_CC_43602_CHIP_ID:
7490 return true;
7491 default:
7492 return false;
7493 }
7494 }
7495
7496 static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
7497 struct brcmf_fil_country_le *ccreq)
7498 {
7499 struct brcmfmac_pd_cc *country_codes;
7500 struct brcmfmac_pd_cc_entry *cc;
7501 s32 found_index;
7502 int i;
7503
7504 if ((alpha2[0] == ccreq->country_abbrev[0]) &&
7505 (alpha2[1] == ccreq->country_abbrev[1])) {
7506 brcmf_dbg(TRACE, "Country code already set\n");
7507 return -EAGAIN;
7508 }
7509
7510 country_codes = drvr->settings->country_codes;
7511 if (!country_codes) {
7512 if (brmcf_use_iso3166_ccode_fallback(drvr)) {
7513 brcmf_dbg(TRACE, "No country codes configured for device, using ISO3166 code and 0 rev\n");
7514 memset(ccreq, 0, sizeof(*ccreq));
7515 ccreq->country_abbrev[0] = alpha2[0];
7516 ccreq->country_abbrev[1] = alpha2[1];
7517 ccreq->ccode[0] = alpha2[0];
7518 ccreq->ccode[1] = alpha2[1];
7519 return 0;
7520 }
7521
7522 brcmf_dbg(TRACE, "No country codes configured for device\n");
7523 return -EINVAL;
7524 }
7525
7526 found_index = -1;
7527 for (i = 0; i < country_codes->table_size; i++) {
7528 cc = &country_codes->table[i];
7529 if ((cc->iso3166[0] == '\0') && (found_index == -1))
7530 found_index = i;
7531 if ((cc->iso3166[0] == alpha2[0]) &&
7532 (cc->iso3166[1] == alpha2[1])) {
7533 found_index = i;
7534 break;
7535 }
7536 }
7537 if (found_index == -1) {
7538 brcmf_dbg(TRACE, "No country code match found\n");
7539 return -EINVAL;
7540 }
7541 memset(ccreq, 0, sizeof(*ccreq));
7542 ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
7543 memcpy(ccreq->ccode, country_codes->table[found_index].cc,
7544 BRCMF_COUNTRY_BUF_SZ);
7545 ccreq->country_abbrev[0] = alpha2[0];
7546 ccreq->country_abbrev[1] = alpha2[1];
7547 ccreq->country_abbrev[2] = 0;
7548
7549 return 0;
7550 }
7551
7552 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
7553 struct regulatory_request *req)
7554 {
7555 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
7556 struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
7557 struct brcmf_pub *drvr = cfg->pub;
7558 struct brcmf_fil_country_le ccreq;
7559 s32 err;
7560 int i;
7561
7562
7563 if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
7564 return;
7565
7566
7567 for (i = 0; i < 2; i++)
7568 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
7569 bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n",
7570 req->alpha2[0], req->alpha2[1]);
7571 return;
7572 }
7573
7574 brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
7575 req->alpha2[0], req->alpha2[1]);
7576
7577 err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
7578 if (err) {
7579 bphy_err(drvr, "Country code iovar returned err = %d\n", err);
7580 return;
7581 }
7582
7583 err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
7584 if (err)
7585 return;
7586
7587 err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
7588 if (err) {
7589 bphy_err(drvr, "Firmware rejected country setting\n");
7590 return;
7591 }
7592 brcmf_setup_wiphybands(cfg);
7593 }
7594
7595 static void brcmf_free_wiphy(struct wiphy *wiphy)
7596 {
7597 int i;
7598
7599 if (!wiphy)
7600 return;
7601
7602 if (wiphy->iface_combinations) {
7603 for (i = 0; i < wiphy->n_iface_combinations; i++)
7604 kfree(wiphy->iface_combinations[i].limits);
7605 }
7606 kfree(wiphy->iface_combinations);
7607 if (wiphy->bands[NL80211_BAND_2GHZ]) {
7608 kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels);
7609 kfree(wiphy->bands[NL80211_BAND_2GHZ]);
7610 }
7611 if (wiphy->bands[NL80211_BAND_5GHZ]) {
7612 kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
7613 kfree(wiphy->bands[NL80211_BAND_5GHZ]);
7614 }
7615 #if IS_ENABLED(CONFIG_PM)
7616 if (wiphy->wowlan != &brcmf_wowlan_support)
7617 kfree(wiphy->wowlan);
7618 #endif
7619 }
7620
7621 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
7622 struct cfg80211_ops *ops,
7623 bool p2pdev_forced)
7624 {
7625 struct wiphy *wiphy = drvr->wiphy;
7626 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
7627 struct brcmf_cfg80211_info *cfg;
7628 struct brcmf_cfg80211_vif *vif;
7629 struct brcmf_if *ifp;
7630 s32 err = 0;
7631 s32 io_type;
7632 u16 *cap = NULL;
7633
7634 if (!ndev) {
7635 bphy_err(drvr, "ndev is invalid\n");
7636 return NULL;
7637 }
7638
7639 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
7640 if (!cfg) {
7641 bphy_err(drvr, "Could not allocate wiphy device\n");
7642 return NULL;
7643 }
7644
7645 cfg->wiphy = wiphy;
7646 cfg->pub = drvr;
7647 init_vif_event(&cfg->vif_event);
7648 INIT_LIST_HEAD(&cfg->vif_list);
7649
7650 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
7651 if (IS_ERR(vif))
7652 goto wiphy_out;
7653
7654 ifp = netdev_priv(ndev);
7655 vif->ifp = ifp;
7656 vif->wdev.netdev = ndev;
7657 ndev->ieee80211_ptr = &vif->wdev;
7658 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
7659
7660 err = wl_init_priv(cfg);
7661 if (err) {
7662 bphy_err(drvr, "Failed to init iwm_priv (%d)\n", err);
7663 brcmf_free_vif(vif);
7664 goto wiphy_out;
7665 }
7666 ifp->vif = vif;
7667
7668
7669 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
7670 if (err) {
7671 bphy_err(drvr, "Failed to get D11 version (%d)\n", err);
7672 goto priv_out;
7673 }
7674 cfg->d11inf.io_type = (u8)io_type;
7675 brcmu_d11_attach(&cfg->d11inf);
7676
7677
7678
7679
7680 drvr->config = cfg;
7681
7682 err = brcmf_setup_wiphy(wiphy, ifp);
7683 if (err < 0)
7684 goto priv_out;
7685
7686 brcmf_dbg(INFO, "Registering custom regulatory\n");
7687 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
7688 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
7689 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
7690
7691
7692
7693
7694
7695 if (wiphy->bands[NL80211_BAND_2GHZ]) {
7696 cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
7697 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7698 }
7699 #ifdef CONFIG_PM
7700 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
7701 ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
7702 #endif
7703 err = wiphy_register(wiphy);
7704 if (err < 0) {
7705 bphy_err(drvr, "Could not register wiphy device (%d)\n", err);
7706 goto priv_out;
7707 }
7708
7709 err = brcmf_setup_wiphybands(cfg);
7710 if (err) {
7711 bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err);
7712 goto wiphy_unreg_out;
7713 }
7714
7715
7716
7717
7718 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
7719 err = brcmf_enable_bw40_2g(cfg);
7720 if (!err)
7721 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
7722 BRCMF_OBSS_COEX_AUTO);
7723 else
7724 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7725 }
7726
7727 err = brcmf_fweh_activate_events(ifp);
7728 if (err) {
7729 bphy_err(drvr, "FWEH activation failed (%d)\n", err);
7730 goto wiphy_unreg_out;
7731 }
7732
7733 err = brcmf_p2p_attach(cfg, p2pdev_forced);
7734 if (err) {
7735 bphy_err(drvr, "P2P initialisation failed (%d)\n", err);
7736 goto wiphy_unreg_out;
7737 }
7738 err = brcmf_btcoex_attach(cfg);
7739 if (err) {
7740 bphy_err(drvr, "BT-coex initialisation failed (%d)\n", err);
7741 brcmf_p2p_detach(&cfg->p2p);
7742 goto wiphy_unreg_out;
7743 }
7744 err = brcmf_pno_attach(cfg);
7745 if (err) {
7746 bphy_err(drvr, "PNO initialisation failed (%d)\n", err);
7747 brcmf_btcoex_detach(cfg);
7748 brcmf_p2p_detach(&cfg->p2p);
7749 goto wiphy_unreg_out;
7750 }
7751
7752 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
7753 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
7754 if (err) {
7755 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
7756 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
7757 } else {
7758 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
7759 brcmf_notify_tdls_peer_event);
7760 }
7761 }
7762
7763
7764 err = brcmf_fweh_activate_events(ifp);
7765 if (err) {
7766 bphy_err(drvr, "FWEH activation failed (%d)\n", err);
7767 goto detach;
7768 }
7769
7770
7771 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
7772 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7773 #ifdef CONFIG_PM
7774 if (wiphy->wowlan &&
7775 wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
7776 wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7777 #endif
7778 }
7779
7780 return cfg;
7781
7782 detach:
7783 brcmf_pno_detach(cfg);
7784 brcmf_btcoex_detach(cfg);
7785 brcmf_p2p_detach(&cfg->p2p);
7786 wiphy_unreg_out:
7787 wiphy_unregister(cfg->wiphy);
7788 priv_out:
7789 wl_deinit_priv(cfg);
7790 brcmf_free_vif(vif);
7791 ifp->vif = NULL;
7792 wiphy_out:
7793 brcmf_free_wiphy(wiphy);
7794 kfree(cfg);
7795 return NULL;
7796 }
7797
7798 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
7799 {
7800 if (!cfg)
7801 return;
7802
7803 brcmf_pno_detach(cfg);
7804 brcmf_btcoex_detach(cfg);
7805 wiphy_unregister(cfg->wiphy);
7806 wl_deinit_priv(cfg);
7807 brcmf_free_wiphy(cfg->wiphy);
7808 kfree(cfg);
7809 }