1b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/****************************************************************************** 2b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 3b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 4b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 5b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * This program is free software; you can redistribute it and/or modify it 6b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * under the terms of version 2 of the GNU General Public License as 7b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * published by the Free Software Foundation. 8b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 9b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * This program is distributed in the hope that it will be useful, but WITHOUT 10b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * more details. 13b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * 14b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ******************************************************************************/ 15b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define _IOCTL_CFG80211_C_ 16b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 17b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <osdep_service.h> 18b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <drv_types.h> 19b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <xmit_osdep.h> 20b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 21b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include "ioctl_cfg80211.h" 22b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 23b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_MAX_MGMT_TX_CNT 8 24b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 25b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 /* ms */ 26b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_MAX_NUM_PMKIDS 4 27b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 28b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic const u32 rtw_cipher_suites[] = { 29b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_WEP40, 30b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_WEP104, 31b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_TKIP, 32b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_CCMP, 33b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 34b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 35b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RATETAB_ENT(_rate, _rateid, _flags) { \ 36b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .bitrate = (_rate), \ 37b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .hw_value = (_rateid), \ 38b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flags = (_flags), \ 39b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 40b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 41b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define CHAN2G(_channel, _freq, _flags) { \ 42b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .band = IEEE80211_BAND_2GHZ, \ 43b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .center_freq = (_freq), \ 44b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .hw_value = (_channel), \ 45b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flags = (_flags), \ 46b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_antenna_gain = 0, \ 47b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_power = 30, \ 48b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 49b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 50b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define CHAN5G(_channel, _flags) { \ 51b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .band = IEEE80211_BAND_5GHZ, \ 52b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .center_freq = 5000 + (5 * (_channel)), \ 53b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .hw_value = (_channel), \ 54b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flags = (_flags), \ 55b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_antenna_gain = 0, \ 56b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_power = 30, \ 57b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 58b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 59b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_rate rtw_rates[] = { 60b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(10, 0x1, 0), 61b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(20, 0x2, 0), 62b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(55, 0x4, 0), 63b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(110, 0x8, 0), 64b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(60, 0x10, 0), 65b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(90, 0x20, 0), 66b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(120, 0x40, 0), 67b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(180, 0x80, 0), 68b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(240, 0x100, 0), 69b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(360, 0x200, 0), 70b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(480, 0x400, 0), 71b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(540, 0x800, 0), 72b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 73b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 74b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define rtw_a_rates (rtw_rates + 4) 75b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_A_RATES_NUM 8 76b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define rtw_g_rates (rtw_rates + 0) 77b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_G_RATES_NUM 12 78b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 79b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_2G_CHANNELS_NUM 14 80b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_5G_CHANNELS_NUM 37 81b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 82b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_channel rtw_2ghz_channels[] = { 83b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(1, 2412, 0), 84b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(2, 2417, 0), 85b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(3, 2422, 0), 86b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(4, 2427, 0), 87b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(5, 2432, 0), 88b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(6, 2437, 0), 89b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(7, 2442, 0), 90b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(8, 2447, 0), 91b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(9, 2452, 0), 92b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(10, 2457, 0), 93b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(11, 2462, 0), 94b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(12, 2467, 0), 95b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(13, 2472, 0), 96b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(14, 2484, 0), 97b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 98b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 99b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_channel rtw_5ghz_a_channels[] = { 100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(34, 0), CHAN5G(36, 0), 101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(38, 0), CHAN5G(40, 0), 102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(42, 0), CHAN5G(44, 0), 103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(46, 0), CHAN5G(48, 0), 104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(52, 0), CHAN5G(56, 0), 105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(60, 0), CHAN5G(64, 0), 106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(100, 0), CHAN5G(104, 0), 107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(108, 0), CHAN5G(112, 0), 108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(116, 0), CHAN5G(120, 0), 109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(124, 0), CHAN5G(128, 0), 110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(132, 0), CHAN5G(136, 0), 111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(140, 0), CHAN5G(149, 0), 112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(153, 0), CHAN5G(157, 0), 113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(161, 0), CHAN5G(165, 0), 114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(184, 0), CHAN5G(188, 0), 115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(192, 0), CHAN5G(196, 0), 116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(200, 0), CHAN5G(204, 0), 117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(208, 0), CHAN5G(212, 0), 118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(216, 0), 119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 121b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_2g_channels_init(struct ieee80211_channel *channels) 122b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy((void *)channels, (void *)rtw_2ghz_channels, 124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM); 125b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 127b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_5g_channels_init(struct ieee80211_channel *channels) 128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy((void *)channels, (void *)rtw_5ghz_a_channels, 130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * RTW_5G_CHANNELS_NUM); 131b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 133b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_2g_rates_init(struct ieee80211_rate *rates) 134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(rates, rtw_g_rates, 136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM); 137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 138b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 139b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_5g_rates_init(struct ieee80211_rate *rates) 140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(rates, rtw_a_rates, 142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM); 143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 145b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_supported_band * 146b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerrtw_spt_band_alloc(enum ieee80211_band band) 147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 148b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_supported_band *spt_band = NULL; 149b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int n_channels, n_bitrates; 150b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (band == IEEE80211_BAND_2GHZ) { 152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_channels = RTW_2G_CHANNELS_NUM; 153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_bitrates = RTW_G_RATES_NUM; 154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (band == IEEE80211_BAND_5GHZ) { 155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_channels = RTW_5G_CHANNELS_NUM; 156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_bitrates = RTW_A_RATES_NUM; 157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band = kzalloc(sizeof(struct ieee80211_supported_band) + 161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * n_channels + 162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_rate) * n_bitrates, 163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_KERNEL); 164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!spt_band) 165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->channels = 168b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct ieee80211_channel *)(((u8 *) spt_band) + 169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct 170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ieee80211_supported_band)); 171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->bitrates = 172b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct ieee80211_rate *)(((u8 *) spt_band->channels) + 173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * 174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_channels); 175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->band = band; 176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->n_channels = n_channels; 177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->n_bitrates = n_bitrates; 178b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (band == IEEE80211_BAND_2GHZ) { 180b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_2g_channels_init(spt_band->channels); 181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_2g_rates_init(spt_band->bitrates); 182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (band == IEEE80211_BAND_5GHZ) { 183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_5g_channels_init(spt_band->channels); 184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_5g_rates_init(spt_band->bitrates); 185b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 187b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* spt_band.ht_cap */ 188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 189b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return spt_band; 191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 192b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 193b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic const struct ieee80211_txrx_stypes 194b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerrtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { 195b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_ADHOC] = { 196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 197b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ACTION >> 4) 198b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_STATION] = { 200b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) 203b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_AP] = { 205b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 206b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | 207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | 208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | 209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DISASSOC >> 4) | 210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_AUTH >> 4) | 211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DEAUTH >> 4) | 212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_ACTION >> 4) 213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_AP_VLAN] = { 215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* copy AP */ 216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | 218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | 219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | 220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DISASSOC >> 4) | 221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_AUTH >> 4) | 222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DEAUTH >> 4) | 223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_ACTION >> 4) 224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_P2P_CLIENT] = { 226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) 229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 230b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_P2P_GO] = { 231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | 233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | 234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | 235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DISASSOC >> 4) | 236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_AUTH >> 4) | 237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DEAUTH >> 4) | 238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_ACTION >> 4) 239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 242b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter, 243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *pnetwork) 244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_channel *notify_channel; 247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_bss *bss; 248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 channel; 249b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 freq; 250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *notify_ie; 251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t notify_ielen; 252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 notify_signal; 253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev = padapter->rtw_wdev; 254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy = wdev->wiphy; 255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 25737cb982c2685029e716bfeccf55ec244a6919a32Jes Sorensen channel = pnetwork->network.DSConfig; 258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 263b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_channel = ieee80211_get_channel(wiphy, freq); 266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2671de65ccb1f90be71cd7deb3c963f7440560e4325Jes Sorensen notify_ie = pnetwork->network.IEs; 2681de65ccb1f90be71cd7deb3c963f7440560e4325Jes Sorensen notify_ielen = pnetwork->network.IELength; 269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: 271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * signal strength in mBm (100*dBm) 272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_LINKED) && 274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger is_same_network23a(&pmlmepriv->cur_network.network, 275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &pnetwork->network)) { 276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */ 277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */ 279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2814062f7aa8f867e515267aeec62a152d2cf763a1cJes Sorensen bss = cfg80211_inform_bss(wiphy, notify_channel, 2825bc8c1f2b070bab82ed738f98ecfac725e33c57fJohannes Berg CFG80211_BSS_FTYPE_UNKNOWN, 283993c52ba61a72a8c669c8091fa75c9514776b3f7Jes Sorensen pnetwork->network.MacAddress, 284993c52ba61a72a8c669c8091fa75c9514776b3f7Jes Sorensen pnetwork->network.tsf, 28511a80e8877bf2db8a13b68018049b48e367bd76eJes Sorensen pnetwork->network.capability, 286143ced27acaa948cbcf34cafe0bca3c926fd35fcJes Sorensen pnetwork->network.beacon_interval, 2874062f7aa8f867e515267aeec62a152d2cf763a1cJes Sorensen notify_ie, notify_ielen, 2884062f7aa8f867e515267aeec62a152d2cf763a1cJes Sorensen notify_signal, GFP_ATOMIC); 289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(!bss)) { 291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("rtw_cfg80211_inform_bss error\n"); 292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_put_bss(wiphy, bss); 296b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 299b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 300b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_connect(struct rtw_adapter *padapter) 301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *cur_network = &pmlmepriv->cur_network; 304b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *pwdev = padapter->rtw_wdev; 305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p)\n", __func__, padapter); 307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 308b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev->iftype != NL80211_IFTYPE_STATION && 309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT) 310b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 31556828797acdb99d23b5e5e5c52e7d571d59b783fJes Sorensen if (padapter->mlmepriv.to_roaming > 0) { 316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy = pwdev->wiphy; 317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_channel *notify_channel; 318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 freq; 31937cb982c2685029e716bfeccf55ec244a6919a32Jes Sorensen u16 channel = cur_network->network.DSConfig; 320b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 321b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 322b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = 323b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ieee80211_channel_to_frequency(channel, 324b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 325b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 326b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = 327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ieee80211_channel_to_frequency(channel, 328b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 329b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_channel = ieee80211_get_channel(wiphy, freq); 331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s call cfg80211_roamed\n", __func__); 333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_roamed(padapter->pnetdev, notify_channel, 334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cur_network->network.MacAddress, 335b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req + 336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 2, 337b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req_len - 338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 2, 339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp + 340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 6, 341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp_len - 342b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 6, 343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_connect_result(padapter->pnetdev, 346b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cur_network->network.MacAddress, 347b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req + 348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 2, 349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req_len - 350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 2, 351b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp + 352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 6, 353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp_len - 354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 6, 355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_STATUS_SUCCESS, GFP_ATOMIC); 356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 359b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_disconnect(struct rtw_adapter *padapter) 360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *pwdev = padapter->rtw_wdev; 363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p)\n", __func__, padapter); 365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev->iftype != NL80211_IFTYPE_STATION && 367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT) 368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 369b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 370b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter->mlmepriv.not_indic_disco) { 374b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) { 375b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0, NULL, 0, 377b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_STATUS_UNSPECIFIED_FAILURE, 378b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 379b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_disconnected(padapter->pnetdev, 0, NULL, 381b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0, GFP_ATOMIC); 382b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 383b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 385b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 38716b9632da2c071d74934447e266717787bec449bJes Sorensenstatic int set_pairwise_key(struct rtw_adapter *padapter, struct sta_info *psta) 388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_obj *ph2c; 390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct set_stakey_parm *psetstakey_para; 391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 39216b9632da2c071d74934447e266717787bec449bJes Sorensen int res = _SUCCESS; 393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 394b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ph2c == NULL) { 396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); 401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psetstakey_para == NULL) { 402b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(ph2c); 403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4097989bcf3e21683f413dd1488718166d3ff474bf3Jes Sorensen psetstakey_para->algorithm = psta->dot118021XPrivacy; 410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 411888df442ef023adbca6536888eae65b2cd8ae295Jes Sorensen ether_addr_copy(psetstakey_para->addr, psta->hwaddr); 412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16); 414b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 415b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = rtw_enqueue_cmd23a(pcmdpriv, ph2c); 416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 417b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 418b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return res; 419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4212dcf6b4c73a3b92774955b83e5bd7c5cec2c87e6Jes Sorensenstatic int set_group_key(struct rtw_adapter *padapter, struct key_params *parms, 4222dcf6b4c73a3b92774955b83e5bd7c5cec2c87e6Jes Sorensen u32 alg, u8 keyid) 423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_obj *pcmd; 425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct setkey_parm *psetkeyparm; 426b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int res = _SUCCESS; 428b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4314e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen if (keyid >= 4) { 4324e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen res = _FAIL; 4334e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen goto exit; 4344e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen } 4354e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen 436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pcmd) { 438b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 440b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL); 442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!psetkeyparm) { 443b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pcmd); 444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 446b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4484e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen psetkeyparm->keyid = keyid; 449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (is_wep_enc(alg)) 4504e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid); 451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 452b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetkeyparm->algorithm = alg; 453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetkeyparm->set_tx = 1; 455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4562dcf6b4c73a3b92774955b83e5bd7c5cec2c87e6Jes Sorensen memcpy(&psetkeyparm->key, parms->key, parms->key_len); 457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 458b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->cmdcode = _SetKey_CMD_; 459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->parmbuf = (u8 *) psetkeyparm; 460b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->cmdsz = (sizeof(struct setkey_parm)); 461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->rsp = NULL; 462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->rspsz = 0; 463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = rtw_enqueue_cmd23a(pcmdpriv, pcmd); 465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 466b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return res; 468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 470f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensenstatic int rtw_cfg80211_ap_set_encryption(struct net_device *dev, u8 key_index, 471f88ab54c10b1270257f39268e88c1949fd903fb2Jes Sorensen int set_tx, const u8 *sta_addr, 4725dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen struct key_params *keyparms) 473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 475c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen int key_len; 476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta = NULL, *pbcmc_sta = NULL; 477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(dev); 478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4837ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen if (!is_broadcast_ether_addr(sta_addr)) { 484f88ab54c10b1270257f39268e88c1949fd903fb2Jes Sorensen psta = rtw_get_stainfo23a(pstapriv, sta_addr); 485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!psta) { 486b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* ret = -EINVAL; */ 487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("rtw_set_encryption(), sta has already " 488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "been removed or never been added\n"); 489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 493c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen key_len = keyparms->key_len; 494c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen 4955dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen if (!psta && (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 || 4965dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen keyparms->cipher == WLAN_CIPHER_SUITE_WEP104)) { 497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n"); 498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("r871x_set_encryption, wep_key_idx =%d, len =%d\n", 500f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen key_index, key_len); 501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->bWepDefaultKeyIdxSet == 0) { 503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wep default key has not been set, so use 504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger this key index as default key. */ 505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = 507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 50855db5d02f81bd45c3a47f4ab4a917a70c6e13916Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = keyparms->cipher; 50955db5d02f81bd45c3a47f4ab4a917a70c6e13916Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = keyparms->cipher; 510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 511f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen psecuritypriv->dot11PrivacyKeyIndex = key_index; 512b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 514f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen memcpy(&psecuritypriv->wep_key[key_index].key, 515c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen keyparms->key, key_len); 516b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 517f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen psecuritypriv->wep_key[key_index].keylen = key_len; 518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5192dcf6b4c73a3b92774955b83e5bd7c5cec2c87e6Jes Sorensen set_group_key(padapter, keyparms, keyparms->cipher, key_index); 520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5244e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen if (!psta) { /* group key */ 5250996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen if (set_tx == 0) { /* group key */ 5265dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 || 5275dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) { 5289cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s, set group_key, WEP\n", __func__); 529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 531f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrpKey[key_index].skey, 5327ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen keyparms->key, key_len); 533b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 53455db5d02f81bd45c3a47f4ab4a917a70c6e13916Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 53555db5d02f81bd45c3a47f4ab4a917a70c6e13916Jes Sorensen keyparms->cipher; 5365dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) { 537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set group_key, TKIP\n", 538b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 539b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5404e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 5414e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen WLAN_CIPHER_SUITE_TKIP; 542b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 544f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrpKey[key_index].skey, 545fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen keyparms->key, 546c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen (key_len > 16 ? 16 : key_len)); 547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set mic key */ 549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 550f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrptxmickey[key_index].skey, 551fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen &keyparms->key[16], 8); 552b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 553f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrprxmickey[key_index].skey, 554fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen &keyparms->key[24], 8); 555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5569216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen psecuritypriv->busetkipkey = 1; 557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5585dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) { 5595dab9e7d2af054ad1df60ef51e25b2dd5e85517bJes Sorensen DBG_8723A("%s, set group_key, CCMP\n", 560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5624e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 5634e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen WLAN_CIPHER_SUITE_CCMP; 564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 566fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen dot118021XGrpKey[key_index].skey, 567fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen keyparms->key, 568c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen (key_len > 16 ? 16 : key_len)); 569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set group_key, none\n", 571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5737ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen psecuritypriv->dot118021XGrpPrivacy = 0; 574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 575b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 576f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen psecuritypriv->dot118021XGrpKeyid = key_index; 577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5789216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen psecuritypriv->binstallGrpkey = 1; 579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyAlgrthm = 581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy; 582b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5832dcf6b4c73a3b92774955b83e5bd7c5cec2c87e6Jes Sorensen set_group_key(padapter, keyparms, 584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy, 585f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen key_index); 586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter); 588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pbcmc_sta) { 589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->ieee8021x_blocked = false; 590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* rx will use bmc_sta's dot118021XPrivacy */ 591b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->dot118021XPrivacy = 592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy; 593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 597b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6014e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { 6024e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen /* psk/802_1x */ 6030996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen if (set_tx == 1) { 6044e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen /* pairwise key */ 6054e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psta->dot118021x_UncstKey.skey, 606fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen keyparms->key, (key_len > 16 ? 16 : key_len)); 607b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6084e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 || 6094e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) { 6104e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen DBG_8723A("%s, set pairwise key, WEP\n", 6114e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen __func__); 612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 61355db5d02f81bd45c3a47f4ab4a917a70c6e13916Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 61455db5d02f81bd45c3a47f4ab4a917a70c6e13916Jes Sorensen keyparms->cipher; 6154e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) { 6164e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen DBG_8723A("%s, set pairwise key, TKIP\n", 6174e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen __func__); 618b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6194e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psta->dot118021XPrivacy = 6204e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen WLAN_CIPHER_SUITE_TKIP; 621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6224e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen /* set mic key */ 6234e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psta->dot11tkiptxmickey.skey, 624fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen &keyparms->key[16], 8); 6254e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psta->dot11tkiprxmickey.skey, 626fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen &keyparms->key[24], 8); 627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6284e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->busetkipkey = 1; 629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6304e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) { 6314e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen DBG_8723A("%s, set pairwise key, CCMP\n", 6324e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen __func__); 633b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6344e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psta->dot118021XPrivacy = 6354e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen WLAN_CIPHER_SUITE_CCMP; 6364e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } else { 6374e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen DBG_8723A("%s, set pairwise key, none\n", 6384e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen __func__); 639b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6404e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psta->dot118021XPrivacy = 0; 6414e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } 642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6434e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen set_pairwise_key(padapter, psta); 644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6454e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psta->ieee8021x_blocked = false; 646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6474e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psta->bpairwise_key_installed = true; 6484e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } else { /* group key??? */ 6494e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 || 6504e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) { 6514e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psecuritypriv-> 652f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrpKey[key_index].skey, 6537ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen keyparms->key, key_len); 6544e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen 6554e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 65655db5d02f81bd45c3a47f4ab4a917a70c6e13916Jes Sorensen keyparms->cipher; 6574e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) { 6584e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 6594e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen WLAN_CIPHER_SUITE_TKIP; 660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6614e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psecuritypriv-> 662f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrpKey[key_index].skey, 663fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen keyparms->key, 664c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen (key_len > 16 ? 16 : key_len)); 665b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6664e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen /* set mic key */ 6674e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psecuritypriv-> 668f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrptxmickey[key_index].skey, 669fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen &keyparms->key[16], 8); 6704e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psecuritypriv-> 671f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrprxmickey[key_index].skey, 672fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen &keyparms->key[24], 8); 673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6744e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->busetkipkey = 1; 6754e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) { 6764e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 6774e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen WLAN_CIPHER_SUITE_CCMP; 6784e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen 6794e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen memcpy(psecuritypriv-> 680f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen dot118021XGrpKey[key_index].skey, 681fd381874eb3efded6c088f649a03c03b9690d588Jes Sorensen keyparms->key, 682c36e122f6eba4e31c67d572c1e01ef845747010dJes Sorensen (key_len > 16 ? 16 : key_len)); 6834e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } else { 6844e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 0; 6854e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen } 6864e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen 687f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen psecuritypriv->dot118021XGrpKeyid = key_index; 6884e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen 6894e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->binstallGrpkey = 1; 6904e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen 6914e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = 6924e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy; 6934e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen 6942dcf6b4c73a3b92774955b83e5bd7c5cec2c87e6Jes Sorensen set_group_key(padapter, keyparms, 6954e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy, 696f7ce87cdb7b8e7a674fa66d3948c5f6986737377Jes Sorensen key_index); 6974e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen 6984e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter); 6994e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen if (pbcmc_sta) { 7004e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen /* rx will use bmc_sta's 7014e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen dot118021XPrivacy */ 7024e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen pbcmc_sta->ieee8021x_blocked = false; 7034e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen pbcmc_sta->dot118021XPrivacy = 7044e297c21bf2932178e7bdaeff654914b576e5f70Jes Sorensen psecuritypriv->dot118021XGrpPrivacy; 705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 709b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 710b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 714b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7155292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensenstatic int rtw_cfg80211_set_encryption(struct net_device *dev, u8 key_index, 716f88ab54c10b1270257f39268e88c1949fd903fb2Jes Sorensen int set_tx, const u8 *sta_addr, 717a9e346fb88d6daeef37c21a3c55ebd70f1501fd2Jes Sorensen struct key_params *keyparms) 718b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 720d0dc266692d1bd4579fd9abd4a9b80f8d0ab5150Jes Sorensen int key_len; 721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(dev); 722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 725b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 727d0dc266692d1bd4579fd9abd4a9b80f8d0ab5150Jes Sorensen key_len = keyparms->key_len; 728d0dc266692d1bd4579fd9abd4a9b80f8d0ab5150Jes Sorensen 7298188b1cb6165655d087edf89b6619e62021762d8Jes Sorensen if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 || 7308188b1cb6165655d087edf89b6619e62021762d8Jes Sorensen keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) { 731b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, 732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("wpa_set_encryption, crypt.alg = WEP\n")); 733b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n"); 734b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->bWepDefaultKeyIdxSet == 0) { 736b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wep default key has not been set, so use this 737b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger key index as default key. */ 738b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 739b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = 740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 7417ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = keyparms->cipher; 7427ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen psecuritypriv->dot118021XGrpPrivacy = keyparms->cipher; 743b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7445292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen psecuritypriv->dot11PrivacyKeyIndex = key_index; 745b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 746b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7475292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen memcpy(&psecuritypriv->wep_key[key_index].key, 748e1343f90809ab29bd1ec286fef1d9e6fcc59b404Jes Sorensen keyparms->key, key_len); 749b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7505292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen psecuritypriv->wep_key[key_index].keylen = key_len; 751b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7525292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen rtw_set_key23a(padapter, psecuritypriv, key_index, 0); 753b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 754b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 755b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 756b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 757b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->securitypriv.dot11AuthAlgrthm == 758b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X) { /* 802_1x */ 759b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta, *pbcmc_sta; 760b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 761b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 762b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, 763b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WIFI_STATION_STATE | WIFI_MP_STATE)) { 764b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* sta mode */ 765b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = rtw_get_stainfo23a(pstapriv, get_bssid(pmlmepriv)); 766b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psta == NULL) { 767b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, : Obtain Sta_info fail\n", 768b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 769b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 770b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Jeff: don't disable ieee8021x_blocked 771b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger while clearing key */ 772efd4216c2d558f2faf03284e95a9c1c1297d801aJes Sorensen if (keyparms->cipher != IW_AUTH_CIPHER_NONE && 773efd4216c2d558f2faf03284e95a9c1c1297d801aJes Sorensen keyparms->cipher != 0) 774b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->ieee8021x_blocked = false; 775b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 776b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((padapter->securitypriv.ndisencryptstatus == 777b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled) || 778b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->securitypriv.ndisencryptstatus == 779b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled)) { 780b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->dot118021XPrivacy = 781b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 782b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11PrivacyAlgrthm; 783b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 784b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7850996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen if (set_tx == 1) { 786b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* pairwise key */ 7870996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen DBG_8723A("%s, : set_tx == 1\n", 7880996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen __func__); 789b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 790b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot118021x_UncstKey.skey, 791e1343f90809ab29bd1ec286fef1d9e6fcc59b404Jes Sorensen keyparms->key, 792d0dc266692d1bd4579fd9abd4a9b80f8d0ab5150Jes Sorensen (key_len > 16 ? 16 : key_len)); 793b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7948188b1cb6165655d087edf89b6619e62021762d8Jes Sorensen if (keyparms->cipher == 7958188b1cb6165655d087edf89b6619e62021762d8Jes Sorensen WLAN_CIPHER_SUITE_TKIP) { 796b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot11tkiptxmickey. 797b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, 798e1343f90809ab29bd1ec286fef1d9e6fcc59b404Jes Sorensen &keyparms->key[16], 8); 799b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot11tkiprxmickey. 800b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, 801e1343f90809ab29bd1ec286fef1d9e6fcc59b404Jes Sorensen &keyparms->key[24], 8); 802b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 803b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 8049216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen busetkipkey = 0; 805b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 806b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A(" ~~~~set sta key:unicastkey\n"); 807b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 808b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_setstakey_cmd23a(padapter, 809b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (unsigned char *)psta, 810b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true); 811b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { /* group key */ 812b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(padapter->securitypriv. 8135292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen dot118021XGrpKey[key_index].skey, 814e1343f90809ab29bd1ec286fef1d9e6fcc59b404Jes Sorensen keyparms->key, 815d0dc266692d1bd4579fd9abd4a9b80f8d0ab5150Jes Sorensen (key_len > 16 ? 16 : key_len)); 816b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(padapter->securitypriv. 8175292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen dot118021XGrptxmickey[key_index]. 818e1343f90809ab29bd1ec286fef1d9e6fcc59b404Jes Sorensen skey, &keyparms->key[16], 8); 819b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(padapter->securitypriv. 8205292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen dot118021XGrprxmickey[key_index]. 821e1343f90809ab29bd1ec286fef1d9e6fcc59b404Jes Sorensen skey, &keyparms->key[24], 8); 822b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.binstallGrpkey = 8239216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen 1; 824b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A 825b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (" ~~~~set sta key:groupkey\n"); 826b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 827b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 8285292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen dot118021XGrpKeyid = key_index; 829b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 830b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_key23a(padapter, 831b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &padapter->securitypriv, 8325292a891979aab582cb66e5105fc2ab78ff2a070Jes Sorensen key_index, 1); 833b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 834b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 835b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 836b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter); 837b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pbcmc_sta) { 838b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Jeff: don't disable ieee8021x_blocked 839b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger while clearing key */ 840efd4216c2d558f2faf03284e95a9c1c1297d801aJes Sorensen if (keyparms->cipher != IW_AUTH_CIPHER_NONE && 841efd4216c2d558f2faf03284e95a9c1c1297d801aJes Sorensen keyparms->cipher != 0) 842b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->ieee8021x_blocked = false; 843b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 844b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((padapter->securitypriv.ndisencryptstatus == 845b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled) || 846b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->securitypriv.ndisencryptstatus == 847b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled)) { 848b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->dot118021XPrivacy = 849b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 850b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11PrivacyAlgrthm; 851b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 852b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 853b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */ 854b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 855b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 856b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 857b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 858b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 859b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ret =%d\n", __func__, ret); 860b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 861b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 862b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 863b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 864b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 865b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 866b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, 867b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 key_index, bool pairwise, 868b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *mac_addr, struct key_params *params) 869b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 8700996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen int set_tx, ret = 0; 871b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy); 872b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 873b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 874f88ab54c10b1270257f39268e88c1949fd903fb2Jes Sorensen u8 sta_addr[ETH_ALEN]; 875b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 876a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): adding key for %pM\n", __func__, ndev->name, 877b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mac_addr); 878b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("cipher = 0x%x\n", params->cipher); 879b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("key_len = 0x%x\n", params->key_len); 880b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("seq_len = 0x%x\n", params->seq_len); 881b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("key_index =%d\n", key_index); 882b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("pairwise =%d\n", pairwise); 883b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 884b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (params->cipher) { 885b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case IW_AUTH_CIPHER_NONE: 886b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP40: 8877ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen if (params->key_len != WLAN_KEY_LEN_WEP40) { 8887ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen ret = -EINVAL; 8897ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen goto exit; 8907ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen } 891b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP104: 8927ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen if (params->key_len != WLAN_KEY_LEN_WEP104) { 8937ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen ret = -EINVAL; 8947ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen goto exit; 8957ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen } 896b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_TKIP: 897b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_CCMP: 898b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 899b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 900b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOTSUPP; 901efd4216c2d558f2faf03284e95a9c1c1297d801aJes Sorensen goto exit; 902b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 903b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 9047ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen if (key_index >= WEP_KEYS || params->key_len < 0) { 9057ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen ret = -EINVAL; 9067ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen goto exit; 9077ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen } 9087ef2743da1bb1edcad5cdfafe75652445fa3cc1bJes Sorensen 909f88ab54c10b1270257f39268e88c1949fd903fb2Jes Sorensen eth_broadcast_addr(sta_addr); 910b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 9110996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen if (!mac_addr || is_broadcast_ether_addr(mac_addr)) 9120996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen set_tx = 0; /* for wpa/wpa2 group key */ 9130996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen else 9140996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen set_tx = 1; /* for wpa/wpa2 pairwise key */ 915b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 916b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 9170996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen ret = rtw_cfg80211_set_encryption(ndev, key_index, set_tx, 918f0bf8dd53d1a1c952784f1e5cf0c076cb514bdafJes Sorensen sta_addr, params); 919b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 920b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 921b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (mac_addr) 922f88ab54c10b1270257f39268e88c1949fd903fb2Jes Sorensen ether_addr_copy(sta_addr, mac_addr); 923b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 9240996cf9c693fd58d116619005ac1e1382865e0dbJes Sorensen ret = rtw_cfg80211_ap_set_encryption(ndev, key_index, set_tx, 925f0bf8dd53d1a1c952784f1e5cf0c076cb514bdafJes Sorensen sta_addr, params); 926b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 927b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 928b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("error! fw_state = 0x%x, iftype =%d\n", 929b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->fw_state, rtw_wdev->iftype); 930b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 931b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 932b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 933efd4216c2d558f2faf03284e95a9c1c1297d801aJes Sorensenexit: 934b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 935b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 936b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 937b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int 938b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingercfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev, 939b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 key_index, bool pairwise, const u8 *mac_addr, 940b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger void *cookie, 941b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger void (*callback) (void *cookie, struct key_params *)) 942b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 943a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 944b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 945b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 946b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 947b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev, 948b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 key_index, bool pairwise, 949b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *mac_addr) 950b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 951b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 952b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 953b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 954a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): key_index =%d\n", __func__, ndev->name, key_index); 955b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 956b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (key_index == psecuritypriv->dot11PrivacyKeyIndex) { 957b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* clear the flag of wep default key set. */ 958b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->bWepDefaultKeyIdxSet = 0; 959b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 960b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 961b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 962b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 963b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 964b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_default_key(struct wiphy *wiphy, 965b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, u8 key_index, 966b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool unicast, bool multicast) 967b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 968b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 969b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 970b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 971a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): key_index =%d, unicast =%d, multicast =%d.\n", 972a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, key_index, unicast, multicast); 973b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 974e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen if (key_index < NUM_WEP_KEYS && 975e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen (psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP40 || 976e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP104)) { 977b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set wep default key */ 978b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; 979b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 980b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyKeyIndex = key_index; 981b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 9829e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 9839e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40; 984e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen if (psecuritypriv->wep_key[key_index].keylen == 13) { 985e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = 986e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 987e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 988e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 989b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 990b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 991b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set the flag to represent that wep default key 992b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger has been set */ 993b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->bWepDefaultKeyIdxSet = 1; 994b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 995b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 996b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 997b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 998b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 99927fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensenstatic u16 rtw_get_cur_max_rate(struct rtw_adapter *adapter) 100027fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen{ 100127fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen int i = 0; 100227fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen const u8 *p; 100327fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen u16 rate = 0, max_rate = 0; 100427fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; 100527fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 100627fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen struct registry_priv *pregistrypriv = &adapter->registrypriv; 100727fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 100827fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; 100927fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen struct ieee80211_ht_cap *pht_capie; 101027fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen u8 rf_type = 0; 101127fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0; 101227fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen u16 mcs_rate = 0; 101327fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 10141d33b0766385957c0e70ff32ec501d1f775c8316Jes Sorensen p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, 10151de65ccb1f90be71cd7deb3c963f7440560e4325Jes Sorensen pcur_bss->IEs, pcur_bss->IELength); 101627fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen if (p && p[1] > 0) { 101727fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen pht_capie = (struct ieee80211_ht_cap *)(p + 2); 101827fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 101927fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen memcpy(&mcs_rate, &pht_capie->mcs, 2); 102027fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 102127fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen /* bw_40MHz = (pht_capie->cap_info& 102227fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1:0; */ 102327fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen /* cur_bwmod is updated by beacon, pmlmeinfo is 102427fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen updated by association response */ 102527fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen bw_40MHz = (pmlmeext->cur_bwmode && 102627fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen (pmlmeinfo->HT_info.ht_param & 102727fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) ? 1:0; 102827fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 102927fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen /* short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP 103027fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen _SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; */ 103127fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen short_GI_20 = (pmlmeinfo->ht_cap.cap_info & 103227fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen cpu_to_le16(IEEE80211_HT_CAP_SGI_20)) ? 1:0; 103327fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen short_GI_40 = (pmlmeinfo->ht_cap.cap_info & 103427fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) ? 1:0; 103527fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 103627fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen rf_type = rtl8723a_get_rf_type(adapter); 103727fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen max_rate = rtw_mcs_rate23a(rf_type, bw_40MHz & 103827fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen pregistrypriv->cbw40_enable, 103927fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen short_GI_20, short_GI_40, 104027fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen &pmlmeinfo->ht_cap.mcs); 104127fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen } else { 104227fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen while (pcur_bss->SupportedRates[i] != 0 && 104327fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen pcur_bss->SupportedRates[i] != 0xFF) { 104427fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen rate = pcur_bss->SupportedRates[i] & 0x7F; 104527fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen if (rate>max_rate) 104627fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen max_rate = rate; 104727fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen i++; 104827fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen } 104927fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 105027fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen max_rate = max_rate * 10 / 2; 105127fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen } 105227fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 105327fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen return max_rate; 105427fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen} 105527fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen 1056b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_get_station(struct wiphy *wiphy, 1057b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 1058f9da455b93f6ba076935b4ef4589f61e529ae046Linus Torvalds const u8 *mac, struct station_info *sinfo) 1059b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1060b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1061b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1062b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1063b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta = NULL; 1064b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 1065b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1066b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled = 0; 1067b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1068b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mac) { 1069a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): mac ==%p\n", __func__, ndev->name, mac); 1070b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 1071b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1072b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1073b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1074b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = rtw_get_stainfo23a(pstapriv, mac); 1075b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psta == NULL) { 1076b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, sta_info is null\n", __func__); 1077b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 1078b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1079b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1080a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): mac =" MAC_FMT "\n", __func__, ndev->name, 1081b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger MAC_ARG(mac)); 1082b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1083b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* for infra./P2PClient mode */ 1084b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && 1085b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, _FW_LINKED)) { 1086b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *cur_network = &pmlmepriv->cur_network; 1087b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1088cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen if (!ether_addr_equal(mac, cur_network->network.MacAddress)) { 1089b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, mismatch bssid =" MAC_FMT "\n", __func__, 1090b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger MAC_ARG(cur_network->network.MacAddress)); 1091b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 1092b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1093b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1094b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1095b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_SIGNAL; 1096b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv. 1097b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger signal_strength); 1098b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1099b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_TX_BITRATE; 110027fd731ece203c37f0a3708cafc95e9cead8cd2dJes Sorensen sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter); 1101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_RX_PACKETS; 1103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->rx_packets = sta_rx_data_pkts(psta); 1104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_TX_PACKETS; 1106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->tx_packets = psta->sta_stats.tx_pkts; 1107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* for Ad-Hoc/AP mode */ 1110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || 1111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 1112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, WIFI_AP_STATE)) && 1113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, _FW_LINKED) 1114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ) { 1115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* TODO: should acquire station info... */ 1116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1118b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 1119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 11221da2a44bf8615ab40e5d4f7408b873385b6beee0Rahul Gargstatic int cfg80211_infrastructure_mode(struct rtw_adapter *padapter, 1123efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen enum nl80211_iftype ifmode) 1124efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen{ 1125efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1126efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen struct wlan_network *cur_network = &pmlmepriv->cur_network; 1127efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen enum nl80211_iftype old_mode; 1128efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1129efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode = cur_network->network.ifmode; 1130efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1131efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, 1132efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen ("+%s: old =%d new =%d fw_state = 0x%08x\n", __func__, 1133efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode, ifmode, get_fwstate(pmlmepriv))); 1134efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1135efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (old_mode != ifmode) { 1136efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen spin_lock_bh(&pmlmepriv->lock); 1137efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1138efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 1139efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen (" change mode!")); 1140efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1141efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (old_mode == NL80211_IFTYPE_AP || 1142efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_P2P_GO) { 1143efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* change to other mode from Ndis802_11APMode */ 1144efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen cur_network->join_res = -1; 1145efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1146efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#ifdef CONFIG_8723AU_AP_MODE 1147efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen stop_ap_mode23a(padapter); 1148efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#endif 1149efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1150efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1151efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED) || 1152efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_ADHOC) 1153efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_disassoc_cmd23a(padapter, 0, true); 1154efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1155efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED) || 1156efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) 1157efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_free_assoc_resources23a(padapter, 1); 1158efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1159efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (old_mode == NL80211_IFTYPE_STATION || 1160efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_P2P_CLIENT || 1161efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_ADHOC) { 1162efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1163efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* will clr Linked_state; before this function, 1164efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen we must have chked whether issue 1165efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen dis-assoc_cmd or not */ 1166efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_indicate_disconnect23a(padapter); 1167efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1168efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1169efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1170efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen cur_network->network.ifmode = ifmode; 1171efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1172efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE); 1173efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1174efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen switch (ifmode) { 1175efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_ADHOC: 1176efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 1177efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1178efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1179efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_P2P_CLIENT: 1180efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_STATION: 1181efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen set_fwstate(pmlmepriv, WIFI_STATION_STATE); 1182efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1183efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1184efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_P2P_GO: 1185efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_AP: 1186efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen set_fwstate(pmlmepriv, WIFI_AP_STATE); 1187efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#ifdef CONFIG_8723AU_AP_MODE 1188efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen start_ap_mode23a(padapter); 1189efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* rtw_indicate_connect23a(padapter); */ 1190efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#endif 1191efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1192efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1193efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen default: 1194efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1195efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1196efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1197efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* SecClearAllKeys(adapter); */ 1198efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1199efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* RT_TRACE(COMP_OID_SET, DBG_LOUD, 1200efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen ("set_infrastructure: fw_state:%x after changing mode\n", */ 1201efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* get_fwstate(pmlmepriv))); */ 1202efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1203efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen spin_unlock_bh(&pmlmepriv->lock); 1204efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1205efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1206efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen return _SUCCESS; 1207efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen} 1208efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1209b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_iface(struct wiphy *wiphy, 1210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 1211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_iftype type, u32 *flags, 1212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct vif_params *params) 1213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_iftype old_type; 1215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy); 1218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1220a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): call netdev_open23a\n", __func__, ndev->name); 1221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger old_type = rtw_wdev->iftype; 1223a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): old_iftype =%d, new_iftype =%d\n", 1224a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, old_type, type); 1225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (old_type != type) { 1227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->action_public_rxseq = 0xffff; 1228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->action_public_dialog_token = 0xff; 1229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1230b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (type) { 1232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_ADHOC: 1233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_CLIENT: 1234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_STATION: 1235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_GO: 1236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_AP: 1237efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_UNSPECIFIED: 1238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 1240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EOPNOTSUPP; 1241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev->iftype = type; 1244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1245efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (cfg80211_infrastructure_mode(padapter, type) != _SUCCESS) { 1246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev->iftype = old_type; 1247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 1248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1249b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1251efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_setopmode_cmd23a(padapter, type); 1252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1253b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 1254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1257b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, 1258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool aborted) 1259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pwdev_priv->scan_req_lock); 1261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->scan_request != NULL) { 1262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s with scan req\n", __func__); 1263141bd353c5a9ba987dbe7b28ffdd034bb3ed55baJes Sorensen 1264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->scan_request->wiphy != 1265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->rtw_wdev->wiphy) 1266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("error wiphy compare\n"); 1267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 1268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_scan_done(pwdev_priv->scan_request, aborted); 1269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->scan_request = NULL; 1271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 1272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s without scan req\n", __func__); 1273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pwdev_priv->scan_req_lock); 1275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1277b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_surveydone_event_callback(struct rtw_adapter *padapter) 1278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct list_head *plist, *phead, *ptmp; 1280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1281b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_queue *queue = &pmlmepriv->scanned_queue; 1282b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *pnetwork; 1283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pmlmepriv->scanned_queue.lock); 1285b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1286b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phead = get_list_head(queue); 1287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_for_each_safe(plist, ptmp, phead) { 1289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork = container_of(plist, struct wlan_network, list); 1290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* report network only if the current channel set 1292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger contains the channel to which this network belongs */ 1293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_ch_set_search_ch23a 1294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->mlmeextpriv.channel_set, 129537cb982c2685029e716bfeccf55ec244a6919a32Jes Sorensen pnetwork->network.DSConfig) >= 0) 1296b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_inform_bss(padapter, pnetwork); 1297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1299b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* call this after other things have been done */ 1302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), 1303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger false); 1304b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1306b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter, 1307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger char *buf, int len) 1308b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1310d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen const u8 *wps_ie; 1311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ielen =%d\n", __func__, len); 1314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (len > 0) { 1316d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 1317d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen WLAN_OUI_TYPE_MICROSOFT_WPS, 1318d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen buf, len); 1319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wps_ie) { 1320d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen DBG_8723A("probe_req_wps_ielen =%d\n", wps_ie[1]); 1321141bd353c5a9ba987dbe7b28ffdd034bb3ed55baJes Sorensen 1322b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_probe_req_ie) { 1323b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_req_ie_len = 0; 1324b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pmlmepriv->wps_probe_req_ie); 1325b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_req_ie = NULL; 1326b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1328d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen pmlmepriv->wps_probe_req_ie = kmemdup(wps_ie, wps_ie[1], 13294a6eea4dcbc0328c3126fed264c42b0725bea659Benoit Taine GFP_KERNEL); 1330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_probe_req_ie == NULL) { 1331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s()-%d: kmalloc() ERROR!\n", 1332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, __LINE__); 1333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 1334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1335d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen pmlmepriv->wps_probe_req_ie_len = wps_ie[1]; 1336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1337b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1342b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_scan(struct wiphy *wiphy, 1343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_scan_request *request) 1344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int i; 1346b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 _status = false; 1347b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT]; 1351b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; 1352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); 1353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ssid *ssids = request->ssids; 1354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool need_indicate_scan_done = false; 1355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1356a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name); 1357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pwdev_priv->scan_req_lock); 1359b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->scan_request = request; 1360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pwdev_priv->scan_req_lock); 1361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s under WIFI_AP_STATE\n", __func__); 1364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* need_indicate_scan_done = true; */ 1365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* goto check_need_indicate_scan_done; */ 1366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_pwr_wakeup(padapter) == _FAIL) { 1369b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1370b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (request->ie && request->ie_len > 0) { 1374b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_set_probe_req_wpsp2pie(padapter, 1375b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (u8 *) request->ie, 1376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger request->ie_len); 1377b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1378b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1379b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) { 1380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, bBusyTraffic == true\n", __func__); 1381b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1382b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1383b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_is_scan_deny(padapter)) { 13859cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): scan deny\n", __func__, 13869cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name); 1387b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == 1392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true) { 1393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state); 1394b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(ssid, 0, sizeof(struct cfg80211_ssid) * RTW_SSID_SCAN_AMOUNT); 1399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* parsing request ssids, n_ssids */ 1400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) { 1401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid, 1402b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ssids[i].ssid_len); 1403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len); 1404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ssid[i].ssid_len = ssids[i].ssid_len; 1405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* parsing channels, n_channels */ 1408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(ch, 0, 1409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT); 1410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (request->n_channels == 1) { 1412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < request->n_channels && 1413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger i < RTW_CHANNEL_SCAN_AMOUNT; i++) { 14149cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s:(%s):" CHAN_FMT "\n", 14159cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen __func__, padapter->pnetdev->name, 1416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN_ARG(request->channels[i])); 1417b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ch[i].hw_value = request->channels[i]->hw_value; 1418b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ch[i].flags = request->channels[i]->flags; 1419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1421b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pmlmepriv->lock); 1423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (request->n_channels == 1) { 1424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel)); 1425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel)); 1426b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _status = rtw_sitesurvey_cmd23a(padapter, ssid, 1427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_SSID_SCAN_AMOUNT, ch, 3); 1428b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 1429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _status = rtw_sitesurvey_cmd23a(padapter, ssid, 1430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_SSID_SCAN_AMOUNT, NULL, 0); 1431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pmlmepriv->lock); 1433b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1434b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (_status == false) 1435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -1; 1436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1437b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingercheck_need_indicate_scan_done: 1438b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (need_indicate_scan_done) 1439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_surveydone_event_callback(padapter); 1440b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1443b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 1446b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1449b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev, 1450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ibss_params *params) 1451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1452a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 1453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1456b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) 1457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1458a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 1459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1460b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1462b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, 1463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 wpa_version) 1464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, wpa_version =%d\n", __func__, wpa_version); 1466b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wpa_version) { 1468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; 1469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1472b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) { 1473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK; 1474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/* 1477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wpa_version & NL80211_WPA_VERSION_2) 1478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 1479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; 1480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger*/ 1482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1483b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1484b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1486b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, 1487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_auth_type sme_auth_type) 1488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type); 1490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (sme_auth_type) { 1492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_AUTHTYPE_AUTOMATIC: 1493b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; 1494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_AUTHTYPE_OPEN_SYSTEM: 1497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 1498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA) 1500b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = 1501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X; 1502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_AUTHTYPE_SHARED_KEY: 1504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; 1505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; 1507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1508b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 1509b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 1510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* return -ENOTSUPP; */ 1511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1512b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1514b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1515b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1516b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, 1517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 cipher, bool ucast) 1518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1519b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 ndisencryptstatus = Ndis802_11EncryptionDisabled; 1520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm : 1522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &psecuritypriv->dot118021XGrpPrivacy; 1523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1524b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher); 1525b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!cipher) { 15279e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = 0; 1528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = ndisencryptstatus; 1529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1531b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (cipher) { 1533b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case IW_AUTH_CIPHER_NONE: 15349e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = 0; 1535b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11EncryptionDisabled; 1536b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP40: 15389e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_WEP40; 1539b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption1Enabled; 1540b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1541b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP104: 15429e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_WEP104; 1543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption1Enabled; 1544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1545b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_TKIP: 15469e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_TKIP; 1547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption2Enabled; 1548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_CCMP: 15509e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_CCMP; 1551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption3Enabled; 1552b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 1554b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Unsupported cipher: 0x%x\n", cipher); 1555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -ENOTSUPP; 1556b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ucast) 1559b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = ndisencryptstatus; 1560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1562b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1564b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, 1565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 key_mgt) 1566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1567b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, key_mgt = 0x%x\n", __func__, key_mgt); 1568b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (key_mgt == WLAN_AKM_SUITE_8021X) 1570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 1571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else if (key_mgt == WLAN_AKM_SUITE_PSK) 1572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 1573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 1574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt); 1575b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1578b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1579b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie, 1580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t ielen) 1581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1582d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen const u8 *wps_ie; 1583b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int group_cipher = 0, pairwise_cipher = 0; 1584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 158558aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen const u8 *pwpa, *pwpa2; 1586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int i; 1587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pie || !ielen) { 1589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Treat this as normal case, but need to clear 1590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WIFI_UNDER_WPS */ 1591b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 1592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) { 1595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 1596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1597b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* dump */ 1600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("set wpa_ie(length:%zu):\n", ielen); 1601b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < ielen; i = i + 8) 16027579a7e47d6572455c48f822dd47bd1993ec9d95Jes Sorensen DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x " 16037579a7e47d6572455c48f822dd47bd1993ec9d95Jes Sorensen "0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", 16047579a7e47d6572455c48f822dd47bd1993ec9d95Jes Sorensen pie[i], pie[i + 1], pie[i + 2], pie[i + 3], 16057579a7e47d6572455c48f822dd47bd1993ec9d95Jes Sorensen pie[i + 4], pie[i + 5], pie[i + 6], pie[i + 7]); 1606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ielen < RSN_HEADER_LEN) { 1607b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, 1608b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("Ie len too short %d\n", (int)ielen)); 1609b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -1; 1610b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 161358aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen pwpa = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 161458aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen WLAN_OUI_TYPE_MICROSOFT_WPA, 16157579a7e47d6572455c48f822dd47bd1993ec9d95Jes Sorensen pie, ielen); 161658aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (pwpa && pwpa[1] > 0) { 161758aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (rtw_parse_wpa_ie23a(pwpa, pwpa[1] + 2, &group_cipher, 161858aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen &pairwise_cipher, NULL) == _SUCCESS) { 1619b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.dot11AuthAlgrthm = 1620b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X; 1621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisauthtype = 1622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11AuthModeWPAPSK; 162358aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen memcpy(padapter->securitypriv.supplicant_ie, pwpa, 162458aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen pwpa[1] + 2); 1625b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 162658aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen DBG_8723A("got wpa_ie, wpa_ielen:%u\n", pwpa[1]); 1627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1628b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16307579a7e47d6572455c48f822dd47bd1993ec9d95Jes Sorensen pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, pie, ielen); 163158aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (pwpa2 && pwpa2[1] > 0) { 163258aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (rtw_parse_wpa2_ie23a (pwpa2, pwpa2[1] + 2, &group_cipher, 163358aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen &pairwise_cipher, NULL) == _SUCCESS) { 1634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.dot11AuthAlgrthm = 1635b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X; 1636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisauthtype = 1637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11AuthModeWPA2PSK; 163858aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen memcpy(padapter->securitypriv.supplicant_ie, pwpa2, 163958aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen pwpa2[1] + 2); 1640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 164158aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", pwpa2[1]); 1642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1645b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (group_cipher == 0) { 1646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger group_cipher = WPA_CIPHER_NONE; 1647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1648b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pairwise_cipher == 0) { 1649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pairwise_cipher = WPA_CIPHER_NONE; 1650b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1652b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (group_cipher) { 1653b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_NONE: 16549e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = 0; 1655b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11EncryptionDisabled; 1657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP40: 16599e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40; 1660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1661b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1662b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1663b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_TKIP: 16649e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP; 1665b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1666b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled; 1667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_CCMP: 16699e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP; 1670b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1671b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled; 1672b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP104: 16749e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104; 1675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1677b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1680b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (pairwise_cipher) { 1681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_NONE: 16829e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = 0; 1683b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1684b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11EncryptionDisabled; 1685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1686b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP40: 16879e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 1688b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1691b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_TKIP: 16929e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_TKIP; 1693b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1694b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled; 1695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_CCMP: 16979e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_CCMP; 1698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1699b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled; 1700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1701b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP104: 17029e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104; 1703b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1704b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1708d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 1709d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen WLAN_OUI_TYPE_MICROSOFT_WPS, 17107579a7e47d6572455c48f822dd47bd1993ec9d95Jes Sorensen pie, ielen); 1711d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen if (wps_ie && wps_ie[1] > 0) { 1712d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ie[1]); 1713d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen padapter->securitypriv.wps_ie_len = wps_ie[1]; 1714d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen memcpy(padapter->securitypriv.wps_ie, wps_ie, 1715d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen padapter->securitypriv.wps_ie_len); 1716d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); 1717d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen } else { 1718d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 1719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* TKIP and AES disallow multicast packets until installing group key */ 17229e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen if (padapter->securitypriv.dot11PrivacyAlgrthm == 17239e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_TKIP || 17249e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm == 17259e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_CCMP) 1726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* WPS open need to enable multicast */ 1727b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/ 1728763b4247cafdb978630d4da7ff48c8113c7d961eJes Sorensen rtl8723a_off_rcr_am(padapter); 1729b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1730b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 1731b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->" 1732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "securitypriv.ndisencryptstatus =%d padapter->" 1733b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "securitypriv.ndisauthtype =%d\n", pairwise_cipher, 1734b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus, 1735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisauthtype)); 1736b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1737b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 1738b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret) 1739b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 1740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1741b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1742b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 17436893c8ebba521ea9d0f1cc4a53233fcb09271d52Jes Sorensenstatic int rtw_cfg80211_add_wep(struct rtw_adapter *padapter, 1744deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen struct rtw_wep_key *wep, u8 keyid) 17451e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen{ 1746deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen int res; 17471e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen struct security_priv *psecuritypriv = &padapter->securitypriv; 17481e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 1749deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (keyid >= NUM_WEP_KEYS) { 17501e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, 17511e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:keyid>4 =>fail\n", __func__)); 17521e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen res = _FAIL; 17531e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen goto exit; 17541e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen } 17551e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 1756deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen switch (wep->keylen) { 17574d9c63bbd207b20ae648bd6bd3ebcf6e52619616Jes Sorensen case WLAN_KEY_LEN_WEP40: 17581e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 17591e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 17601e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:wep->KeyLength = 5\n", __func__)); 17611e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen break; 17624d9c63bbd207b20ae648bd6bd3ebcf6e52619616Jes Sorensen case WLAN_KEY_LEN_WEP104: 17631e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104; 17641e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 17651e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:wep->KeyLength = 13\n", __func__)); 17661e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen break; 17671e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen default: 17681e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = 0; 17691e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 17701e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:wep->KeyLength!= 5 or 13\n", __func__)); 17711e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen res = _FAIL; 17721e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen goto exit; 17731e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen } 17741e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 17751e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 1776deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen ("%s:before memcpy, wep->KeyLength = 0x%x keyid =%x\n", 1777deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen __func__, wep->keylen, keyid)); 17781e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 1779deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen memcpy(&psecuritypriv->wep_key[keyid], wep, sizeof(struct rtw_wep_key)); 17801e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 17811e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyKeyIndex = keyid; 17821e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 17831e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 17841e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:security key material : " 17851e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen "%x %x %x %x %x %x %x %x %x %x %x %x %x\n", __func__, 17861e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[0], 17871e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[1], 17881e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[2], 17891e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[3], 17901e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[4], 17911e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[5], 17921e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[6], 17931e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[7], 17941e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[8], 17951e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[9], 17961e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[10], 17971e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[11], 17981e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[12])); 17991e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 18001e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen res = rtw_set_key23a(padapter, psecuritypriv, keyid, 1); 18011e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 18021e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensenexit: 18031e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 18041e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen return res; 18051e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen} 18061e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 1807e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensenstatic int rtw_set_ssid(struct rtw_adapter *padapter, 1808e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen struct wlan_network *newnetwork) 180997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen{ 181097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 181197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen struct wlan_network *pnetwork = &pmlmepriv->cur_network; 181297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen int status = _SUCCESS; 181397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen u32 cur_time = 0; 181497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 181597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n", 1816e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen newnetwork->network.Ssid.ssid, get_fwstate(pmlmepriv)); 181797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 181897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (padapter->hw_init_completed == false) { 181997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, 182097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen ("set_ssid: hw_init_completed == false =>exit!!!\n")); 182197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen status = _FAIL; 182297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen goto exit; 182397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 182497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 182597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen spin_lock_bh(&pmlmepriv->lock); 182697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 182797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen DBG_8723A("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv)); 182897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) 182997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen goto handle_tkip_countermeasure; 183097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 183197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) { 183297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 183397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); 183497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 1835e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen if (pmlmepriv->assoc_ssid.ssid_len == 1836e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen newnetwork->network.Ssid.ssid_len && 1837e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen !memcmp(&pmlmepriv->assoc_ssid.ssid, 1838e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen newnetwork->network.Ssid.ssid, 1839e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen newnetwork->network.Ssid.ssid_len)) { 184097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 184197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, 184297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen _drv_err_, ("New SSID is same SSID, " 184397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen "fw_state = 0x%08x\n", 184497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen get_fwstate(pmlmepriv))); 184597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 184697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (rtw_is_same_ibss23a(padapter, pnetwork)) { 184797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen /* 184897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen * it means driver is in 184997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen * WIFI_ADHOC_MASTER_STATE, we needn't 185097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen * create bss again. 185197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen */ 185297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen goto release_mlme_lock; 185397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 185497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 185597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen /* 185697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen * if in WIFI_ADHOC_MASTER_STATE | 185797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen * WIFI_ADHOC_STATE, create bss or 185897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen * rejoin again 185997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen */ 186097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen rtw_disassoc_cmd23a(padapter, 0, true); 186197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 186297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED)) 186397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen rtw_indicate_disconnect23a(padapter); 186497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 186597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen rtw_free_assoc_resources23a(padapter, 1); 186697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 186797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (check_fwstate(pmlmepriv, 186897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen WIFI_ADHOC_MASTER_STATE)) { 186997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen _clr_fwstate_(pmlmepriv, 187097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen WIFI_ADHOC_MASTER_STATE); 187197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen set_fwstate(pmlmepriv, 187297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen WIFI_ADHOC_STATE); 187397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 187497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } else { 187597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen rtw_lps_ctrl_wk_cmd23a(padapter, 187697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen LPS_CTRL_JOINBSS, 1); 187797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 187897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } else { 187997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 188097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen ("Set SSID not the same ssid\n")); 188197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 1882e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen ("set_ssid =[%s] len = 0x%x\n", 1883e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen newnetwork->network.Ssid.ssid, 1884e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen newnetwork->network.Ssid.ssid_len)); 188597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 188697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen ("assoc_ssid =[%s] len = 0x%x\n", 188797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen pmlmepriv->assoc_ssid.ssid, 188897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen pmlmepriv->assoc_ssid.ssid_len)); 188997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 189097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen rtw_disassoc_cmd23a(padapter, 0, true); 189197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 189297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED)) 189397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen rtw_indicate_disconnect23a(padapter); 189497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 189597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen rtw_free_assoc_resources23a(padapter, 1); 189697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 189797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 189897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); 189997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 190097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 190197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 190297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 190397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 190497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensenhandle_tkip_countermeasure: 190597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 190697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if (padapter->securitypriv.btkip_countermeasure == true) { 190797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen cur_time = jiffies; 190897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 190997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen if ((cur_time - 191097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen padapter->securitypriv.btkip_countermeasure_time) > 191197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 60 * HZ) { 191297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen padapter->securitypriv.btkip_countermeasure = false; 191397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen padapter->securitypriv.btkip_countermeasure_time = 0; 191497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } else { 191597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen status = _FAIL; 191697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen goto release_mlme_lock; 191797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 191897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen } 191997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 1920e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen memcpy(&pmlmepriv->assoc_ssid, &newnetwork->network.Ssid, 1921e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen sizeof(struct cfg80211_ssid)); 1922e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen 192397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen pmlmepriv->assoc_by_bssid = false; 192497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 192572795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen pmlmepriv->to_join = true; 192672795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen 192772795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen if (!check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { 192872795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen pmlmepriv->cur_network.join_res = -2; 192997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 193072795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen status = rtw_do_join_network(padapter, newnetwork); 193172795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen if (status == _SUCCESS) { 193272795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen pmlmepriv->to_join = false; 193372795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen } else { 193472795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { 193572795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen /* switch to ADHOC_MASTER */ 193672795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen status = rtw_do_join_adhoc(padapter); 193772795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen if (status != _SUCCESS) 193872795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen goto release_mlme_lock; 193972795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen } else { 194072795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen /* can't associate ; reset under-linking */ 194172795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 194272795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen status = _FAIL; 194372795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen pmlmepriv->to_join = false; 194472795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen } 194572795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen } 194672795e9de7deae0952d1174cfb37cb869b582d29Jes Sorensen } 194797c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensenrelease_mlme_lock: 194897c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen spin_unlock_bh(&pmlmepriv->lock); 194997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 195097c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensenexit: 195197c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, 195297c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen ("-%s: status =%d\n", __func__, status)); 195397c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 195497c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen return status; 195597c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen} 195697c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen 1957b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, 1958b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_connect_params *sme) 1959b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1960b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1961b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct list_head *phead, *plist, *ptmp; 1962b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *pnetwork = NULL; 1963b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* u8 matched_by_bssid = false; */ 1964b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* u8 matched_by_ssid = false; */ 1965b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 matched = false; 1966b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1967b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1968b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 1969b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_queue *queue = &pmlmepriv->scanned_queue; 1970b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1971a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("=>" "%s(%s)\n", __func__, ndev->name); 1972b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("privacy =%d, key =%p, key_len =%d, key_idx =%d\n", 1973b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->privacy, sme->key, sme->key_len, sme->key_idx); 1974b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1975b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (_FAIL == rtw_pwr_wakeup(padapter)) { 1976b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 1977b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1978b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1979b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1980b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1981b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 1982b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1983b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1984b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1985c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen if (!sme->ssid || !sme->ssid_len || 1986c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen sme->ssid_len > IEEE80211_MAX_SSID_LEN) { 1987b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 1988b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1989b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1990b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1991c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen DBG_8723A("ssid =%s, len =%zu\n", sme->ssid, sme->ssid_len); 1992b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1993b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->bssid) 1994b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bssid =" MAC_FMT "\n", MAC_ARG(sme->bssid)); 1995b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1996b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 1997b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EBUSY; 1998b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, fw_state = 0x%x, goto exit\n", __func__, 1999b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->fw_state); 2000b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2001b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2002b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { 2003b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_scan_abort23a(padapter); 2004b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2005b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2006b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&queue->lock); 2007b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2008b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phead = get_list_head(queue); 2009b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2010b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_for_each_safe(plist, ptmp, phead) { 2011b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork = container_of(plist, struct wlan_network, list); 2012b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2013b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->bssid) { 2014cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen if (!ether_addr_equal(pnetwork->network.MacAddress, 2015cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen sme->bssid)) 2016b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger continue; 2017b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2018b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2019b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->ssid && sme->ssid_len) { 2020b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetwork->network.Ssid.ssid_len != sme->ssid_len || 2021b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcmp(pnetwork->network.Ssid.ssid, sme->ssid, 2022b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->ssid_len)) 2023b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger continue; 2024b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2025b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2026b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->bssid) { 20279ab98d42401d50d6ab5f6ef59e1d63c486391f1cJes Sorensen if (ether_addr_equal(pnetwork->network.MacAddress, 20289ab98d42401d50d6ab5f6ef59e1d63c486391f1cJes Sorensen sme->bssid)) { 2029b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("matched by bssid\n"); 2030b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2031b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger matched = true; 2032b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2033b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2034b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (sme->ssid && sme->ssid_len) { 20359ab98d42401d50d6ab5f6ef59e1d63c486391f1cJes Sorensen if (!memcmp(pnetwork->network.Ssid.ssid, 20369ab98d42401d50d6ab5f6ef59e1d63c486391f1cJes Sorensen sme->ssid, sme->ssid_len) && 2037c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen pnetwork->network.Ssid.ssid_len == sme->ssid_len) { 2038b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("matched by ssid\n"); 2039c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen 2040b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger matched = true; 2041b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2042b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2043b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2044b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2045b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2046b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&queue->lock); 2047b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2048c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen if (!matched || !pnetwork) { 2049b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 2050b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("connect, matched == false, goto exit\n"); 2051b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2052b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2053b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2054efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (cfg80211_infrastructure_mode( 2055efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen padapter, pnetwork->network.ifmode) != _SUCCESS) { 2056b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 2057b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2058b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2059b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2060b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; 20619e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = 0; 20629e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = 0; 2063b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 2064b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; 2065b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2066c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen ret = rtw_cfg80211_set_wpa_version(psecuritypriv, 2067c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen sme->crypto.wpa_versions); 2068b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2069b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2070b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2071b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type); 2072b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2073b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2074b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2075b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2076b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ie_len =%zu\n", __func__, sme->ie_len); 2077b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2078b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len); 2079b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2080b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2081b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2082b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->crypto.n_ciphers_pairwise) { 2083b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_cipher(psecuritypriv, 2084b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->crypto.ciphers_pairwise[0], 2085b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true); 2086b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2087b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2088b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2089b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2090b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* For WEP Shared auth */ 2091b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared || 2092b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && 2093b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->key) { 2094deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen struct rtw_wep_key wep_key; 2095deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen u8 wep_key_idx, wep_key_len; 2096b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(): Shared/Auto WEP\n", __func__); 2097b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2098b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_idx = sme->key_idx; 2099b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_len = sme->key_len; 2100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2101deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (wep_key_idx > WEP_KEYS || !wep_key_len || 2102deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen wep_key_len > WLAN_KEY_LEN_WEP104) { 2103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 2104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2107deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen wep_key_len = wep_key_len <= 5 ? 5 : 13; 2108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2109deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen memset(&wep_key, 0, sizeof(struct rtw_wep_key)); 2110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2111deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen wep_key.keylen = wep_key_len; 2112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2113deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (wep_key_len == 13) { 2114deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = 2115deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 2116deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = 2117deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 2118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 2119deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = 2120deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP40; 2121deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = 2122deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP40; 2123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2125deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen memcpy(wep_key.key, (void *)sme->key, wep_key.keylen); 2126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2127deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (rtw_cfg80211_add_wep(padapter, &wep_key, wep_key_idx) != 2128deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen _SUCCESS) 2129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EOPNOTSUPP; 2130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2131b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2133b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_cipher(psecuritypriv, 2136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->crypto.cipher_group, false); 2137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2138c5178b0bc2ea2e72d45a90ae346a9b2fda0b5f08Jes Sorensen goto exit; 2139b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->crypto.n_akm_suites) { 2141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_key_mgt(psecuritypriv, 2142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->crypto.akm_suites[0]); 2143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 214739dbc446a7168e4d7542d6523132ee44189d0ba2Jes Sorensen if (psecuritypriv->ndisauthtype > 3) 214839dbc446a7168e4d7542d6523132ee44189d0ba2Jes Sorensen psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 214939dbc446a7168e4d7542d6523132ee44189d0ba2Jes Sorensen 215039dbc446a7168e4d7542d6523132ee44189d0ba2Jes Sorensen if (rtw_set_auth23a(padapter, psecuritypriv) != _SUCCESS) { 215139dbc446a7168e4d7542d6523132ee44189d0ba2Jes Sorensen ret = -EBUSY; 215239dbc446a7168e4d7542d6523132ee44189d0ba2Jes Sorensen goto exit; 215339dbc446a7168e4d7542d6523132ee44189d0ba2Jes Sorensen } 2154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* rtw_set_802_11_encryption_mode(padapter, 2156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus); */ 2157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2158e73d82efa4583e5ecaf598d85341403806a16e62Jes Sorensen if (rtw_set_ssid(padapter, pnetwork) != _SUCCESS) { 215997c4361d50e833a0c178cf425590a15e9663f3d0Jes Sorensen ret = -EBUSY; 2160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, " 2164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm, 2165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyAlgrthm, 2166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy); 2167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2168b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 2169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=%s, ret %d\n", __func__, ret); 2171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2172b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2175b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, 2176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 reason_code) 2177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2178b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2180a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_roaming(padapter, 0); 2183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { 2185b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_scan_abort23a(padapter); 2186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 2187b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(padapter, 500, false); 2188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2189b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s...call rtw_indicate_disconnect23a\n", __func__); 2190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->mlmepriv.not_indic_disco = true; 2192b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_indicate_disconnect23a(padapter); 2193b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->mlmepriv.not_indic_disco = false; 2194b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2195b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_assoc_resources23a(padapter, 1); 2196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2197b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2198b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2200b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2201b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_txpower(struct wiphy *wiphy, 2202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev, 2203b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_tx_power_setting type, int mbm) 2204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2205b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2206b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2209b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_get_txpower(struct wiphy *wiphy, 2210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev, int *dbm) 2211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *dbm = (12); 2214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2217b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerinline bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter) 2218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev); 2220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return rtw_wdev_priv->power_mgmt; 2221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2223b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, 2224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 2225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool enabled, int timeout) 2226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev); 2229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2230a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): enabled:%u, timeout:%d\n", 2231a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, enabled, timeout); 2232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_priv->power_mgmt = enabled; 2234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!enabled) 2236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LPS_Leave23a(padapter); 2237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2241b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, 2242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *netdev, 2243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_pmksa *pmksa) 2244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 index, blInserted = false; 2246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 2248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2249a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, netdev->name); 2250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2251cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen if (is_zero_ether_addr(pmksa->bssid)) 2252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger blInserted = false; 2255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* overwrite PMKID */ 2257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (index = 0; index < NUM_PMKID_CACHE; index++) { 2258cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid, 2259cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen pmksa->bssid)) { 2260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* BSSID is matched, the same AP => rewrite with 2261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger new PMKID. */ 2262a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): BSSID exists in the PMKList.\n", 2263a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, netdev->name); 2264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv->PMKIDList[index].PMKID, 2266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmksa->pmkid, WLAN_PMKID_LEN); 2267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDList[index].bUsed = true; 2268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex = index + 1; 2269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger blInserted = true; 2270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!blInserted) { 2275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Find a new entry */ 2276a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): Use new entry index = %d for this PMKID\n", 2277a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, netdev->name, psecuritypriv->PMKIDIndex); 2278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2279888df442ef023adbca6536888eae65b2cd8ae295Jes Sorensen ether_addr_copy( 2280888df442ef023adbca6536888eae65b2cd8ae295Jes Sorensen psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex]. 2281888df442ef023adbca6536888eae65b2cd8ae295Jes Sorensen Bssid, pmksa->bssid); 2282b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex]. 2283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger PMKID, pmksa->pmkid, WLAN_PMKID_LEN); 2284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2285b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = 2286b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true; 2287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex++; 2288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->PMKIDIndex == 16) { 2289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex = 0; 2290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2296b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_pmksa(struct wiphy *wiphy, 2297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *netdev, 2298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_pmksa *pmksa) 2299b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 index, bMatched = false; 2301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 2303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2304a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, netdev->name); 2305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (index = 0; index < NUM_PMKID_CACHE; index++) { 2307cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid, 2308cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen pmksa->bssid)) { 2309cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen /* BSSID is matched, the same AP => Remove this PMKID 2310cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen information and reset it. */ 231143c34be13047dd53e70bc4759ff314424db7036bJes Sorensen eth_zero_addr(psecuritypriv->PMKIDList[index].Bssid); 2312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, 2313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_PMKID_LEN); 2314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDList[index].bUsed = false; 2315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bMatched = true; 2316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2320b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (false == bMatched) { 2321a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): do not have matched BSSID\n", __func__, 2322a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen netdev->name); 2323b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2324b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2325b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2326b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2328b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2329b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy, 2330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *netdev) 2331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 2334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2335a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, netdev->name); 2336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2337b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(&psecuritypriv->PMKIDList[0], 0x00, 2338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); 2339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex = 0; 2340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2342b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 2345b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter, 2346b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *pmgmt_frame, uint frame_len) 2347b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 freq; 2349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int channel; 2350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2351b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev = padapter->pnetdev; 2352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name); 2354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#if defined(RTW_USE_CFG80211_STA_EVENT) 2356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 2357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_info sinfo; 2358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 ie_offset; 235960e78f3df4f5b9bc3fd61755fd00e69c4923ac1dJes Sorensen 2360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_is_assoc_req(hdr->frame_control)) 236160e78f3df4f5b9bc3fd61755fd00e69c4923ac1dJes Sorensen ie_offset = offsetof(struct ieee80211_mgmt, 236260e78f3df4f5b9bc3fd61755fd00e69c4923ac1dJes Sorensen u.assoc_req.variable); 2363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else /* WIFI_REASSOCREQ */ 236460e78f3df4f5b9bc3fd61755fd00e69c4923ac1dJes Sorensen ie_offset = offsetof(struct ieee80211_mgmt, 236560e78f3df4f5b9bc3fd61755fd00e69c4923ac1dJes Sorensen u.reassoc_req.variable); 2366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo.filled = 0; 2368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo.filled = STATION_INFO_ASSOC_REQ_IES; 236960e78f3df4f5b9bc3fd61755fd00e69c4923ac1dJes Sorensen sinfo.assoc_req_ies = pmgmt_frame + ie_offset; 237060e78f3df4f5b9bc3fd61755fd00e69c4923ac1dJes Sorensen sinfo.assoc_req_ies_len = frame_len - ie_offset; 2371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC); 2372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2374b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = pmlmeext->cur_channel; 2375b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 2376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2377b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 2378b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 2379b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 2381b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 238256b0bd91e0087e0b172aec022bdfb4fcd9de9194Jes Sorensen cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pmgmt_frame, frame_len, 2383970fdfa89babb5a6f1a3d345e8cb54d92c1e3a8fVladimir Kondratiev 0); 2384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2385b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2387b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter, 2388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *da, 2389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned short reason) 2390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 freq; 2392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int channel; 2393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint frame_len; 2394cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen struct ieee80211_mgmt mgmt; 2395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 2397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev = padapter->pnetdev; 2398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name); 2400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2401cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen memset(&mgmt, 0, sizeof(struct ieee80211_mgmt)); 24021daffaeecb4bf01c4a34fc2330c745ace5af3f60Jes Sorensen 2403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#if defined(RTW_USE_CFG80211_STA_EVENT) 2404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_del_sta(ndev, da, GFP_ATOMIC); 2405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = pmlmeext->cur_channel; 2407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 2408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 2410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 2411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 2413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2414cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen mgmt.frame_control = 2415036cdd9cb34a10aabb80a97a41fb9dcfead7d113Jes Sorensen cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); 2416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2417cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen ether_addr_copy(mgmt.da, myid(&padapter->eeprompriv)); 2418cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen ether_addr_copy(mgmt.sa, da); 2419cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen ether_addr_copy(mgmt.bssid, get_my_bssid23a(&pmlmeinfo->network)); 2420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2421cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen mgmt.seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq)); 2422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq++; 2423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2424cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen mgmt.u.disassoc.reason_code = cpu_to_le16(reason); 2425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2426cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen frame_len = sizeof(struct ieee80211_hdr_3addr) + 2; 2427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2428cc531f6154167893f1cf8ab084871fe06b38fb2bJes Sorensen cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, (u8 *)&mgmt, frame_len, 2429970fdfa89babb5a6f1a3d345e8cb54d92c1e3a8fVladimir Kondratiev 0); 2430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2433b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_monitor_if_open(struct net_device *ndev) 2434b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2438b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2440b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2442b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_monitor_if_close(struct net_device *ndev) 2443b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2446b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2451b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, 2452b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev) 2453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int rtap_len; 2456b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int qos_len = 0; 2457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int dot11_hdr_len = 24; 2458b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int snap_len = 6; 2459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *pdata; 2460b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char src_mac_addr[6]; 2461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char dst_mac_addr[6]; 2462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_hdr *dot11_hdr; 2463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_radiotap_header *rtap_hdr; 2464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 2465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2466a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) 2469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; 2472b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(rtap_hdr->it_version)) 2473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtap_len = ieee80211_get_radiotap_len(skb->data); 2476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(skb->len < rtap_len)) 2477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtap_len != 14) { 2480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("radiotap len (should be 14): %d\n", rtap_len); 2481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2483b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2484b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Skip the ratio tap header */ 2485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skb_pull(skb, rtap_len); 2486b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11_hdr = (struct ieee80211_hdr *)skb->data; 2488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Check if the QoS bit is set */ 2489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_is_data(dot11_hdr->frame_control)) { 2490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Check if this ia a Wireless Distribution System (WDS) frame 2491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * which has 4 MAC addresses 2492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 2493b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_is_data_qos(dot11_hdr->frame_control)) 2494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger qos_len = IEEE80211_QOS_CTL_LEN; 2495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_has_a4(dot11_hdr->frame_control)) 2496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11_hdr_len += 6; 2497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr)); 2499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr)); 2500b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 2502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * Skip the 802.11 header, QoS (if any) and SNAP, 2503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * but leave spaces for two MAC addresses 2504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 2505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skb_pull(skb, dot11_hdr_len + qos_len + snap_len - 2506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ETH_ALEN * 2); 2507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdata = (unsigned char *)skb->data; 2508888df442ef023adbca6536888eae65b2cd8ae295Jes Sorensen ether_addr_copy(pdata, dst_mac_addr); 2509888df442ef023adbca6536888eae65b2cd8ae295Jes Sorensen ether_addr_copy(pdata + ETH_ALEN, src_mac_addr); 2510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("should be eapol packet\n"); 2512b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Use the real net device to transmit the packet */ 2514b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_xmit23a_entry23a(skb, padapter->pnetdev); 2515b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2516b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (ieee80211_is_action(dot11_hdr->frame_control)) { 251938eb09b5be235eeaf1c4d0a2100d3cb2a3e0b3a3Jes Sorensen struct ieee80211_mgmt *mgmt; 2520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* only for action frames */ 2521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_frame *pmgntframe; 2522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pkt_attrib *pattrib; 2523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *pframe; 2524b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* u8 category, action, OUI_Subtype, dialogToken = 0; */ 2525b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* unsigned char *frame_body; */ 2526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2527b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 len = skb->len; 2529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 category, action; 2530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 253138eb09b5be235eeaf1c4d0a2100d3cb2a3e0b3a3Jes Sorensen mgmt = (struct ieee80211_mgmt *)dot11_hdr; 2532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2533a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("RTW_Tx:da =" MAC_FMT " via %s(%s)\n", 253438eb09b5be235eeaf1c4d0a2100d3cb2a3e0b3a3Jes Sorensen MAC_ARG(mgmt->da), __func__, ndev->name); 253538eb09b5be235eeaf1c4d0a2100d3cb2a3e0b3a3Jes Sorensen category = mgmt->u.action.category; 253638eb09b5be235eeaf1c4d0a2100d3cb2a3e0b3a3Jes Sorensen action = mgmt->u.action.u.wme_action.action_code; 25372e74d336edb945b4a1f851e821001093e4094729Jes Sorensen DBG_8723A("RTW_Tx:category(%u), action(%u)\n", 25382e74d336edb945b4a1f851e821001093e4094729Jes Sorensen category, action); 253998fb81291d30f83838379bf1522fead6673b5fdfJes Sorensen 2540b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* starting alloc mgmt frame to dump it */ 2541b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmgntframe = alloc_mgtxmitframe23a(pxmitpriv); 2542b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmgntframe == NULL) 2543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2545b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update attribute */ 2546b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib = &pmgntframe->attrib; 2547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger update_mgntframe_attrib23a(padapter, pattrib); 2548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->retry_ctrl = false; 2549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2550b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2552b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2554b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pframe, skb->data, len); 2555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->pktlen = len; 2556b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update seq number */ 2558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq = le16_to_cpu(dot11_hdr->seq_ctrl) >> 4; 2559b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->seqnum = pmlmeext->mgnt_seq; 2560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq++; 2561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2562b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->last_txcmdsz = pattrib->pktlen; 2563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dump_mgntframe23a(padapter, pmgntframe); 2565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2567b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfail: 2568b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dev_kfree_skb(skb); 2570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2574b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int 2575b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerrtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr) 2576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2578b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2582b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2583b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2584b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic const struct net_device_ops rtw_cfg80211_monitor_if_ops = { 2585b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_open = rtw_cfg80211_monitor_if_open, 2586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_stop = rtw_cfg80211_monitor_if_close, 2587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry, 2588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address, 2589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 2590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2591b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name, 2592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device **ndev) 2593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *mon_ndev = NULL; 2596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *mon_wdev = NULL; 2597b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); 2598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!name) { 26009cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): without specific name\n", 26019cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen __func__, padapter->pnetdev->name); 2602b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 2603b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2604b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2605b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->pmon_ndev) { 26079cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): monitor interface exist: %s\n", __func__, 26089cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, pwdev_priv->pmon_ndev->name); 2609b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EBUSY; 2610b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2613b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev = alloc_etherdev(sizeof(struct rtw_adapter)); 2614b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mon_ndev) { 26159cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): allocate ndev fail\n", __func__, 26169cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name); 2617b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 2618b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2619b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2620b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP; 2622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger strncpy(mon_ndev->name, name, IFNAMSIZ); 2623b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->name[IFNAMSIZ - 1] = 0; 2624b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->destructor = rtw_ndev_destructor; 2625b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2626b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops; 2627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2628b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wdev */ 2629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2630b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mon_wdev) { 26319cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): allocate mon_wdev fail\n", __func__, 26329cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name); 2633b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 2634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2635b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev->wiphy = padapter->rtw_wdev->wiphy; 2638b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev->netdev = mon_ndev; 2639b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev->iftype = NL80211_IFTYPE_MONITOR; 2640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->ieee80211_ptr = mon_wdev; 2641b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = register_netdevice(mon_ndev); 2643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret) { 2644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2645b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *ndev = pwdev_priv->pmon_ndev = mon_ndev; 2648b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1); 2649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2650b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerout: 2651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret) { 2652b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(mon_wdev); 2653b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev = NULL; 2654b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2655b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret && mon_ndev) { 2657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_netdev(mon_ndev); 2658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *ndev = mon_ndev = NULL; 2659b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2661b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2662b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2663b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2664b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct wireless_dev * 2665b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingercfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name, 2666b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_iftype type, u32 *flags, 2667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct vif_params *params) 2668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2669b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2670b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev = NULL; 2671b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2672b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 26739cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): wiphy:%s, name:%s, type:%d\n", __func__, 26749cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, wiphy_name(wiphy), name, type); 2675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (type) { 2677b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_ADHOC: 2678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_AP_VLAN: 2679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_WDS: 2680b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_MESH_POINT: 2681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2682b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2683b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_MONITOR: 2684b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 2685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); 2686b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2687b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2688b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_CLIENT: 2689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_STATION: 2690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2691b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2692b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2693b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_GO: 2694b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_AP: 2695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2697b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 2698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2699b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Unsupported interface type\n"); 2700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2701b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2702b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 27039cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): ndev:%p, ret:%d\n", __func__, 27049cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, 2705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndev, ret); 2706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret); 2708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2709b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2710b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, 2711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev) 2712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv = 2714b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct rtw_wdev_priv *)wiphy_priv(wiphy); 2715b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev; 2716b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndev = wdev ? wdev->netdev : NULL; 2717b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2718b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!ndev) 2719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unregister_netdevice(ndev); 2722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ndev == pwdev_priv->pmon_ndev) { 2724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->pmon_ndev = NULL; 2725b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->ifname_mon[0] = '\0'; 2726a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): remove monitor interface\n", 2727a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name); 2728b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2729b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2730b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 2731b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2733b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2734b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head, 2735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t head_len, const u8 *tail, size_t tail_len) 2736b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2737b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2738db97812c2c5e8a18d7cf3eb679a4cfdd6125f748Jes Sorensen u8 *pbuf; 2739fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen uint len, ielen, wps_ielen = 0; 2740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 2741ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen struct wlan_bssid_ex *bss = &pmlmepriv->cur_network.network; 2742ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)head; 2743fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen struct ieee80211_mgmt *tmpmgmt; 2744b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* struct sta_priv *pstapriv = &padapter->stapriv; */ 2745b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2746b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n", 2747b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, head_len, tail_len); 2748b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2749b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2750b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2751b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2752ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen if (head_len < offsetof(struct ieee80211_mgmt, u.beacon.variable)) 2753b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2754b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2755b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbuf = kzalloc(head_len + tail_len, GFP_KERNEL); 2756b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pbuf) 2757b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -ENOMEM; 2758fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen tmpmgmt = (struct ieee80211_mgmt *)pbuf; 2759ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen 2760ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen bss->beacon_interval = get_unaligned_le16(&mgmt->u.beacon.beacon_int); 2761ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen bss->capability = get_unaligned_le16(&mgmt->u.beacon.capab_info); 2762ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen bss->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp); 2763ddf5c2bd1044d923ad82f519c68cdf12a055a568Jes Sorensen 2764b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 24 = beacon header len. */ 2765fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen memcpy(pbuf, (void *)head, head_len); 2766fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen memcpy(pbuf + head_len, (void *)tail, tail_len); 2767b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2768fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen len = head_len + tail_len; 2769fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen ielen = len - offsetof(struct ieee80211_mgmt, u.beacon.variable); 2770b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* check wps ie if inclued */ 2771d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 2772d3797af488780e4f83d92ea0a3dc0a6381b566f3Jes Sorensen WLAN_OUI_TYPE_MICROSOFT_WPS, 2773fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen tmpmgmt->u.beacon.variable, ielen)) 2774b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen); 2775b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2776b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* pbss_network->IEs will not include p2p_ie, wfd ie */ 2777fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0, 27789300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen WLAN_EID_VENDOR_SPECIFIC, P2P_OUI23A, 4); 2779fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0, 27809300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen WLAN_EID_VENDOR_SPECIFIC, WFD_OUI23A, 4); 2781b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2782fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen len = ielen + offsetof(struct ieee80211_mgmt, u.beacon.variable); 2783fb5fd46dbdd32faecd5f826f2d47e798732b7b4dJes Sorensen if (rtw_check_beacon_data23a(adapter, tmpmgmt, len) == _SUCCESS) { 2784b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 0; 2785b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 2786b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 2787b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2788b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2789b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pbuf); 2790b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2791b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2792b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2793b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2794b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, 2795b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ap_settings *settings) 2796b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2797b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2798b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *adapter = wiphy_to_adapter(wiphy); 2799b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2800a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): hidden_ssid:%d, auth_type:%d\n", 2801a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, settings->hidden_ssid, 2802b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->auth_type); 2803b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2804b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_add_beacon(adapter, settings->beacon.head, 2805b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->beacon.head_len, settings->beacon.tail, 2806b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->beacon.tail_len); 2807b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2808b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = 2809b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->hidden_ssid; 2810b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2811b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (settings->ssid && settings->ssid_len) { 2812b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_bssid_ex *pbss_network = 2813b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &adapter->mlmepriv.cur_network.network; 2814b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_bssid_ex *pbss_network_ext = 2815b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &adapter->mlmeextpriv.mlmext_info.network; 2816b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2817b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pbss_network->Ssid.ssid, (void *)settings->ssid, 2818b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->ssid_len); 2819b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbss_network->Ssid.ssid_len = settings->ssid_len; 2820b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pbss_network_ext->Ssid.ssid, (void *)settings->ssid, 2821b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->ssid_len); 2822b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbss_network_ext->Ssid.ssid_len = settings->ssid_len; 2823b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2824b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2825b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2826b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2827b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2828b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_beacon(struct wiphy *wiphy, 2829b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 2830b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_beacon_data *info) 2831b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2832b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2833b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *adapter = wiphy_to_adapter(wiphy); 2834b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2835a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2836b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2837b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, 2838b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger info->tail_len); 2839b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2840b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2841b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2842b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2843b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev) 2844b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2845a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2846b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2847b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2848b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2849b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_add_station(struct wiphy *wiphy, 2850f9da455b93f6ba076935b4ef4589f61e529ae046Linus Torvalds struct net_device *ndev, const u8 *mac, 2851b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_parameters *params) 2852b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2853a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2854b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2855b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2856b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2857b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2858b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_station(struct wiphy *wiphy, 2859f9da455b93f6ba076935b4ef4589f61e529ae046Linus Torvalds struct net_device *ndev, const u8 *mac) 2860b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2861b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2862b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct list_head *phead, *plist, *ptmp; 2863b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 updated = 0; 2864b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta; 2865b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 2866b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2867b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 2868b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2869a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("+%s(%s)\n", __func__, ndev->name); 2870b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2871b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true) { 2872b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", 2873b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 2874b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2875b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2876b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2877b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mac) { 2878b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("flush all sta, and cam_entry\n"); 2879b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2880b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger flush_all_cam_entry23a(padapter); /* clear CAM */ 2881b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2882b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_sta_flush23a(padapter); 2883b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2884b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2885b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2886b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2887b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac)); 2888b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2889b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (is_broadcast_ether_addr(mac)) 2890b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2891b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2892b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pstapriv->asoc_list_lock); 2893b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2894b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phead = &pstapriv->asoc_list; 2895b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2896b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* check asoc_queue */ 2897b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_for_each_safe(plist, ptmp, phead) { 2898b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = container_of(plist, struct sta_info, asoc_list); 2899b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2900cc2db7cb8de67cb172b90b72bf42c784b08959adJes Sorensen if (ether_addr_equal(mac, psta->hwaddr)) { 2901b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psta->dot8021xalg == 1 && 2902b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->bpairwise_key_installed == false) { 2903b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, sta's dot8021xalg = 1 and " 2904b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "key_installed = false\n", __func__); 2905b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 2906b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("free psta =%p, aid =%d\n", psta, 2907b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->aid); 2908b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2909b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_del_init(&psta->asoc_list); 2910b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pstapriv->asoc_list_cnt--; 2911b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2912b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* spin_unlock_bh(&pstapriv->asoc_list_lock); */ 2913b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger updated = 2914b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ap_free_sta23a(padapter, psta, true, 2915b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_REASON_DEAUTH_LEAVING); 2916b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* spin_lock_bh(&pstapriv->asoc_list_lock); */ 2917b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2918b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = NULL; 2919b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2920b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2921b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2922b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2923b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2924b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2925b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pstapriv->asoc_list_lock); 2926b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2927b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger associated_clients_update23a(padapter, updated); 2928b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2929a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("-%s(%s)\n", __func__, ndev->name); 2930b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2931b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2932b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2933b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2934b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_station(struct wiphy *wiphy, 2935f9da455b93f6ba076935b4ef4589f61e529ae046Linus Torvalds struct net_device *ndev, const u8 *mac, 2936b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_parameters *params) 2937b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2938a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2939b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2940b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2941b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2942b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_dump_station(struct wiphy *wiphy, 2943b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, int idx, u8 *mac, 2944b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_info *sinfo) 2945b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2946a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2947b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2948b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* TODO: dump scanned queue */ 2949b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2950b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -ENOENT; 2951b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2952b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2953b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev, 2954b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct bss_parameters *params) 2955b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2956a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2957b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2958b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2959b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* CONFIG_8723AU_AP_MODE */ 2960b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2961b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch, 2962b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *buf, size_t len) 2963b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2964b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_frame *pmgntframe; 2965b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pkt_attrib *pattrib; 2966b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *pframe; 2967b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = _FAIL; 2968b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_hdr *pwlanhdr; 2969b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2970b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2971b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2972b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (_FAIL == rtw_pwr_wakeup(padapter)) { 2973b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EFAULT; 2974b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2975b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2976b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2977b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_scan_deny(padapter, 1000); 2978b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2979b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_scan_abort23a(padapter); 2980b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2981b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (tx_ch != rtw_get_oper_ch23a(padapter)) { 2982b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) 2983b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->cur_channel = tx_ch; 2984b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_channel_bwmode23a(padapter, tx_ch, 2985b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger HAL_PRIME_CHNL_OFFSET_DONT_CARE, 2986b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger HT_CHANNEL_WIDTH_20); 2987b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2988b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2989b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* starting alloc mgmt frame to dump it */ 2990b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmgntframe = alloc_mgtxmitframe23a(pxmitpriv); 2991de62f67a00286eb78d44762ce845b00742d79dd0Jes Sorensen if (!pmgntframe) { 2992b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* ret = -ENOMEM; */ 2993b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = _FAIL; 2994b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2995b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2996b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2997b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update attribute */ 2998b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib = &pmgntframe->attrib; 2999b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger update_mgntframe_attrib23a(padapter, pattrib); 3000b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->retry_ctrl = false; 3001b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3002b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3003b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3004b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET; 3005b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3006b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pframe, (void *)buf, len); 3007b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->pktlen = len; 3008b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3009b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwlanhdr = (struct ieee80211_hdr *)pframe; 3010b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update seq number */ 3011b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq = le16_to_cpu(pwlanhdr->seq_ctrl) >> 4; 3012b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->seqnum = pmlmeext->mgnt_seq; 3013b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq++; 3014b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3015b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->last_txcmdsz = pattrib->pktlen; 3016b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3017de62f67a00286eb78d44762ce845b00742d79dd0Jes Sorensen ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe); 3018b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3019de62f67a00286eb78d44762ce845b00742d79dd0Jes Sorensen if (ret != _SUCCESS) 3020de62f67a00286eb78d44762ce845b00742d79dd0Jes Sorensen DBG_8723A("%s, ack == false\n", __func__); 3021de62f67a00286eb78d44762ce845b00742d79dd0Jes Sorensen else 3022de62f67a00286eb78d44762ce845b00742d79dd0Jes Sorensen DBG_8723A("%s, ack == true\n", __func__); 3023b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3024b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 3025b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3026b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ret =%d\n", __func__, ret); 3027b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3028b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3029b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3030b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3031b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3032b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_mgmt_tx_params *params, 3033b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u64 *cookie) 3034b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3035b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = 3036b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct rtw_adapter *)wiphy_to_adapter(wiphy); 3037b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 3038b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int tx_ret; 3039b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 dump_limit = RTW_MAX_MGMT_TX_CNT; 3040b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 dump_cnt = 0; 3041b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool ack = true; 3042b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 category, action; 3043b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned long start = jiffies; 3044b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t len = params->len; 3045b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_channel *chan = params->chan; 3046b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *buf = params->buf; 3047ea2ea44079784794838dc0ae953967990f8457d5Jes Sorensen struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *)buf; 3048b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 tx_ch = (u8) ieee80211_frequency_to_channel(chan->center_freq); 3049b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3050ea2ea44079784794838dc0ae953967990f8457d5Jes Sorensen if (!ieee80211_is_action(hdr->frame_control)) 3051ea2ea44079784794838dc0ae953967990f8457d5Jes Sorensen return -EINVAL; 3052ea2ea44079784794838dc0ae953967990f8457d5Jes Sorensen 3053b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* cookie generation */ 3054b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *cookie = (unsigned long)buf; 3055b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 30569cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): len =%zu, ch =%d\n", __func__, 30579cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, len, tx_ch); 3058b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3059b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* indicate ack before issue frame to avoid racing with rsp frame */ 306056b0bd91e0087e0b172aec022bdfb4fcd9de9194Jes Sorensen cfg80211_mgmt_tx_status(padapter->rtw_wdev, *cookie, buf, len, ack, 306156b0bd91e0087e0b172aec022bdfb4fcd9de9194Jes Sorensen GFP_KERNEL); 3062b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3063b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Tx:tx_ch =%d, da =" MAC_FMT "\n", tx_ch, 3064ea2ea44079784794838dc0ae953967990f8457d5Jes Sorensen MAC_ARG(hdr->da)); 3065ea2ea44079784794838dc0ae953967990f8457d5Jes Sorensen category = hdr->u.action.category; 3066ea2ea44079784794838dc0ae953967990f8457d5Jes Sorensen action = hdr->u.action.u.wme_action.action_code; 30672e74d336edb945b4a1f851e821001093e4094729Jes Sorensen DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action); 3068b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3069b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger do { 3070b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dump_cnt++; 3071b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len); 3072b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } while (dump_cnt < dump_limit && tx_ret != _SUCCESS); 3073b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3074b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (tx_ret != _SUCCESS || dump_cnt > 1) { 30759cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): %s (%d/%d) in %d ms\n", 30769cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen __func__, padapter->pnetdev->name, 3077b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt, 3078b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dump_limit, jiffies_to_msecs(jiffies - start)); 3079b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3080b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3081b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3082b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3083b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3084b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, 3085b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev, 3086b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 frame_type, bool reg) 3087b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3088b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) 3089b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3090b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3091b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3092b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3093b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3094b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct cfg80211_ops rtw_cfg80211_ops = { 3095b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_virtual_intf = cfg80211_rtw_change_iface, 3096b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .add_key = cfg80211_rtw_add_key, 3097b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .get_key = cfg80211_rtw_get_key, 3098b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_key = cfg80211_rtw_del_key, 3099b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_default_key = cfg80211_rtw_set_default_key, 3100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .get_station = cfg80211_rtw_get_station, 3101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .scan = cfg80211_rtw_scan, 3102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_wiphy_params = cfg80211_rtw_set_wiphy_params, 3103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .connect = cfg80211_rtw_connect, 3104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .disconnect = cfg80211_rtw_disconnect, 3105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .join_ibss = cfg80211_rtw_join_ibss, 3106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .leave_ibss = cfg80211_rtw_leave_ibss, 3107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_tx_power = cfg80211_rtw_set_txpower, 3108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .get_tx_power = cfg80211_rtw_get_txpower, 3109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_power_mgmt = cfg80211_rtw_set_power_mgmt, 3110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_pmksa = cfg80211_rtw_set_pmksa, 3111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_pmksa = cfg80211_rtw_del_pmksa, 3112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flush_pmksa = cfg80211_rtw_flush_pmksa, 3113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 3115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .add_virtual_intf = cfg80211_rtw_add_virtual_intf, 3116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_virtual_intf = cfg80211_rtw_del_virtual_intf, 3117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .start_ap = cfg80211_rtw_start_ap, 3119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_beacon = cfg80211_rtw_change_beacon, 3120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .stop_ap = cfg80211_rtw_stop_ap, 3121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3122b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .add_station = cfg80211_rtw_add_station, 3123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_station = cfg80211_rtw_del_station, 3124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_station = cfg80211_rtw_change_station, 3125b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .dump_station = cfg80211_rtw_dump_station, 3126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_bss = cfg80211_rtw_change_bss, 3127b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* CONFIG_8723AU_AP_MODE */ 3128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .mgmt_tx = cfg80211_rtw_mgmt_tx, 3130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, 3131b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 3132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3133b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, 3134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum ieee80211_band band, u8 rf_type) 3135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ 3138b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ 3139b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->ht_supported = true; 3141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 3143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | 3144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; 3145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *Maximum length of AMPDU that the STA can receive. 3148b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) 3149b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 3150b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 3151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /*Minimum MPDU start spacing , */ 3153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; 3154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 3156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *hw->wiphy->bands[IEEE80211_BAND_2GHZ] 3159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *base on ant_num 3160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *rx_mask: RX mask 3161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7 3162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15 3163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if rx_ant >= 3 rx_mask[2]= 0xff; 3164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if BW_40 rx_mask[4]= 0x01; 3165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *highest supported RX rate 3166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 3167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rf_type == RF_1T1R) { 3168b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[0] = 0xFF; 3169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[1] = 0x00; 3170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[4] = 0x01; 3171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3172f78c0710cd60cd108d436490955909983f309c62Kieron Browne ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7); 3173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R)) { 3174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[0] = 0xFF; 3175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[1] = 0xFF; 3176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[4] = 0x01; 3177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3178f78c0710cd60cd108d436490955909983f309c62Kieron Browne ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); 3179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 3180b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, error rf_type =%d\n", __func__, rf_type); 3181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3185b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter) 3186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3187b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 rf_type; 3188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_supported_band *bands; 3189b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *pwdev = padapter->rtw_wdev; 3190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy = pwdev->wiphy; 3191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3192c2370e83ab5432e2d32e9c097930c69366d27b4cJes Sorensen rf_type = rtl8723a_get_rf_type(padapter); 3193b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3194b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s:rf_type =%d\n", __func__, rf_type); 3195b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */ 3197b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 3198b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bands = wiphy->bands[IEEE80211_BAND_2GHZ]; 3199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (bands) 3200b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_init_ht_capab(&bands->ht_cap, 3201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ, 3202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rf_type); 3203b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3205b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */ 3206b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 3207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bands = wiphy->bands[IEEE80211_BAND_5GHZ]; 3208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (bands) 3209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_init_ht_capab(&bands->ht_cap, 3210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ, 3211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rf_type); 3212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3215b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_cfg80211_preinit_wiphy(struct rtw_adapter *padapter, 3216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy) 3217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 3219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT; 3221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 3222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS; 3223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_remain_on_channel_duration = 3225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_MAX_REMAIN_ON_CHANNEL_DURATION; 3226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 3228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(NL80211_IFTYPE_ADHOC) | 3229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 3230b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | 3231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 3232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0; 3233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 3235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes; 3236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* CONFIG_8723AU_AP_MODE */ 3237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); 3239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->iface_combinations = &rtw_combinations; 3242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->n_iface_combinations = 1; 3243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 3244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->cipher_suites = rtw_cipher_suites; 3246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites); 3247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */ 3249b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->bands[IEEE80211_BAND_2GHZ] = 3250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_spt_band_alloc(IEEE80211_BAND_2GHZ); 3251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */ 3252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->bands[IEEE80211_BAND_5GHZ] = 3253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_spt_band_alloc(IEEE80211_BAND_5GHZ); 3254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 3256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; 3257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) 3259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; 3260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 3262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3263b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3264b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev) 3265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 3267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy; 3268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev; 3269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv; 3270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 3271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p)\n", __func__, padapter); 3273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wiphy */ 3275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv)); 3276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wiphy) { 3277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Couldn't allocate wiphy device\n"); 3278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 3279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 3280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3281d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen 3282d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen /* wdev */ 3283d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 3284d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen if (!wdev) { 3285d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen DBG_8723A("Couldn't allocate wireless device\n"); 3286d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen ret = -ENOMEM; 3287d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen goto free_wiphy; 3288d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen } 3289d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen 3290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_wiphy_dev(wiphy, dev); 3291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_preinit_wiphy(padapter, wiphy); 3292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = wiphy_register(wiphy); 3294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) { 3295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Couldn't register wiphy device\n"); 3296d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen goto free_wdev; 3297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3299b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wdev->wiphy = wiphy; 3300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wdev->netdev = pnetdev; 3301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wdev->iftype = NL80211_IFTYPE_STATION; */ 3302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* for rtw_setopmode_cmd23a() in cfg80211_rtw_change_iface() */ 3303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wdev->iftype = NL80211_IFTYPE_MONITOR; 3304b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->rtw_wdev = wdev; 3305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev->ieee80211_ptr = wdev; 3306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* init pwdev_priv */ 3308b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv = wdev_to_priv(wdev); 3309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->rtw_wdev = wdev; 3310b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->pmon_ndev = NULL; 3311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->ifname_mon[0] = '\0'; 3312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->padapter = padapter; 3313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->scan_request = NULL; 3314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_init(&pwdev_priv->scan_req_lock); 3315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->p2p_enabled = false; 3317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) 3319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->power_mgmt = true; 3320b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3321b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->power_mgmt = false; 3322b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3323b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3324d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensenfree_wdev: 3325d165e4efbc6d76cff51abb523567a840cb6623b9Jes Sorensen kfree(wdev); 3326b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_wiphy: 3327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy_free(wiphy); 3328b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 3329b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3332b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_wdev_free(struct wireless_dev *wdev) 3333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(wdev =%p)\n", __func__, wdev); 3335b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wdev) 3337b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]); 3340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]); 3341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3342b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy_free(wdev->wiphy); 3343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(wdev); 3345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3346b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3347b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_wdev_unregister(struct wireless_dev *wdev) 3348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv; 3350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3351b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(wdev =%p)\n", __func__, wdev); 3352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wdev) 3354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv = wdev_to_priv(wdev); 3357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_indicate_scan_done(pwdev_priv, true); 3359b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->pmon_ndev) { 3361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, unregister monitor interface\n", __func__); 3362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unregister_netdev(pwdev_priv->pmon_ndev); 3363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy_unregister(wdev->wiphy); 3366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3367