ioctl_cfg80211.c revision deff11554fa4a0bf0f3616d29f0636ab5ff52758
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 <rtw_ioctl_set.h> 20b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <xmit_osdep.h> 21b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 22b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include "ioctl_cfg80211.h" 23b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#include <linux/version.h> 24b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 25b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_MAX_MGMT_TX_CNT 8 26b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 27b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 /* ms */ 28b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_MAX_NUM_PMKIDS 4 29b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 30b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ 31b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 32b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic const u32 rtw_cipher_suites[] = { 33b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_WEP40, 34b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_WEP104, 35b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_TKIP, 36b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_CIPHER_SUITE_CCMP, 37b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 38b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 39b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RATETAB_ENT(_rate, _rateid, _flags) { \ 40b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .bitrate = (_rate), \ 41b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .hw_value = (_rateid), \ 42b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flags = (_flags), \ 43b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 44b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 45b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define CHAN2G(_channel, _freq, _flags) { \ 46b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .band = IEEE80211_BAND_2GHZ, \ 47b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .center_freq = (_freq), \ 48b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .hw_value = (_channel), \ 49b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flags = (_flags), \ 50b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_antenna_gain = 0, \ 51b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_power = 30, \ 52b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 53b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 54b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define CHAN5G(_channel, _flags) { \ 55b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .band = IEEE80211_BAND_5GHZ, \ 56b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .center_freq = 5000 + (5 * (_channel)), \ 57b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .hw_value = (_channel), \ 58b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flags = (_flags), \ 59b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_antenna_gain = 0, \ 60b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .max_power = 30, \ 61b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 62b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 63b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_rate rtw_rates[] = { 64b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(10, 0x1, 0), 65b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(20, 0x2, 0), 66b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(55, 0x4, 0), 67b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(110, 0x8, 0), 68b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(60, 0x10, 0), 69b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(90, 0x20, 0), 70b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(120, 0x40, 0), 71b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(180, 0x80, 0), 72b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(240, 0x100, 0), 73b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(360, 0x200, 0), 74b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(480, 0x400, 0), 75b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RATETAB_ENT(540, 0x800, 0), 76b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 77b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 78b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define rtw_a_rates (rtw_rates + 4) 79b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_A_RATES_NUM 8 80b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define rtw_g_rates (rtw_rates + 0) 81b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_G_RATES_NUM 12 82b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 83b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_2G_CHANNELS_NUM 14 84b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define RTW_5G_CHANNELS_NUM 37 85b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 86b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_channel rtw_2ghz_channels[] = { 87b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(1, 2412, 0), 88b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(2, 2417, 0), 89b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(3, 2422, 0), 90b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(4, 2427, 0), 91b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(5, 2432, 0), 92b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(6, 2437, 0), 93b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(7, 2442, 0), 94b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(8, 2447, 0), 95b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(9, 2452, 0), 96b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(10, 2457, 0), 97b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(11, 2462, 0), 98b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(12, 2467, 0), 99b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(13, 2472, 0), 100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN2G(14, 2484, 0), 101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 103b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_channel rtw_5ghz_a_channels[] = { 104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(34, 0), CHAN5G(36, 0), 105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(38, 0), CHAN5G(40, 0), 106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(42, 0), CHAN5G(44, 0), 107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(46, 0), CHAN5G(48, 0), 108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(52, 0), CHAN5G(56, 0), 109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(60, 0), CHAN5G(64, 0), 110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(100, 0), CHAN5G(104, 0), 111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(108, 0), CHAN5G(112, 0), 112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(116, 0), CHAN5G(120, 0), 113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(124, 0), CHAN5G(128, 0), 114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(132, 0), CHAN5G(136, 0), 115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(140, 0), CHAN5G(149, 0), 116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(153, 0), CHAN5G(157, 0), 117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(161, 0), CHAN5G(165, 0), 118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(184, 0), CHAN5G(188, 0), 119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(192, 0), CHAN5G(196, 0), 120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(200, 0), CHAN5G(204, 0), 121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(208, 0), CHAN5G(212, 0), 122b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN5G(216, 0), 123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 125b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_2g_channels_init(struct ieee80211_channel *channels) 126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 127b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy((void *)channels, (void *)rtw_2ghz_channels, 128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM); 129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 131b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_5g_channels_init(struct ieee80211_channel *channels) 132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 133b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy((void *)channels, (void *)rtw_5ghz_a_channels, 134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * RTW_5G_CHANNELS_NUM); 135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 137b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_2g_rates_init(struct ieee80211_rate *rates) 138b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 139b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(rates, rtw_g_rates, 140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM); 141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 143b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_5g_rates_init(struct ieee80211_rate *rates) 144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(rates, rtw_a_rates, 146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM); 147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 148b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 149b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct ieee80211_supported_band * 150b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerrtw_spt_band_alloc(enum ieee80211_band band) 151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_supported_band *spt_band = NULL; 153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int n_channels, n_bitrates; 154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (band == IEEE80211_BAND_2GHZ) { 156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_channels = RTW_2G_CHANNELS_NUM; 157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_bitrates = RTW_G_RATES_NUM; 158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (band == IEEE80211_BAND_5GHZ) { 159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_channels = RTW_5G_CHANNELS_NUM; 160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_bitrates = RTW_A_RATES_NUM; 161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band = kzalloc(sizeof(struct ieee80211_supported_band) + 165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * n_channels + 166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_rate) * n_bitrates, 167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_KERNEL); 168b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!spt_band) 169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->channels = 172b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct ieee80211_channel *)(((u8 *) spt_band) + 173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct 174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ieee80211_supported_band)); 175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->bitrates = 176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct ieee80211_rate *)(((u8 *) spt_band->channels) + 177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_channel) * 178b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger n_channels); 179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->band = band; 180b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->n_channels = n_channels; 181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spt_band->n_bitrates = n_bitrates; 182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (band == IEEE80211_BAND_2GHZ) { 184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_2g_channels_init(spt_band->channels); 185b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_2g_rates_init(spt_band->bitrates); 186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (band == IEEE80211_BAND_5GHZ) { 187b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_5g_channels_init(spt_band->channels); 188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_5g_rates_init(spt_band->bitrates); 189b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* spt_band.ht_cap */ 192b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 193b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 194b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return spt_band; 195b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 197b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic const struct ieee80211_txrx_stypes 198b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerrtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { 199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_ADHOC] = { 200b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ACTION >> 4) 202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 203b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_STATION] = { 204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 205b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 206b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) 207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_AP] = { 209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | 211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | 212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | 213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DISASSOC >> 4) | 214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_AUTH >> 4) | 215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DEAUTH >> 4) | 216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_ACTION >> 4) 217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_AP_VLAN] = { 219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* copy AP */ 220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | 222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | 223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | 224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DISASSOC >> 4) | 225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_AUTH >> 4) | 226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DEAUTH >> 4) | 227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_ACTION >> 4) 228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_P2P_CLIENT] = { 230b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) 233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger [NL80211_IFTYPE_P2P_GO] = { 235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .tx = 0xffff, 236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | 237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | 238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | 239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DISASSOC >> 4) | 240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_AUTH >> 4) | 241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_DEAUTH >> 4) | 242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(IEEE80211_STYPE_ACTION >> 4) 243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger }, 244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define MAX_BSSINFO_LEN 1000 247b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter, 248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *pnetwork) 249b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_channel *notify_channel; 252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_bss *bss; 253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* struct ieee80211_supported_band *band; */ 254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 channel; 255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 freq; 256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u64 notify_timestamp; 257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 notify_capability; 258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 notify_interval; 259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *notify_ie; 260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t notify_ielen; 261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 notify_signal; 262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 buf[MAX_BSSINFO_LEN], *pbuf; 263f844717c6a5b30ed605e6fbfcab685c6d2e58592Jes Sorensen size_t len; 264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_hdr *pwlanhdr; 265507a755dd78b782ed6e274803950759f81faf574Larry Finger __le16 *fctrl; 266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev = padapter->rtw_wdev; 268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy = wdev->wiphy; 269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* DBG_8723A("%s\n", __func__); */ 272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 273f844717c6a5b30ed605e6fbfcab685c6d2e58592Jes Sorensen if (pnetwork->network.IELength > MAX_IE_SZ) { 274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s IE Length too long > %d byte\n", __func__, 275f844717c6a5b30ed605e6fbfcab685c6d2e58592Jes Sorensen MAX_IE_SZ); 276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = pnetwork->network.Configuration.DSConfig; 280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 281b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 282b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 285b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 286b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_channel = ieee80211_get_channel(wiphy, freq); 288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_timestamp = jiffies_to_msecs(jiffies) * 1000; /* uSec */ 290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_interval = 292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger le16_to_cpu(*(u16 *) 293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_get_beacon_interval23a_from_ie(pnetwork->network.IEs)); 294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_capability = 2956a235443be58fbdfebb02f536c6338ba82ab399aJes Sorensen get_unaligned_le16( 296b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_get_capability23a_from_ie(pnetwork->network.IEs)); 297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_; 299b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_; 300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: 302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * signal strength in mBm (100*dBm) 303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 304b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_LINKED) && 305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger is_same_network23a(&pmlmepriv->cur_network.network, 306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &pnetwork->network)) { 307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */ 308b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */ 310b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbuf = buf; 312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwlanhdr = (struct ieee80211_hdr *)pbuf; 314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger fctrl = &pwlanhdr->frame_control; 315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *(fctrl) = 0; 316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger SetSeqNum(pwlanhdr, 0); 318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetwork->network.reserved == 1) { /* WIFI_BEACON */ 32043c34be13047dd53e70bc4759ff314424db7036bJes Sorensen eth_broadcast_addr(pwlanhdr->addr1); 321b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger SetFrameSubType(pbuf, WIFI_BEACON); 322b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 323b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwlanhdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN); 324b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger SetFrameSubType(pbuf, WIFI_PROBERSP); 325b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 326b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN); 328b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN); 329b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbuf += sizeof(struct ieee80211_hdr_3addr); 331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger len = sizeof(struct ieee80211_hdr_3addr); 332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength); 334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger len += pnetwork->network.IELength; 335b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bss = cfg80211_inform_bss_frame(wiphy, notify_channel, 337b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct ieee80211_mgmt *)buf, len, 338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_signal, GFP_ATOMIC); 339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(!bss)) { 341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("rtw_cfg80211_inform_bss error\n"); 342b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_put_bss(wiphy, bss); 346b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 347b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 351b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_connect(struct rtw_adapter *padapter) 352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *cur_network = &pmlmepriv->cur_network; 355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *pwdev = padapter->rtw_wdev; 356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p)\n", __func__, padapter); 358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 359b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev->iftype != NL80211_IFTYPE_STATION && 360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT) 361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 36656828797acdb99d23b5e5e5c52e7d571d59b783fJes Sorensen if (padapter->mlmepriv.to_roaming > 0) { 367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy = pwdev->wiphy; 368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_channel *notify_channel; 369b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 freq; 370b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 channel = cur_network->network.Configuration.DSConfig; 371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = 374b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ieee80211_channel_to_frequency(channel, 375b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 377b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = 378b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ieee80211_channel_to_frequency(channel, 379b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 381b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger notify_channel = ieee80211_get_channel(wiphy, freq); 382b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 383b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s call cfg80211_roamed\n", __func__); 384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_roamed(padapter->pnetdev, notify_channel, 385b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cur_network->network.MacAddress, 386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req + 387b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 2, 388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req_len - 389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 2, 390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp + 391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 6, 392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp_len - 393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 6, 394b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_connect_result(padapter->pnetdev, 397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cur_network->network.MacAddress, 398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req + 399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 2, 400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_req_len - 401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 2, 402b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp + 403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) + 6, 404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->assoc_rsp_len - 405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct ieee80211_hdr_3addr) - 6, 406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_STATUS_SUCCESS, GFP_ATOMIC); 407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 410b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_disconnect(struct rtw_adapter *padapter) 411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *pwdev = padapter->rtw_wdev; 414b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 415b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p)\n", __func__, padapter); 416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 417b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev->iftype != NL80211_IFTYPE_STATION && 418b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT) 419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 421b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!padapter->mlmepriv.not_indic_disco) { 425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) { 426b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0, NULL, 0, 428b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_STATUS_UNSPECIFIED_FAILURE, 429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_disconnected(padapter->pnetdev, 0, NULL, 432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0, GFP_ATOMIC); 433b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 434b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 43816b9632da2c071d74934447e266717787bec449bJes Sorensenstatic int set_pairwise_key(struct rtw_adapter *padapter, struct sta_info *psta) 439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 440b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_obj *ph2c; 441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct set_stakey_parm *psetstakey_para; 442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 44316b9632da2c071d74934447e266717787bec449bJes Sorensen int res = _SUCCESS; 444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 446b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ph2c == NULL) { 447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); 452b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psetstakey_para == NULL) { 453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(ph2c); 454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 456b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 458b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4607989bcf3e21683f413dd1488718166d3ff474bf3Jes Sorensen psetstakey_para->algorithm = psta->dot118021XPrivacy; 461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN); 463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16); 465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 466b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = rtw_enqueue_cmd23a(pcmdpriv, ph2c); 467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 468b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return res; 470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4727989bcf3e21683f413dd1488718166d3ff474bf3Jes Sorensenstatic int set_group_key(struct rtw_adapter *padapter, u8 *key, u32 alg, 4734e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen u8 keyid) 474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 keylen; 476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_obj *pcmd; 477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct setkey_parm *psetkeyparm; 478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int res = _SUCCESS; 480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 4834e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen if (keyid >= 4) { 4844e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen res = _FAIL; 4854e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen goto exit; 4864e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen } 4874e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen 488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pcmd) { 490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 493b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL); 494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!psetkeyparm) { 495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pcmd); 496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = _FAIL; 497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 5004e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen psetkeyparm->keyid = keyid; 501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (is_wep_enc(alg)) 5024e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid); 503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetkeyparm->algorithm = alg; 505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psetkeyparm->set_tx = 1; 507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 508b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (alg) { 5099e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen case WLAN_CIPHER_SUITE_WEP40: 510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger keylen = 5; 511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 5129e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen case WLAN_CIPHER_SUITE_WEP104: 513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger keylen = 13; 514b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 5159e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen case WLAN_CIPHER_SUITE_TKIP: 5169e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen case WLAN_CIPHER_SUITE_CCMP: 517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger keylen = 16; 519b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(&psetkeyparm->key[0], key, keylen); 522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->cmdcode = _SetKey_CMD_; 524b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->parmbuf = (u8 *) psetkeyparm; 525b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->cmdsz = (sizeof(struct setkey_parm)); 526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->rsp = NULL; 527b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pcmd->rspsz = 0; 528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger res = rtw_enqueue_cmd23a(pcmdpriv, pcmd); 530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 531b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return res; 533b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 534b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 535e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensenstatic int set_wep_key(struct rtw_adapter *padapter, u8 *key, u16 keylen, 5364e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen u8 keyid) 537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 5389e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen u32 alg; 539b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 540b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (keylen) { 541b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case 5: 5429e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen alg = WLAN_CIPHER_SUITE_WEP40; 543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case 13: 5459e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen alg = WLAN_CIPHER_SUITE_WEP104; 546b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 5489e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen alg = 0; 549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 550b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return set_group_key(padapter, key, alg, keyid); 552b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 554b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_ap_set_encryption(struct net_device *dev, 555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee_param *param, 556b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 param_len) 557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 559e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen u16 wep_key_len; 5604e489d91b4fe320b1260a504a61eb806f3044e61Jes Sorensen u8 wep_key_idx; 561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta = NULL, *pbcmc_sta = NULL; 562b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(dev); 563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 567b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 568b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.err = 0; 570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* sizeof(struct ieee_param) = 64 bytes; */ 573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (param_len != (u32) ((u8 *) param->u.crypt.key - 574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (u8 *) param) + param->u.crypt.key_len) */ 575b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) { 576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 578b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (is_broadcast_ether_addr(param->sta_addr)) { 581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.idx >= WEP_KEYS) { 582b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 583b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 585b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = rtw_get_stainfo23a(pstapriv, param->sta_addr); 587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!psta) { 588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* ret = -EINVAL; */ 589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("rtw_set_encryption(), sta has already " 590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "been removed or never been added\n"); 591b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) { 596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* todo:clear default encryption keys */ 597b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("clear default encryption keys, keyid =%d\n", 599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.idx); 600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 601b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 602b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 603b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 604b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) { 605b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n"); 606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 607b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_idx = param->u.crypt.idx; 608b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_len = param->u.crypt.key_len; 609b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 610b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("r871x_set_encryption, wep_key_idx =%d, len =%d\n", 611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_idx, wep_key_len); 612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 613b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) { 614b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 615b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 616b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 617b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 618b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wep_key_len > 0) { 619b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_len = wep_key_len <= 5 ? 5 : 13; 620b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->bWepDefaultKeyIdxSet == 0) { 623b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wep default key has not been set, so use 624b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger this key index as default key. */ 625b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 626b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = 627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 6289e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 6299e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40; 630b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 631b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wep_key_len == 13) { 6329e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104; 6339e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104; 634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 635b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; 637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 638b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 639e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen memcpy(&psecuritypriv->wep_key[wep_key_idx].key, 640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, wep_key_len); 641b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 642e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->wep_key[wep_key_idx].keylen = wep_key_len; 643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_wep_key(padapter, param->u.crypt.key, wep_key_len, 645b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_idx); 646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 648b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 650b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* group key */ 652b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.set_tx == 0) { /* group key */ 653b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (strcmp(param->u.crypt.alg, "WEP") == 0) { 6549cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s, set group_key, WEP\n", __func__); 655b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKey[param->u.crypt.idx]. 658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, param->u.crypt.key, 659b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt.key_len)); 661b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6629e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40; 663b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.key_len == 13) { 664b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy = 6659e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_WEP104; 666b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 669b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set group_key, TKIP\n", 670b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 671b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6729e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP; 673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 674b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKey[param->u.crypt.idx]. 676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, param->u.crypt.key, 677b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt.key_len)); 679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 680b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set mic key */ 682b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 683b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrptxmickey[param->u.crypt. 684b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger idx].skey, 685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ¶m->u.crypt.key[16], 8); 686b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 687b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrprxmickey[param->u.crypt. 688b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger idx].skey, 689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ¶m->u.crypt.key[24], 8); 690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6919216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen psecuritypriv->busetkipkey = 1; 692b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 693b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 694b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set group_key, CCMP\n", 695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 6979e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP; 698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 699b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKey[param->u.crypt.idx]. 701b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, param->u.crypt.key, 702b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 703b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt.key_len)); 704b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set group_key, none\n", 706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy = 7099e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen 0; 710b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; 713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7149216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen psecuritypriv->binstallGrpkey = 1; 715b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 716b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyAlgrthm = 717b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy; 718b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_group_key(padapter, param->u.crypt.key, 720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy, 721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.idx); 722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter); 724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pbcmc_sta) { 725b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->ieee8021x_blocked = false; 726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* rx will use bmc_sta's dot118021XPrivacy */ 727b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->dot118021XPrivacy = 728b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy; 729b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 730b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 731b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 733b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 734b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 736b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 737b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->dot11AuthAlgrthm == 738b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */ 739b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.set_tx == 1) { 741b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* pairwise key */ 742b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot118021x_UncstKey.skey, 743b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, 744b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 745b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt.key_len)); 746b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 747b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!strcmp(param->u.crypt.alg, "WEP")) { 748b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set pairwise key, WEP\n", 749b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 750b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7519e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_WEP40; 752b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.key_len == 13) { 753b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->dot118021XPrivacy = 7549e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_WEP104; 755b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 756b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (!strcmp(param->u.crypt.alg, "TKIP")) { 757b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set pairwise key, " 758b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "TKIP\n", __func__); 759b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7609e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_TKIP; 761b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 762b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */ 763b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set mic key */ 764b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot11tkiptxmickey.skey, 765b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ¶m->u.crypt.key[16], 8); 766b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot11tkiprxmickey.skey, 767b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ¶m->u.crypt.key[24], 8); 768b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7699216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen psecuritypriv->busetkipkey = 1; 770b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 771b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (!strcmp(param->u.crypt.alg, "CCMP")) { 772b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 773b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set pairwise key, " 774b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "CCMP\n", __func__); 775b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7769e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_CCMP; 777b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 778b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, set pairwise key, " 779b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "none\n", __func__); 780b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 7819e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psta->dot118021XPrivacy = 0; 782b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 783b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 784b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_pairwise_key(padapter, psta); 785b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 786b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->ieee8021x_blocked = false; 787b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 788b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->bpairwise_key_installed = true; 789b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { /* group key??? */ 790b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!strcmp(param->u.crypt.alg, "WEP")) { 791b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 792b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKey[param->u.crypt. 793b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger idx].skey, 794b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, 795b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 796b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt. 797b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger key_len)); 798b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 799b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy = 8009e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_WEP40; 801b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.key_len == 13) { 802b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv-> 803b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpPrivacy = 8049e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_WEP104; 805b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 806b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (!strcmp(param->u.crypt.alg, "TKIP")) { 807b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy = 8089e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_TKIP; 809b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 810b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 811b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKey[param->u.crypt. 812b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger idx].skey, 813b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, 814b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 815b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt. 816b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger key_len)); 817b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 818b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* DEBUG_ERR("set key length :param->u" 819b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ".crypt.key_len =%d\n", 820b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key_len); */ 821b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set mic key */ 822b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 823b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrptxmickey[param->u. 824b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger crypt.idx]. 825b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, ¶m->u.crypt.key[16], 826b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8); 827b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 828b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrprxmickey[param->u. 829b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger crypt.idx]. 830b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, ¶m->u.crypt.key[24], 831b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8); 832b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8339216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen psecuritypriv->busetkipkey = 1; 834b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 835b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (!strcmp(param->u.crypt.alg, "CCMP")) { 836b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy = 8379e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_CCMP; 838b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 839b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv-> 840b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKey[param->u.crypt. 841b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger idx].skey, 842b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, 843b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 844b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt. 845b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger key_len)); 846b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 847b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy = 8489e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen 0; 849b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 850b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 851b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpKeyid = 852b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.idx; 853b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8549216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen psecuritypriv->binstallGrpkey = 1; 855b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 856b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyAlgrthm = 857b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy; 858b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 859b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_group_key(padapter, param->u.crypt.key, 860b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv-> 861b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpPrivacy, 862b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.idx); 863b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 864b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter); 865b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pbcmc_sta) { 866b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* rx will use bmc_sta's 867b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XPrivacy */ 868b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->ieee8021x_blocked = false; 869b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; 870b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 871b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 872b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 873b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 874b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 875b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 876b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 877b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 878b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 879b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 880b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 881b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 882b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_encryption(struct net_device *dev, 883b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee_param *param, u32 param_len) 884b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 885b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 886e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen u32 wep_key_idx; 887e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen u16 wep_key_len; 888b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(dev); 889b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 890b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 891b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 892b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 893b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 894b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.err = 0; 895b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 896b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 897b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param_len < 898b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + 899b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key_len) { 900b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 901b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 902b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 903b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 904b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (is_broadcast_ether_addr(param->sta_addr)) { 905b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.idx >= WEP_KEYS) { 906b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 907b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 908b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 909b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 910b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 911b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 912b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 913b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 914b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (strcmp(param->u.crypt.alg, "WEP") == 0) { 915b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, 916b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("wpa_set_encryption, crypt.alg = WEP\n")); 917b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n"); 918b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 919b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_idx = param->u.crypt.idx; 920b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_len = param->u.crypt.key_len; 921b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 922b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) { 923b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 924b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 925b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 926b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 927b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->bWepDefaultKeyIdxSet == 0) { 928b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wep default key has not been set, so use this 929b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger key index as default key. */ 930b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 931b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_len = wep_key_len <= 5 ? 5 : 13; 932b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 933b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = 934b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 9359e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 9369e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40; 937b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 938b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wep_key_len == 13) { 9399e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104; 9409e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104; 941b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 942b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 943b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; 944b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 945b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 946e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen memcpy(&psecuritypriv->wep_key[wep_key_idx].key, 947b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, wep_key_len); 948b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 949e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->wep_key[wep_key_idx].keylen = wep_key_len; 950b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 951b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_key23a(padapter, psecuritypriv, wep_key_idx, 0); 952b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 953b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 954b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 955b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 956b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->securitypriv.dot11AuthAlgrthm == 957b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X) { /* 802_1x */ 958b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta, *pbcmc_sta; 959b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 960b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 961b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, 962b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WIFI_STATION_STATE | WIFI_MP_STATE)) { 963b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* sta mode */ 964b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = rtw_get_stainfo23a(pstapriv, get_bssid(pmlmepriv)); 965b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psta == NULL) { 966b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, : Obtain Sta_info fail\n", 967b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 968b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 969b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Jeff: don't disable ieee8021x_blocked 970b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger while clearing key */ 971b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (strcmp(param->u.crypt.alg, "none") != 0) 972b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->ieee8021x_blocked = false; 973b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 974b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((padapter->securitypriv.ndisencryptstatus == 975b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled) || 976b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->securitypriv.ndisencryptstatus == 977b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled)) { 978b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->dot118021XPrivacy = 979b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 980b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11PrivacyAlgrthm; 981b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 982b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 983b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (param->u.crypt.set_tx == 1) { 984b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* pairwise key */ 985b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, : param->u.crypt.set_tx" 986b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger " == 1\n", __func__); 987b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 988b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot118021x_UncstKey.skey, 989b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, 990b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 991b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt. 992b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger key_len)); 993b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 994b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (strcmp(param->u.crypt.alg, 995b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "TKIP") == 0) { 996b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot11tkiptxmickey. 997b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, 998b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ¶m->u.crypt.key[16], 999b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8); 1000b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psta->dot11tkiprxmickey. 1001b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, 1002b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ¶m->u.crypt.key[24], 1003b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8); 1004b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1005b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 10069216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen busetkipkey = 0; 1007b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1008b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A(" ~~~~set sta key:unicastkey\n"); 1009b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1010b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_setstakey_cmd23a(padapter, 1011b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (unsigned char *)psta, 1012b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true); 1013b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { /* group key */ 1014b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(padapter->securitypriv. 1015b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKey[param->u.crypt. 1016b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger idx].skey, 1017b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key, 1018b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (param->u.crypt.key_len > 1019b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 16 ? 16 : param->u.crypt. 1020b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger key_len)); 1021b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(padapter->securitypriv. 1022b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrptxmickey[param->u. 1023b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger crypt.idx]. 1024b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, ¶m->u.crypt.key[16], 1025b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8); 1026b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(padapter->securitypriv. 1027b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrprxmickey[param->u. 1028b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger crypt.idx]. 1029b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skey, ¶m->u.crypt.key[24], 1030b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 8); 1031b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.binstallGrpkey = 10329216c517fb0192d1828169d8af2bac59ee8e3173Jes Sorensen 1; 1033b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* DEBUG_ERR((" param->u.crypt.key_len" 1034b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "=%d\n", param->u.crypt.key_len)); */ 1035b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A 1036b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (" ~~~~set sta key:groupkey\n"); 1037b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1038b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 1039b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot118021XGrpKeyid = 1040b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.idx; 1041b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1042b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_key23a(padapter, 1043b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &padapter->securitypriv, 1044b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.idx, 1); 1045b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1046b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1047b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1048b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter); 1049b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pbcmc_sta) { 1050b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Jeff: don't disable ieee8021x_blocked 1051b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger while clearing key */ 1052b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (strcmp(param->u.crypt.alg, "none") != 0) 1053b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->ieee8021x_blocked = false; 1054b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1055b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((padapter->securitypriv.ndisencryptstatus == 1056b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled) || 1057b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->securitypriv.ndisencryptstatus == 1058b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled)) { 1059b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbcmc_sta->dot118021XPrivacy = 1060b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv. 1061b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11PrivacyAlgrthm; 1062b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1063b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1064b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */ 1065b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1066b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1067b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1068b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 1069b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1070b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ret =%d\n", __func__, ret); 1071b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1072b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1073b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1074b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1075b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1076b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1077b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, 1078b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 key_index, bool pairwise, 1079b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *mac_addr, struct key_params *params) 1080b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1081b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger char *alg_name; 1082b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 param_len; 10836f1c59bf2c00eeba0f9ad9ce176cce731de1a8e5Jes Sorensen struct ieee_param *param; 1084b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1085b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy); 1086b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1087b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1088b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1089a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): adding key for %pM\n", __func__, ndev->name, 1090b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mac_addr); 1091b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("cipher = 0x%x\n", params->cipher); 1092b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("key_len = 0x%x\n", params->key_len); 1093b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("seq_len = 0x%x\n", params->seq_len); 1094b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("key_index =%d\n", key_index); 1095b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("pairwise =%d\n", pairwise); 1096b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1097b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param_len = sizeof(struct ieee_param) + params->key_len; 1098b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param = kzalloc(param_len, GFP_KERNEL); 10996f1c59bf2c00eeba0f9ad9ce176cce731de1a8e5Jes Sorensen if (!param) 11006f1c59bf2c00eeba0f9ad9ce176cce731de1a8e5Jes Sorensen return -ENOMEM; 1101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->cmd = IEEE_CMD_SET_ENCRYPTION; 110343c34be13047dd53e70bc4759ff314424db7036bJes Sorensen eth_broadcast_addr(param->sta_addr); 1104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (params->cipher) { 1106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case IW_AUTH_CIPHER_NONE: 1107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* todo: remove key */ 1108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* remove = 1; */ 1109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger alg_name = "none"; 1110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP40: 1112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP104: 1113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger alg_name = "WEP"; 1114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_TKIP: 1116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger alg_name = "TKIP"; 1117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_CCMP: 1119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger alg_name = "CCMP"; 1120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1122b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 1123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOTSUPP; 1124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto addkey_end; 1125b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1127b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); 1128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mac_addr || is_broadcast_ether_addr(mac_addr)) { 1130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */ 1131b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 1132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */ 1133b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* param->u.crypt.idx = key_index - 1; */ 1136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.idx = key_index; 1137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1138b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (params->seq_len && params->seq) { 1139b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(param->u.crypt.seq, params->seq, params->seq_len); 1140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (params->key_len && params->key) { 1143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger param->u.crypt.key_len = params->key_len; 1144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(param->u.crypt.key, params->key, params->key_len); 1145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1148b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_encryption(ndev, param, param_len); 1149b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1150b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 1151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (mac_addr) 1152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(param->sta_addr, (void *)mac_addr, ETH_ALEN); 1153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len); 1155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 1156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 1157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("error! fw_state = 0x%x, iftype =%d\n", 1158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->fw_state, rtw_wdev->iftype); 1159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1162b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingeraddkey_end: 1163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(param); 1164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1168b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int 1169b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingercfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev, 1170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 key_index, bool pairwise, const u8 *mac_addr, 1171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger void *cookie, 1172b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger void (*callback) (void *cookie, struct key_params *)) 1173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1174a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 1175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1178b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev, 1179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 key_index, bool pairwise, 1180b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *mac_addr) 1181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 1183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 1184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1185a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): key_index =%d\n", __func__, ndev->name, key_index); 1186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1187b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (key_index == psecuritypriv->dot11PrivacyKeyIndex) { 1188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* clear the flag of wep default key set. */ 1189b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->bWepDefaultKeyIdxSet = 0; 1190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1192b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1193b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1194b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1195b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_default_key(struct wiphy *wiphy, 1196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, u8 key_index, 1197b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool unicast, bool multicast) 1198b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 1200b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 1201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1202a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): key_index =%d, unicast =%d, multicast =%d.\n", 1203a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, key_index, unicast, multicast); 1204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1205e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen if (key_index < NUM_WEP_KEYS && 1206e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen (psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP40 || 1207e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP104)) { 1208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set wep default key */ 1209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; 1210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyKeyIndex = key_index; 1212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 12139e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 12149e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40; 1215e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen if (psecuritypriv->wep_key[key_index].keylen == 13) { 1216e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = 1217e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 1218e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen psecuritypriv->dot118021XGrpPrivacy = 1219e0827909a27c5d90bf88f714e108de9419fd8b29Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 1220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* set the flag to represent that wep default key 1223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger has been set */ 1224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->bWepDefaultKeyIdxSet = 1; 1225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1230b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_get_station(struct wiphy *wiphy, 1231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 1232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *mac, struct station_info *sinfo) 1233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta = NULL; 1238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 1239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled = 0; 1241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mac) { 1243a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): mac ==%p\n", __func__, ndev->name, mac); 1244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 1245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = rtw_get_stainfo23a(pstapriv, mac); 1249b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psta == NULL) { 1250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, sta_info is null\n", __func__); 1251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 1252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1254a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): mac =" MAC_FMT "\n", __func__, ndev->name, 1255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger MAC_ARG(mac)); 1256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* for infra./P2PClient mode */ 1258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && 1259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, _FW_LINKED)) { 1260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *cur_network = &pmlmepriv->cur_network; 1261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (memcmp(mac, cur_network->network.MacAddress, ETH_ALEN)) { 1263b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, mismatch bssid =" MAC_FMT "\n", __func__, 1264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger MAC_ARG(cur_network->network.MacAddress)); 1265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 1266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_SIGNAL; 1270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv. 1271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger signal_strength); 1272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_TX_BITRATE; 1274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->txrate.legacy = rtw_get_cur_max_rate23a(padapter); 1275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_RX_PACKETS; 1277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->rx_packets = sta_rx_data_pkts(psta); 1278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->filled |= STATION_INFO_TX_PACKETS; 1280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo->tx_packets = psta->sta_stats.tx_pkts; 1281b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1282b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* for Ad-Hoc/AP mode */ 1284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || 1285b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || 1286b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, WIFI_AP_STATE)) && 1287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger check_fwstate(pmlmepriv, _FW_LINKED) 1288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ) { 1289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* TODO: should acquire station info... */ 1290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1292b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 1293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1296efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensenint cfg80211_infrastructure_mode(struct rtw_adapter* padapter, 1297efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen enum nl80211_iftype ifmode) 1298efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen{ 1299efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1300efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen struct wlan_network *cur_network = &pmlmepriv->cur_network; 1301efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen enum nl80211_iftype old_mode; 1302efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1303efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode = cur_network->network.ifmode; 1304efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1305efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, 1306efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen ("+%s: old =%d new =%d fw_state = 0x%08x\n", __func__, 1307efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode, ifmode, get_fwstate(pmlmepriv))); 1308efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1309efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (old_mode != ifmode) { 1310efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen spin_lock_bh(&pmlmepriv->lock); 1311efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1312efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 1313efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen (" change mode!")); 1314efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1315efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (old_mode == NL80211_IFTYPE_AP || 1316efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_P2P_GO) { 1317efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* change to other mode from Ndis802_11APMode */ 1318efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen cur_network->join_res = -1; 1319efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1320efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#ifdef CONFIG_8723AU_AP_MODE 1321efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen stop_ap_mode23a(padapter); 1322efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#endif 1323efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1324efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1325efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED) || 1326efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_ADHOC) 1327efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_disassoc_cmd23a(padapter, 0, true); 1328efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1329efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED) || 1330efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) 1331efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_free_assoc_resources23a(padapter, 1); 1332efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1333efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (old_mode == NL80211_IFTYPE_STATION || 1334efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_P2P_CLIENT || 1335efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen old_mode == NL80211_IFTYPE_ADHOC) { 1336efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1337efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* will clr Linked_state; before this function, 1338efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen we must have chked whether issue 1339efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen dis-assoc_cmd or not */ 1340efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_indicate_disconnect23a(padapter); 1341efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1342efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1343efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1344efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen cur_network->network.ifmode = ifmode; 1345efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1346efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE); 1347efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1348efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen switch (ifmode) { 1349efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_ADHOC: 1350efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 1351efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1352efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1353efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_P2P_CLIENT: 1354efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_STATION: 1355efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen set_fwstate(pmlmepriv, WIFI_STATION_STATE); 1356efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1357efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1358efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_P2P_GO: 1359efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_AP: 1360efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen set_fwstate(pmlmepriv, WIFI_AP_STATE); 1361efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#ifdef CONFIG_8723AU_AP_MODE 1362efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen start_ap_mode23a(padapter); 1363efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* rtw_indicate_connect23a(padapter); */ 1364efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen#endif 1365efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1366efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1367efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen default: 1368efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen break; 1369efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1370efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1371efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* SecClearAllKeys(adapter); */ 1372efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1373efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* RT_TRACE(COMP_OID_SET, DBG_LOUD, 1374efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen ("set_infrastructure: fw_state:%x after changing mode\n", */ 1375efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen /* get_fwstate(pmlmepriv))); */ 1376efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1377efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen spin_unlock_bh(&pmlmepriv->lock); 1378efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen } 1379efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1380efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen return _SUCCESS; 1381efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen} 1382efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen 1383b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_iface(struct wiphy *wiphy, 1384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 1385b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_iftype type, u32 *flags, 1386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct vif_params *params) 1387b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_iftype old_type; 1389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy); 1392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1394a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): call netdev_open23a\n", __func__, ndev->name); 1395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (netdev_open23a(ndev) != 0) { 1396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 1397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (_FAIL == rtw_pwr_wakeup(padapter)) { 1401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 1402b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger old_type = rtw_wdev->iftype; 1406a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): old_iftype =%d, new_iftype =%d\n", 1407a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, old_type, type); 1408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (old_type != type) { 1410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->action_public_rxseq = 0xffff; 1411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->action_public_dialog_token = 0xff; 1412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1414b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (type) { 1415b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_ADHOC: 1416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_CLIENT: 1417b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_STATION: 1418b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_GO: 1419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_AP: 1420efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen case NL80211_IFTYPE_UNSPECIFIED: 1421b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 1423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EOPNOTSUPP; 1424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1426b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev->iftype = type; 1427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1428efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (cfg80211_infrastructure_mode(padapter, type) != _SUCCESS) { 1429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev->iftype = old_type; 1430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 1431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1433b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1434efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen rtw_setopmode_cmd23a(padapter, type); 1435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1436b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 1437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1438b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1440b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, 1441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool aborted) 1442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1443b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pwdev_priv->scan_req_lock); 1444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->scan_request != NULL) { 1445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s with scan req\n", __func__); 1446141bd353c5a9ba987dbe7b28ffdd034bb3ed55baJes Sorensen 1447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->scan_request->wiphy != 1448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->rtw_wdev->wiphy) 1449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("error wiphy compare\n"); 1450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 1451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_scan_done(pwdev_priv->scan_request, aborted); 1452b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->scan_request = NULL; 1454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 1455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s without scan req\n", __func__); 1456b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pwdev_priv->scan_req_lock); 1458b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1460b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_surveydone_event_callback(struct rtw_adapter *padapter) 1461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct list_head *plist, *phead, *ptmp; 1463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_queue *queue = &pmlmepriv->scanned_queue; 1465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *pnetwork; 1466b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pmlmepriv->scanned_queue.lock); 1468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phead = get_list_head(queue); 1470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_for_each_safe(plist, ptmp, phead) { 1472b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork = container_of(plist, struct wlan_network, list); 1473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* report network only if the current channel set 1475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger contains the channel to which this network belongs */ 1476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_ch_set_search_ch23a 1477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (padapter->mlmeextpriv.channel_set, 1478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork->network.Configuration.DSConfig) >= 0) 1479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_inform_bss(padapter, pnetwork); 1480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1483b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1484b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* call this after other things have been done */ 1485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), 1486b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger false); 1487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1489b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter, 1490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger char *buf, int len) 1491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1493b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint wps_ielen = 0; 1494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *wps_ie; 1495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ielen =%d\n", __func__, len); 1498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (len > 0) { 1500b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen); 1501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wps_ie) { 1502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("probe_req_wps_ielen =%d\n", wps_ielen); 1503141bd353c5a9ba987dbe7b28ffdd034bb3ed55baJes Sorensen 1504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_probe_req_ie) { 1505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_req_ie_len = 0; 1506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pmlmepriv->wps_probe_req_ie); 1507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_req_ie = NULL; 1508b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1509b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_req_ie = 1511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kmalloc(wps_ielen, GFP_KERNEL); 1512b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_probe_req_ie == NULL) { 1513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s()-%d: kmalloc() ERROR!\n", 1514b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, __LINE__); 1515b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 1516b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen); 1518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_req_ie_len = wps_ielen; 1519b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1524b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1525b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_scan(struct wiphy *wiphy, 1526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_scan_request *request) 1527b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int i; 1529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 _status = false; 1530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 1531b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 1532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1533b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT]; 1534b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; 1535b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); 1536b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ssid *ssids = request->ssids; 1537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool need_indicate_scan_done = false; 1538b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1539a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name); 1540b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1541b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pwdev_priv->scan_req_lock); 1542b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->scan_request = request; 1543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pwdev_priv->scan_req_lock); 1544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1545b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1546b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s under WIFI_AP_STATE\n", __func__); 1547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* need_indicate_scan_done = true; */ 1548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* goto check_need_indicate_scan_done; */ 1549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1550b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_pwr_wakeup(padapter) == _FAIL) { 1552b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1554b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1556b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (request->ie && request->ie_len > 0) { 1557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_set_probe_req_wpsp2pie(padapter, 1558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (u8 *) request->ie, 1559b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger request->ie_len); 1560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1562b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) { 1563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, bBusyTraffic == true\n", __func__); 1564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1567b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_is_scan_deny(padapter)) { 15689cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): scan deny\n", __func__, 15699cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name); 1570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == 1575b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true) { 1576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state); 1577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger need_indicate_scan_done = true; 1578b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto check_need_indicate_scan_done; 1579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(ssid, 0, sizeof(struct cfg80211_ssid) * RTW_SSID_SCAN_AMOUNT); 1582b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* parsing request ssids, n_ssids */ 1583b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) { 1584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid, 1585b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ssids[i].ssid_len); 1586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len); 1587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ssid[i].ssid_len = ssids[i].ssid_len; 1588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* parsing channels, n_channels */ 1591b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(ch, 0, 1592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT); 1593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (request->n_channels == 1) { 1595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < request->n_channels && 1596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger i < RTW_CHANNEL_SCAN_AMOUNT; i++) { 15979cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s:(%s):" CHAN_FMT "\n", 15989cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen __func__, padapter->pnetdev->name, 1599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger CHAN_ARG(request->channels[i])); 1600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ch[i].hw_value = request->channels[i]->hw_value; 1601b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ch[i].flags = request->channels[i]->flags; 1602b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1603b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1604b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1605b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pmlmepriv->lock); 1606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (request->n_channels == 1) { 1607b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel)); 1608b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel)); 1609b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _status = rtw_sitesurvey_cmd23a(padapter, ssid, 1610b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_SSID_SCAN_AMOUNT, ch, 3); 1611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 1612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _status = rtw_sitesurvey_cmd23a(padapter, ssid, 1613b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_SSID_SCAN_AMOUNT, NULL, 0); 1614b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1615b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pmlmepriv->lock); 1616b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1617b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (_status == false) 1618b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -1; 1619b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1620b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingercheck_need_indicate_scan_done: 1621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (need_indicate_scan_done) 1622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_surveydone_event_callback(padapter); 1623b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1624b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1625b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1626b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1628b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 1629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1630b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1631b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1632b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev, 1633b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ibss_params *params) 1634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1635a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 1636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1638b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1639b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) 1640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1641a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 1642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1645b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, 1646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 wpa_version) 1647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1648b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, wpa_version =%d\n", __func__, wpa_version); 1649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1650b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wpa_version) { 1651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; 1652b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1653b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1654b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1655b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) { 1656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK; 1657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1659b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger/* 1660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wpa_version & NL80211_WPA_VERSION_2) 1661b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 1662b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; 1663b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1664b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger*/ 1665b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1666b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1669b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, 1670b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_auth_type sme_auth_type) 1671b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1672b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type); 1673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1674b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (sme_auth_type) { 1675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_AUTHTYPE_AUTOMATIC: 1676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; 1677b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_AUTHTYPE_OPEN_SYSTEM: 1680b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 1681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1682b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA) 1683b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = 1684b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X; 1685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1686b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_AUTHTYPE_SHARED_KEY: 1687b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; 1688b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; 1690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1691b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 1692b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 1693b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* return -ENOTSUPP; */ 1694b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1697b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1699b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, 1700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 cipher, bool ucast) 1701b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1702b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 ndisencryptstatus = Ndis802_11EncryptionDisabled; 1703b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1704b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm : 1705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &psecuritypriv->dot118021XGrpPrivacy; 1706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher); 1708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1709b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!cipher) { 17109e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = 0; 1711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = ndisencryptstatus; 1712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1714b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1715b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (cipher) { 1716b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case IW_AUTH_CIPHER_NONE: 17179e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = 0; 1718b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11EncryptionDisabled; 1719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP40: 17219e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_WEP40; 1722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption1Enabled; 1723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_WEP104: 17259e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_WEP104; 1726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption1Enabled; 1727b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1728b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_TKIP: 17299e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_TKIP; 1730b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption2Enabled; 1731b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WLAN_CIPHER_SUITE_CCMP: 17339e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen *profile_cipher = WLAN_CIPHER_SUITE_CCMP; 1734b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndisencryptstatus = Ndis802_11Encryption3Enabled; 1735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1736b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 1737b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Unsupported cipher: 0x%x\n", cipher); 1738b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -ENOTSUPP; 1739b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1741b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ucast) 1742b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = ndisencryptstatus; 1743b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1744b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1745b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1746b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1747b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, 1748b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 key_mgt) 1749b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 1750b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, key_mgt = 0x%x\n", __func__, key_mgt); 1751b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1752b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (key_mgt == WLAN_AKM_SUITE_8021X) 1753b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 1754b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else if (key_mgt == WLAN_AKM_SUITE_PSK) 1755b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; 1756b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 1757b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt); 1758b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1759b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 1760b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1761b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1762b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie, 1763b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t ielen) 1764b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 17659bf29cb9404c8368d7a501e5266e0cfcf0bce702Jes Sorensen u8 *buf = NULL; 1766b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int group_cipher = 0, pairwise_cipher = 0; 1767b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 176858aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen const u8 *pwpa, *pwpa2; 1769b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int i; 1770b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1771b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pie || !ielen) { 1772b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Treat this as normal case, but need to clear 1773b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WIFI_UNDER_WPS */ 1774b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 1775b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1776b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1777b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) { 1778b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 1779b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1780b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1781b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger buf = kzalloc(ielen, GFP_KERNEL); 1782b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (buf == NULL) { 1783b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 1784b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1785b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1786b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(buf, pie, ielen); 1787b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1788b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* dump */ 1789b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("set wpa_ie(length:%zu):\n", ielen); 1790b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (i = 0; i < ielen; i = i + 8) 1791b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", 1792b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger buf[i], buf[i + 1], 1793b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger buf[i + 2], buf[i + 3], buf[i + 4], 1794b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger buf[i + 5], buf[i + 6], buf[i + 7]); 1795b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ielen < RSN_HEADER_LEN) { 1796b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, 1797b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("Ie len too short %d\n", (int)ielen)); 1798b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -1; 1799b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 1800b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1801b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 180258aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen pwpa = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 180358aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen WLAN_OUI_TYPE_MICROSOFT_WPA, 180458aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen buf, ielen); 180558aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (pwpa && pwpa[1] > 0) { 180658aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (rtw_parse_wpa_ie23a(pwpa, pwpa[1] + 2, &group_cipher, 180758aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen &pairwise_cipher, NULL) == _SUCCESS) { 1808b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.dot11AuthAlgrthm = 1809b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X; 1810b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisauthtype = 1811b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11AuthModeWPAPSK; 181258aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen memcpy(padapter->securitypriv.supplicant_ie, pwpa, 181358aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen pwpa[1] + 2); 1814b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 181558aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen DBG_8723A("got wpa_ie, wpa_ielen:%u\n", pwpa[1]); 1816b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1817b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1818b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 181958aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, buf, ielen); 182058aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (pwpa2 && pwpa2[1] > 0) { 182158aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen if (rtw_parse_wpa2_ie23a (pwpa2, pwpa2[1] + 2, &group_cipher, 182258aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen &pairwise_cipher, NULL) == _SUCCESS) { 1823b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.dot11AuthAlgrthm = 1824b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11AuthAlgrthm_8021X; 1825b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisauthtype = 1826b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11AuthModeWPA2PSK; 182758aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen memcpy(padapter->securitypriv.supplicant_ie, pwpa2, 182858aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen pwpa2[1] + 2); 1829b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 183058aedb498f8a9870ff871058d4b91d77457fc14cJes Sorensen DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", pwpa2[1]); 1831b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1832b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1833b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1834b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (group_cipher == 0) { 1835b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger group_cipher = WPA_CIPHER_NONE; 1836b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1837b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pairwise_cipher == 0) { 1838b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pairwise_cipher = WPA_CIPHER_NONE; 1839b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1840b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1841b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (group_cipher) { 1842b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_NONE: 18439e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = 0; 1844b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1845b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11EncryptionDisabled; 1846b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1847b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP40: 18489e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40; 1849b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1850b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1851b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1852b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_TKIP: 18539e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP; 1854b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1855b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled; 1856b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1857b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_CCMP: 18589e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP; 1859b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1860b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled; 1861b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1862b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP104: 18639e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104; 1864b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1865b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1866b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1867b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1868b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1869b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (pairwise_cipher) { 1870b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_NONE: 18719e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = 0; 1872b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1873b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11EncryptionDisabled; 1874b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1875b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP40: 18769e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 1877b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1878b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1879b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1880b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_TKIP: 18819e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_TKIP; 1882b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1883b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption2Enabled; 1884b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1885b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_CCMP: 18869e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_CCMP; 1887b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1888b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption3Enabled; 1889b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1890b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case WPA_CIPHER_WEP104: 18919e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104; 1892b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus = 1893b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Ndis802_11Encryption1Enabled; 1894b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 1895b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1896b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1897b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { /* handle wps_ie */ 1898b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint wps_ielen; 1899b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *wps_ie; 1900b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1901b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wps_ie = rtw_get_wps_ie23a(buf, ielen, NULL, &wps_ielen); 1902b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wps_ie && wps_ielen > 0) { 1903b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ielen); 1904b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.wps_ie_len = 1905b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wps_ielen < 1906b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN; 1907b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(padapter->securitypriv.wps_ie, wps_ie, 1908b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.wps_ie_len); 1909b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); 1910b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 1911b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 1912b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1913b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 1914b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1915b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* TKIP and AES disallow multicast packets until installing group key */ 19169e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen if (padapter->securitypriv.dot11PrivacyAlgrthm == 19179e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_TKIP || 19189e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm == 19199e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen WLAN_CIPHER_SUITE_CCMP) 1920b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* WPS open need to enable multicast */ 1921b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/ 1922763b4247cafdb978630d4da7ff48c8113c7d961eJes Sorensen rtl8723a_off_rcr_am(padapter); 1923b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1924b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, 1925b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->" 1926b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "securitypriv.ndisencryptstatus =%d padapter->" 1927b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "securitypriv.ndisauthtype =%d\n", pairwise_cipher, 1928b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus, 1929b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisauthtype)); 1930b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 1931b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 1932b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(buf); 1933b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret) 1934b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); 1935b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 1936b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 1937b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 19386893c8ebba521ea9d0f1cc4a53233fcb09271d52Jes Sorensenstatic int rtw_cfg80211_add_wep(struct rtw_adapter *padapter, 1939deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen struct rtw_wep_key *wep, u8 keyid) 19401e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen{ 1941deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen int res; 19421e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen struct security_priv *psecuritypriv = &padapter->securitypriv; 19431e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 1944deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (keyid >= NUM_WEP_KEYS) { 19451e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, 19461e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:keyid>4 =>fail\n", __func__)); 19471e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen res = _FAIL; 19481e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen goto exit; 19491e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen } 19501e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 1951deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen switch (wep->keylen) { 19521e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen case 5: 19531e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40; 19541e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 19551e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:wep->KeyLength = 5\n", __func__)); 19561e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen break; 19571e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen case 13: 19581e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104; 19591e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 19601e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:wep->KeyLength = 13\n", __func__)); 19611e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen break; 19621e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen default: 19631e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyAlgrthm = 0; 19641e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 19651e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:wep->KeyLength!= 5 or 13\n", __func__)); 19661e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen res = _FAIL; 19671e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen goto exit; 19681e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen } 19691e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 19701e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 1971deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen ("%s:before memcpy, wep->KeyLength = 0x%x keyid =%x\n", 1972deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen __func__, wep->keylen, keyid)); 19731e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 1974deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen memcpy(&psecuritypriv->wep_key[keyid], wep, sizeof(struct rtw_wep_key)); 19751e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 19761e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->dot11PrivacyKeyIndex = keyid; 19771e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 19781e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, 19791e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen ("%s:security key material : " 19801e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen "%x %x %x %x %x %x %x %x %x %x %x %x %x\n", __func__, 19811e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[0], 19821e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[1], 19831e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[2], 19841e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[3], 19851e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[4], 19861e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[5], 19871e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[6], 19881e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[7], 19891e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[8], 19901e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[9], 19911e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[10], 19921e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[11], 19931e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen psecuritypriv->wep_key[keyid].key[12])); 19941e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 19951e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen res = rtw_set_key23a(padapter, psecuritypriv, keyid, 1); 19961e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 19971e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensenexit: 19981e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 19991e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen return res; 20001e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen} 20011e6e7f6030f3cec00641c5a356b5986723f33df6Jes Sorensen 2002b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, 2003b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_connect_params *sme) 2004b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2005b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2006b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct list_head *phead, *plist, *ptmp; 2007b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_network *pnetwork = NULL; 2008b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum ndis_802_11_auth_mode authmode; 2009b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ssid ndis_ssid; 2010b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *dst_ssid; 2011b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *src_ssid; 2012b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *dst_bssid; 2013b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *src_bssid; 2014b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* u8 matched_by_bssid = false; */ 2015b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* u8 matched_by_ssid = false; */ 2016b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 matched = false; 2017b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2018b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2019b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 2020b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_queue *queue = &pmlmepriv->scanned_queue; 2021b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2022a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("=>" "%s(%s)\n", __func__, ndev->name); 2023b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("privacy =%d, key =%p, key_len =%d, key_idx =%d\n", 2024b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->privacy, sme->key, sme->key_len, sme->key_idx); 2025b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2026b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wdev_to_priv(padapter->rtw_wdev)->block) { 2027b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EBUSY; 2028b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s wdev_priv.block is set\n", __func__); 2029b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2030b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2031b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2032b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (_FAIL == rtw_pwr_wakeup(padapter)) { 2033b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 2034b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2035b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2036b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2037b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 2038b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 2039b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2040b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2041b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2042b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!sme->ssid || !sme->ssid_len) { 2043b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 2044b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2045b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2046b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2047b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->ssid_len > IW_ESSID_MAX_SIZE) { 2048b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -E2BIG; 2049b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2050b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2051b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2052b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(&ndis_ssid, 0, sizeof(struct cfg80211_ssid)); 2053b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndis_ssid.ssid_len = sme->ssid_len; 2054b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(ndis_ssid.ssid, sme->ssid, sme->ssid_len); 2055b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2056b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("ssid =%s, len =%zu\n", ndis_ssid.ssid, sme->ssid_len); 2057b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2058b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->bssid) 2059b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bssid =" MAC_FMT "\n", MAC_ARG(sme->bssid)); 2060b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2061b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { 2062b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EBUSY; 2063b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, fw_state = 0x%x, goto exit\n", __func__, 2064b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->fw_state); 2065b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2066b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2067b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { 2068b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_scan_abort23a(padapter); 2069b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2070b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2071b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&queue->lock); 2072b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2073b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phead = get_list_head(queue); 2074b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2075b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_for_each_safe(plist, ptmp, phead) { 2076b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork = container_of(plist, struct wlan_network, list); 2077b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2078b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dst_ssid = pnetwork->network.Ssid.ssid; 2079b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dst_bssid = pnetwork->network.MacAddress; 2080b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2081b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->bssid) { 2082b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (memcmp(pnetwork->network.MacAddress, 2083b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->bssid, ETH_ALEN)) 2084b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger continue; 2085b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2086b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2087b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->ssid && sme->ssid_len) { 2088b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pnetwork->network.Ssid.ssid_len != sme->ssid_len || 2089b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcmp(pnetwork->network.Ssid.ssid, sme->ssid, 2090b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->ssid_len)) 2091b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger continue; 2092b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2093b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2094b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->bssid) { 2095b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger src_bssid = sme->bssid; 2096b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2097b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) { 2098b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("matched by bssid\n"); 2099b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndis_ssid.ssid_len = 2101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork->network.Ssid.ssid_len; 2102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(ndis_ssid.ssid, 2103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork->network.Ssid.ssid, 2104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetwork->network.Ssid.ssid_len); 2105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger matched = true; 2107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (sme->ssid && sme->ssid_len) { 2111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger src_ssid = ndis_ssid.ssid; 2112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2113b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_len)) && 2114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (pnetwork->network.Ssid.ssid_len == 2115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndis_ssid.ssid_len)) { 2116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("matched by ssid\n"); 2117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger matched = true; 2118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2122b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&queue->lock); 2124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2125b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!matched || (pnetwork == NULL)) { 2126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOENT; 2127b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("connect, matched == false, goto exit\n"); 2128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2131efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen if (cfg80211_infrastructure_mode( 2132efc7144ff163bb1305ec8585e9e2f93ad9b06bd9Jes Sorensen padapter, pnetwork->network.ifmode) != _SUCCESS) { 2133b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EPERM; 2134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; 21389e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot11PrivacyAlgrthm = 0; 21399e3d6df2df8dbc4c2c5fb733dc494dfc82e0e2aeJes Sorensen psecuritypriv->dot118021XGrpPrivacy = 0; 2140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; 2141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; 2142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 2144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_set_wpa_version(psecuritypriv, 2145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->crypto.wpa_versions); 2146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2148b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2149b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type); 2150b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ie_len =%zu\n", __func__, sme->ie_len); 2155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len); 2157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->crypto.n_ciphers_pairwise) { 2161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_cipher(psecuritypriv, 2162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->crypto.ciphers_pairwise[0], 2163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true); 2164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2168b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* For WEP Shared auth */ 2169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared || 2170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && 2171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->key) { 2172deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen struct rtw_wep_key wep_key; 2173deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen u8 wep_key_idx, wep_key_len; 2174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(): Shared/Auto WEP\n", __func__); 2175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_idx = sme->key_idx; 2177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wep_key_len = sme->key_len; 2178b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2179deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (wep_key_idx > WEP_KEYS || !wep_key_len || 2180deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen wep_key_len > WLAN_KEY_LEN_WEP104) { 2181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 2182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2185deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen wep_key_len = wep_key_len <= 5 ? 5 : 13; 2186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2187deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen memset(&wep_key, 0, sizeof(struct rtw_wep_key)); 2188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2189deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen wep_key.keylen = wep_key_len; 2190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2191deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (wep_key_len == 13) { 2192deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = 2193deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 2194deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = 2195deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP104; 2196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 2197deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot11PrivacyAlgrthm = 2198deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP40; 2199deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen padapter->securitypriv.dot118021XGrpPrivacy = 2200deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen WLAN_CIPHER_SUITE_WEP40; 2201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2203deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen memcpy(wep_key.key, (void *)sme->key, wep_key.keylen); 2204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2205deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen if (rtw_cfg80211_add_wep(padapter, &wep_key, wep_key_idx) != 2206deff11554fa4a0bf0f3616d29f0636ab5ff52758Jes Sorensen _SUCCESS) 2207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EOPNOTSUPP; 2208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_cipher(psecuritypriv, 2214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->crypto.cipher_group, false); 2215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (sme->crypto.n_akm_suites) { 2219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_cfg80211_set_key_mgt(psecuritypriv, 2220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sme->crypto.akm_suites[0]); 2221b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) 2222b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger authmode = psecuritypriv->ndisauthtype; 2226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_802_11_authentication_mode23a(padapter, authmode); 2227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* rtw_set_802_11_encryption_mode(padapter, 2229b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->securitypriv.ndisencryptstatus); */ 2230b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_set_802_11_ssid23a(padapter, &ndis_ssid) == false) { 2232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -1; 2233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, " 2237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm, 2238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot11PrivacyAlgrthm, 2239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->dot118021XGrpPrivacy); 2240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2241b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 2242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("<=%s, ret %d\n", __func__, ret); 2244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2248b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, 2249b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 reason_code) 2250b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2253a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_roaming(padapter, 0); 2256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { 2258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_scan_abort23a(padapter); 2259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LeaveAllPowerSaveMode23a(padapter); 2260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_disassoc_cmd23a(padapter, 500, false); 2261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2262b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s...call rtw_indicate_disconnect23a\n", __func__); 2263b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2264b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->mlmepriv.not_indic_disco = true; 2265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_indicate_disconnect23a(padapter); 2266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->mlmepriv.not_indic_disco = false; 2267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_free_assoc_resources23a(padapter, 1); 2269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2272b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2274b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_txpower(struct wiphy *wiphy, 2275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev, 2276b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_tx_power_setting type, int mbm) 2277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2281b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2282b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_get_txpower(struct wiphy *wiphy, 2283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev, int *dbm) 2284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2285b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2286b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *dbm = (12); 2287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2290b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerinline bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter) 2291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2292b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev); 2293b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return rtw_wdev_priv->power_mgmt; 2294b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2296b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, 2297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 2298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool enabled, int timeout) 2299b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev); 2302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2303a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): enabled:%u, timeout:%d\n", 2304a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, enabled, timeout); 2305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_priv->power_mgmt = enabled; 2307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2308b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!enabled) 2309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger LPS_Leave23a(padapter); 2310b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2314b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, 2315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *netdev, 2316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_pmksa *pmksa) 2317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 index, blInserted = false; 2319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2320b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 2321b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 strZeroMacAddress[ETH_ALEN] = { 0x00 }; 2322b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2323a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, netdev->name); 2324b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2325b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!memcmp(pmksa->bssid, strZeroMacAddress, ETH_ALEN)) { 2326b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2328b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2329b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger blInserted = false; 2330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* overwrite PMKID */ 2332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (index = 0; index < NUM_PMKID_CACHE; index++) { 2333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!memcmp(psecuritypriv->PMKIDList[index].Bssid, 2334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmksa->bssid, ETH_ALEN)) { 2335b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* BSSID is matched, the same AP => rewrite with 2336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger new PMKID. */ 2337a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): BSSID exists in the PMKList.\n", 2338a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, netdev->name); 2339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2340b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv->PMKIDList[index].PMKID, 2341b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmksa->pmkid, WLAN_PMKID_LEN); 2342b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDList[index].bUsed = true; 2343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex = index + 1; 2344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger blInserted = true; 2345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2346b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2347b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!blInserted) { 2350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Find a new entry */ 2351a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): Use new entry index = %d for this PMKID\n", 2352a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, netdev->name, psecuritypriv->PMKIDIndex); 2353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex]. 2355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger Bssid, pmksa->bssid, ETH_ALEN); 2356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex]. 2357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger PMKID, pmksa->pmkid, WLAN_PMKID_LEN); 2358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2359b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = 2360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger true; 2361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex++; 2362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psecuritypriv->PMKIDIndex == 16) { 2363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex = 0; 2364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2369b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2370b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_pmksa(struct wiphy *wiphy, 2371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *netdev, 2372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_pmksa *pmksa) 2373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2374b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 index, bMatched = false; 2375b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 2377b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2378a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, netdev->name); 2379b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger for (index = 0; index < NUM_PMKID_CACHE; index++) { 2381b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!memcmp(psecuritypriv->PMKIDList[index].Bssid, 2382b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmksa->bssid, ETH_ALEN)) { 2383b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */ 238443c34be13047dd53e70bc4759ff314424db7036bJes Sorensen eth_zero_addr(psecuritypriv->PMKIDList[index].Bssid); 2385b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, 2386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_PMKID_LEN); 2387b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDList[index].bUsed = false; 2388b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bMatched = true; 2389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (false == bMatched) { 2394a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): do not have matched BSSID\n", __func__, 2395a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen netdev->name); 2396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2402b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy, 2403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *netdev) 2404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct security_priv *psecuritypriv = &padapter->securitypriv; 2407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2408a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, netdev->name); 2409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(&psecuritypriv->PMKIDList[0], 0x00, 2411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE); 2412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psecuritypriv->PMKIDIndex = 0; 2413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2414b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2415b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2417b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 2418b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter, 2419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *pmgmt_frame, uint frame_len) 2420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2421b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 freq; 2422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int channel; 2423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev = padapter->pnetdev; 2425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2426b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name); 2427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2428b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#if defined(RTW_USE_CFG80211_STA_EVENT) 2429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 2430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_info sinfo; 2431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 ie_offset; 2432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_is_assoc_req(hdr->frame_control)) 2433b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ie_offset = _ASOCREQ_IE_OFFSET_; 2434b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else /* WIFI_REASSOCREQ */ 2435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ie_offset = _REASOCREQ_IE_OFFSET_; 2436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo.filled = 0; 2438b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo.filled = STATION_INFO_ASSOC_REQ_IES; 2439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; 2440b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger sinfo.assoc_req_ies_len = 2441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger frame_len - WLAN_HDR_A3_LEN - ie_offset; 2442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC); 2443b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = pmlmeext->cur_channel; 2446b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 2447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 2449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 2450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 2452b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, 2454b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 2455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2456b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2458b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter, 2459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *da, 2460b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned short reason) 2461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 freq; 2463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int channel; 2464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *pmgmt_frame; 2465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint frame_len; 2466b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_hdr *pwlanhdr; 2467507a755dd78b782ed6e274803950759f81faf574Larry Finger __le16 *fctrl; 2468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 mgmt_buf[128] = { 0 }; 2469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 2471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev = padapter->pnetdev; 2472b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name); 2474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#if defined(RTW_USE_CFG80211_STA_EVENT) 2476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger cfg80211_del_sta(ndev, da, GFP_ATOMIC); 2477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = pmlmeext->cur_channel; 2479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 2480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 2482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 2483b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 2484b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 2485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2486b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmgmt_frame = mgmt_buf; 2487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwlanhdr = (struct ieee80211_hdr *)pmgmt_frame; 2488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger fctrl = &pwlanhdr->frame_control; 2490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *(fctrl) = 0; 2491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwlanhdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN); 2493b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwlanhdr->addr2, da, ETH_ALEN); 2494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); 2495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq++; 2498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger SetFrameSubType(pmgmt_frame, WIFI_DEAUTH); 2499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2500b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmgmt_frame += sizeof(struct ieee80211_hdr_3addr); 2501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger frame_len = sizeof(struct ieee80211_hdr_3addr); 2502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger reason = cpu_to_le16(reason); 2504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmgmt_frame = rtw_set_fixed_ie23a(pmgmt_frame, 2505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_REASON_PREV_AUTH_NOT_VALID, 2506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (unsigned char *)&reason, &frame_len); 2507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2508b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, 2509b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 2510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ 2511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2512b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2513b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_monitor_if_open(struct net_device *ndev) 2514b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2515b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2516b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2519b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2522b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_monitor_if_close(struct net_device *ndev) 2523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2524b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2525b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2527b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2531b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, 2532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev) 2533b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2534b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2535b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int rtap_len; 2536b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int qos_len = 0; 2537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int dot11_hdr_len = 24; 2538b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int snap_len = 6; 2539b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *pdata; 2540b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char src_mac_addr[6]; 2541b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char dst_mac_addr[6]; 2542b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_hdr *dot11_hdr; 2543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_radiotap_header *rtap_hdr; 2544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 2545b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2546a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) 2549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2550b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; 2552b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(rtap_hdr->it_version)) 2553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2554b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtap_len = ieee80211_get_radiotap_len(skb->data); 2556b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (unlikely(skb->len < rtap_len)) 2557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2559b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtap_len != 14) { 2560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("radiotap len (should be 14): %d\n", rtap_len); 2561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2562b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Skip the ratio tap header */ 2565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skb_pull(skb, rtap_len); 2566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2567b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11_hdr = (struct ieee80211_hdr *)skb->data; 2568b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Check if the QoS bit is set */ 2569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_is_data(dot11_hdr->frame_control)) { 2570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Check if this ia a Wireless Distribution System (WDS) frame 2571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * which has 4 MAC addresses 2572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 2573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_is_data_qos(dot11_hdr->frame_control)) 2574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger qos_len = IEEE80211_QOS_CTL_LEN; 2575b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ieee80211_has_a4(dot11_hdr->frame_control)) 2576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dot11_hdr_len += 6; 2577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2578b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr)); 2579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr)); 2580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 2582b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * Skip the 802.11 header, QoS (if any) and SNAP, 2583b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger * but leave spaces for two MAC addresses 2584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 2585b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger skb_pull(skb, dot11_hdr_len + qos_len + snap_len - 2586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ETH_ALEN * 2); 2587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pdata = (unsigned char *)skb->data; 2588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pdata, dst_mac_addr, ETH_ALEN); 2589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pdata + ETH_ALEN, src_mac_addr, ETH_ALEN); 2590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2591b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("should be eapol packet\n"); 2592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* Use the real net device to transmit the packet */ 2594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_xmit23a_entry23a(skb, padapter->pnetdev); 2595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2597b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if (ieee80211_is_action(dot11_hdr->frame_control)) { 2599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* only for action frames */ 2600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_frame *pmgntframe; 2601b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pkt_attrib *pattrib; 2602b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *pframe; 2603b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* u8 category, action, OUI_Subtype, dialogToken = 0; */ 2604b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* unsigned char *frame_body; */ 2605b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2607b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 len = skb->len; 2608b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 category, action; 2609b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2610b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_action_frame_parse23a(skb->data, len, &category, 2611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &action) == false) { 2612a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): frame_control:0x%x\n", 2613a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, 2614b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger le16_to_cpu(dot11_hdr->frame_control)); 2615b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2616b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2617b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2618a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("RTW_Tx:da =" MAC_FMT " via %s(%s)\n", 2619a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen MAC_ARG(dot11_hdr->addr1), __func__, ndev->name); 2620b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (category == WLAN_CATEGORY_PUBLIC) 2621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action)); 2622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 2623b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, 2624b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger action); 262598fb81291d30f83838379bf1522fead6673b5fdfJes Sorensen 2626b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* starting alloc mgmt frame to dump it */ 2627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmgntframe = alloc_mgtxmitframe23a(pxmitpriv); 2628b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmgntframe == NULL) 2629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto fail; 2630b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2631b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update attribute */ 2632b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib = &pmgntframe->attrib; 2633b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger update_mgntframe_attrib23a(padapter, pattrib); 2634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->retry_ctrl = false; 2635b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2638b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2639b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pframe, skb->data, len); 2641b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->pktlen = len; 2642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update seq number */ 2644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq = le16_to_cpu(dot11_hdr->seq_ctrl) >> 4; 2645b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->seqnum = pmlmeext->mgnt_seq; 2646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq++; 2647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2648b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->last_txcmdsz = pattrib->pktlen; 2649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2650b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dump_mgntframe23a(padapter, pmgntframe); 2651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2652b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2653b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfail: 2654b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2655b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dev_kfree_skb(skb); 2656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2659b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2660b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int 2661b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerrtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr) 2662b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2663b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2664b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2665b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s\n", __func__); 2666b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2669b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2670b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic const struct net_device_ops rtw_cfg80211_monitor_if_ops = { 2671b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_open = rtw_cfg80211_monitor_if_open, 2672b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_stop = rtw_cfg80211_monitor_if_close, 2673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry, 2674b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address, 2675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 2676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2677b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name, 2678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device **ndev) 2679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2680b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *mon_ndev = NULL; 2682b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *mon_wdev = NULL; 2683b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); 2684b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!name) { 26869cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): without specific name\n", 26879cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen __func__, padapter->pnetdev->name); 2688b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 2689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2691b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2692b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->pmon_ndev) { 26939cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): monitor interface exist: %s\n", __func__, 26949cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, pwdev_priv->pmon_ndev->name); 2695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EBUSY; 2696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2697b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2699b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev = alloc_etherdev(sizeof(struct rtw_adapter)); 2700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mon_ndev) { 27019cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): allocate ndev fail\n", __func__, 27029cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name); 2703b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 2704b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2707b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP; 2708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger strncpy(mon_ndev->name, name, IFNAMSIZ); 2709b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->name[IFNAMSIZ - 1] = 0; 2710b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->destructor = rtw_ndev_destructor; 2711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops; 2713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2714b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wdev */ 2715b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2716b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mon_wdev) { 27179cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): allocate mon_wdev fail\n", __func__, 27189cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name); 2719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 2720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev->wiphy = padapter->rtw_wdev->wiphy; 2724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev->netdev = mon_ndev; 2725b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev->iftype = NL80211_IFTYPE_MONITOR; 2726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_ndev->ieee80211_ptr = mon_wdev; 2727b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2728b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = register_netdevice(mon_ndev); 2729b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret) { 2730b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto out; 2731b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2732b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2733b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *ndev = pwdev_priv->pmon_ndev = mon_ndev; 2734b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1); 2735b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2736b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerout: 2737b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret) { 2738b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(mon_wdev); 2739b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger mon_wdev = NULL; 2740b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2741b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2742b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret && mon_ndev) { 2743b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger free_netdev(mon_ndev); 2744b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *ndev = mon_ndev = NULL; 2745b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2746b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2747b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2748b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2749b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2750b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct wireless_dev * 2751b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingercfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name, 2752b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum nl80211_iftype type, u32 *flags, 2753b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct vif_params *params) 2754b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2755b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2756b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev = NULL; 2757b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = wiphy_to_adapter(wiphy); 2758b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 27599cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): wiphy:%s, name:%s, type:%d\n", __func__, 27609cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, wiphy_name(wiphy), name, type); 2761b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2762b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (type) { 2763b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_ADHOC: 2764b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_AP_VLAN: 2765b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_WDS: 2766b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_MESH_POINT: 2767b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2768b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2769b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_MONITOR: 2770b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 2771b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); 2772b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2773b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2774b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_CLIENT: 2775b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_STATION: 2776b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2777b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2778b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2779b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_P2P_GO: 2780b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case NL80211_IFTYPE_AP: 2781b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2782b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2783b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger default: 2784b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENODEV; 2785b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Unsupported interface type\n"); 2786b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2787b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2788b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 27899cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): ndev:%p, ret:%d\n", __func__, 27909cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, 2791b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndev, ret); 2792b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2793b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret); 2794b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2795b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2796b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, 2797b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev) 2798b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2799b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv = 2800b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct rtw_wdev_priv *)wiphy_priv(wiphy); 2801b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev; 2802b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ndev = wdev ? wdev->netdev : NULL; 2803b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2804b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!ndev) 2805b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 2806b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2807b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unregister_netdevice(ndev); 2808b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2809b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ndev == pwdev_priv->pmon_ndev) { 2810b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->pmon_ndev = NULL; 2811b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->ifname_mon[0] = '\0'; 2812a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): remove monitor interface\n", 2813a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name); 2814b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2815b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2816b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 2817b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2818b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2819b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2820b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head, 2821b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t head_len, const u8 *tail, size_t tail_len) 2822b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2823b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2824b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *pbuf = NULL; 2825b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint len, wps_ielen = 0; 2826b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 2827b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* struct sta_priv *pstapriv = &padapter->stapriv; */ 2828b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2829b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n", 2830b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, head_len, tail_len); 2831b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2832b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 2833b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2834b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2835b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (head_len < 24) 2836b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2837b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2838b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbuf = kzalloc(head_len + tail_len, GFP_KERNEL); 2839b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!pbuf) 2840b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -ENOMEM; 2841b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 24 = beacon header len. */ 2842b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pbuf, (void *)head + 24, head_len - 24); 2843b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pbuf + head_len - 24, (void *)tail, tail_len); 2844b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2845b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger len = head_len + tail_len - 24; 2846b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2847b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* check wps ie if inclued */ 2848b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_get_wps_ie23a 2849b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, 2850b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &wps_ielen)) 2851b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen); 2852b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2853b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* pbss_network->IEs will not include p2p_ie, wfd ie */ 28549300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, 28559300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen WLAN_EID_VENDOR_SPECIFIC, P2P_OUI23A, 4); 28569300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, 28579300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen WLAN_EID_VENDOR_SPECIFIC, WFD_OUI23A, 4); 2858b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2859b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_check_beacon_data23a(adapter, pbuf, len) == _SUCCESS) { 2860b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 0; 2861b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 2862b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EINVAL; 2863b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2864b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2865b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pbuf); 2866b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2867b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2868b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2869b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2870b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, 2871b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_ap_settings *settings) 2872b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2873b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2874b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *adapter = wiphy_to_adapter(wiphy); 2875b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2876a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): hidden_ssid:%d, auth_type:%d\n", 2877a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen __func__, ndev->name, settings->hidden_ssid, 2878b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->auth_type); 2879b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2880b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_add_beacon(adapter, settings->beacon.head, 2881b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->beacon.head_len, settings->beacon.tail, 2882b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->beacon.tail_len); 2883b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2884b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = 2885b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->hidden_ssid; 2886b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2887b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (settings->ssid && settings->ssid_len) { 2888b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_bssid_ex *pbss_network = 2889b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &adapter->mlmepriv.cur_network.network; 2890b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wlan_bssid_ex *pbss_network_ext = 2891b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &adapter->mlmeextpriv.mlmext_info.network; 2892b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2893b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pbss_network->Ssid.ssid, (void *)settings->ssid, 2894b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->ssid_len); 2895b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbss_network->Ssid.ssid_len = settings->ssid_len; 2896b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pbss_network_ext->Ssid.ssid, (void *)settings->ssid, 2897b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger settings->ssid_len); 2898b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pbss_network_ext->Ssid.ssid_len = settings->ssid_len; 2899b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2900b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2901b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2902b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2903b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2904b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_beacon(struct wiphy *wiphy, 2905b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, 2906b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_beacon_data *info) 2907b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2908b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2909b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *adapter = wiphy_to_adapter(wiphy); 2910b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2911a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2912b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2913b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, 2914b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger info->tail_len); 2915b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2916b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2917b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2918b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2919b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev) 2920b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2921a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2922b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2923b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2924b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2925b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_add_station(struct wiphy *wiphy, 2926b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, u8 *mac, 2927b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_parameters *params) 2928b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2929a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 2930b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2931b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 2932b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 2933b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2934b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_del_station(struct wiphy *wiphy, 2935b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, u8 *mac) 2936b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 2937b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 2938b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct list_head *phead, *plist, *ptmp; 2939b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 updated = 0; 2940b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_info *psta; 2941b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 2942b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2943b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct sta_priv *pstapriv = &padapter->stapriv; 2944b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2945a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("+%s(%s)\n", __func__, ndev->name); 2946b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2947b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true) { 2948b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", 2949b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__); 2950b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2951b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2952b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2953b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!mac) { 2954b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("flush all sta, and cam_entry\n"); 2955b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2956b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger flush_all_cam_entry23a(padapter); /* clear CAM */ 2957b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2958b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = rtw_sta_flush23a(padapter); 2959b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2960b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 2961b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2962b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2963b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac)); 2964b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2965b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (is_broadcast_ether_addr(mac)) 2966b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 2967b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2968b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_bh(&pstapriv->asoc_list_lock); 2969b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2970b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger phead = &pstapriv->asoc_list; 2971b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2972b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* check asoc_queue */ 2973b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_for_each_safe(plist, ptmp, phead) { 2974b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = container_of(plist, struct sta_info, asoc_list); 2975b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2976b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!memcmp(mac, psta->hwaddr, ETH_ALEN)) { 2977b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (psta->dot8021xalg == 1 && 2978b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->bpairwise_key_installed == false) { 2979b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, sta's dot8021xalg = 1 and " 2980b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "key_installed = false\n", __func__); 2981b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 2982b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("free psta =%p, aid =%d\n", psta, 2983b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta->aid); 2984b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2985b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger list_del_init(&psta->asoc_list); 2986b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pstapriv->asoc_list_cnt--; 2987b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2988b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* spin_unlock_bh(&pstapriv->asoc_list_lock); */ 2989b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger updated = 2990b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ap_free_sta23a(padapter, psta, true, 2991b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WLAN_REASON_DEAUTH_LEAVING); 2992b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* spin_lock_bh(&pstapriv->asoc_list_lock); */ 2993b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2994b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger psta = NULL; 2995b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 2996b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 2997b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2998b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 2999b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3000b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3001b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_unlock_bh(&pstapriv->asoc_list_lock); 3002b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3003b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger associated_clients_update23a(padapter, updated); 3004b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3005a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("-%s(%s)\n", __func__, ndev->name); 3006b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3007b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3008b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3009b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3010b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_station(struct wiphy *wiphy, 3011b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, u8 *mac, 3012b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_parameters *params) 3013b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3014a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 3015b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 3016b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3017b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3018b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_dump_station(struct wiphy *wiphy, 3019b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *ndev, int idx, u8 *mac, 3020b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct station_info *sinfo) 3021b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3022a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 3023b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3024b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* TODO: dump scanned queue */ 3025b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3026b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -ENOENT; 3027b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3028b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3029b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev, 3030b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct bss_parameters *params) 3031b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3032a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s)\n", __func__, ndev->name); 3033b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return 0; 3034b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3035b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* CONFIG_8723AU_AP_MODE */ 3036b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3037b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_rx_action_p2p(struct rtw_adapter *padapter, u8 *pmgmt_frame, 3038b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint frame_len) 3039b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3040b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 freq; 3041b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int channel; 3042b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 category, action; 3043b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3044b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = rtw_get_oper_ch23a(padapter); 3045b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3046b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Rx:cur_ch =%d\n", channel); 3047b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action); 3048b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action); 3049b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3050b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 3051b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 3052b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 3053b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3054b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 3055b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 3056b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3057b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, 3058b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 3059b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3060b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3061b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_rx_p2p_action_public(struct rtw_adapter *padapter, 3062b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *pmgmt_frame, uint frame_len) 3063b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3064b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 freq; 3065b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int channel; 3066b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 category, action; 3067b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3068b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = rtw_get_oper_ch23a(padapter); 3069b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3070b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Rx:cur_ch =%d\n", channel); 3071b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action); 3072b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action); 3073b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3074b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 3075b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 3076b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 3077b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3078b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 3079b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 3080b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3081b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, 3082b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_ATOMIC); 3083b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3084b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3085b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_rx_action(struct rtw_adapter *adapter, u8 *frame, 3086b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint frame_len, const char *msg) 3087b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3088b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger s32 freq; 3089b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int channel; 3090b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 category, action; 3091b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3092b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger channel = rtw_get_oper_ch23a(adapter); 3093b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3094b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_action_frame_parse23a(frame, frame_len, &category, &action); 3095b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3096b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Rx:cur_ch =%d\n", channel); 3097b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (msg) 3098b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Rx:%s\n", msg); 3099b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3100b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, 3101b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger action); 3102b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3103b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (channel <= RTW_CH_MAX_2G_CHANNEL) 3104b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 3105b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ); 3106b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3107b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger freq = ieee80211_channel_to_frequency(channel, 3108b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ); 3109b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3110b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC); 3111b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3112b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3113b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch, 3114b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *buf, size_t len) 3115b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3116b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_frame *pmgntframe; 3117b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct pkt_attrib *pattrib; 3118b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned char *pframe; 3119b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = _FAIL; 3120b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool ack = true; 3121b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_hdr *pwlanhdr; 3122b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 3123b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 3124b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3125b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (_FAIL == rtw_pwr_wakeup(padapter)) { 3126b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -EFAULT; 3127b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 3128b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3129b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3130b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_scan_deny(padapter, 1000); 3131b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3132b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_scan_abort23a(padapter); 3133b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3134b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (tx_ch != rtw_get_oper_ch23a(padapter)) { 3135b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) 3136b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->cur_channel = tx_ch; 3137b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_channel_bwmode23a(padapter, tx_ch, 3138b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger HAL_PRIME_CHNL_OFFSET_DONT_CARE, 3139b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger HT_CHANNEL_WIDTH_20); 3140b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3141b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3142b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* starting alloc mgmt frame to dump it */ 3143b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmgntframe = alloc_mgtxmitframe23a(pxmitpriv); 3144b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmgntframe == NULL) { 3145b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* ret = -ENOMEM; */ 3146b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = _FAIL; 3147b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 3148b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3149b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3150b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update attribute */ 3151b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib = &pmgntframe->attrib; 3152b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger update_mgntframe_attrib23a(padapter, pattrib); 3153b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->retry_ctrl = false; 3154b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3155b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3156b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3157b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET; 3158b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3159b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pframe, (void *)buf, len); 3160b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->pktlen = len; 3161b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3162b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwlanhdr = (struct ieee80211_hdr *)pframe; 3163b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* update seq number */ 3164b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq = le16_to_cpu(pwlanhdr->seq_ctrl) >> 4; 3165b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->seqnum = pmlmeext->mgnt_seq; 3166b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->mgnt_seq++; 3167b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3168b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pattrib->last_txcmdsz = pattrib->pktlen; 3169b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3170b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe) != _SUCCESS) { 3171b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ack = false; 3172b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = _FAIL; 3173b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3174b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ack == _FAIL\n", __func__); 3175b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 3176b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ack =%d, ok!\n", __func__, ack); 3177b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = _SUCCESS; 3178b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3179b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3180b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 3181b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3182b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ret =%d\n", __func__, ret); 3183b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3184b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3185b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3186b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3187b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3188b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) 3189b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_channel *chan, 3190b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool offchan, 3191b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned int wait, 3192b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *buf, size_t len, 3193b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool no_cck, bool dont_wait_for_ack, 3194b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#else 3195b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct cfg80211_mgmt_tx_params *params, 3196b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 3197b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u64 *cookie) 3198b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3199b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = 3200b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger (struct rtw_adapter *)wiphy_to_adapter(wiphy); 3201b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); 3202b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 3203b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int tx_ret; 3204b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 dump_limit = RTW_MAX_MGMT_TX_CNT; 3205b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u32 dump_cnt = 0; 3206b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bool ack = true; 3207b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 category, action; 3208b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int type = (-1); 3209b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unsigned long start = jiffies; 3210b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) 3211b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger size_t len = params->len; 3212b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_channel *chan = params->chan; 3213b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger const u8 *buf = params->buf; 3214b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 3215b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buf; 3216b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 tx_ch = (u8) ieee80211_frequency_to_channel(chan->center_freq); 3217b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3218b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* cookie generation */ 3219b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *cookie = (unsigned long)buf; 3220b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 32219cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): len =%zu, ch =%d\n", __func__, 32229cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, len, tx_ch); 3223b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3224b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* indicate ack before issue frame to avoid racing with rsp frame */ 3225b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, 3226b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger GFP_KERNEL); 3227b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3228b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rtw_action_frame_parse23a(buf, len, &category, &action) == false) { 32299cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): frame_control:0x%x\n", __func__, 32309cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen padapter->pnetdev->name, 3231b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger le16_to_cpu(hdr->frame_control)); 3232b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 3233b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3234b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3235b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Tx:tx_ch =%d, da =" MAC_FMT "\n", tx_ch, 3236b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger MAC_ARG(hdr->addr1)); 3237b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (category == WLAN_CATEGORY_PUBLIC) 3238b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action)); 3239b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3240b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("RTW_Tx:category(%u), action(%u)\n", 3241b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger category, action); 3242b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3243b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger do { 3244b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dump_cnt++; 3245b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len); 3246b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } while (dump_cnt < dump_limit && tx_ret != _SUCCESS); 3247b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3248b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (tx_ret != _SUCCESS || dump_cnt > 1) { 32499cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): %s (%d/%d) in %d ms\n", 32509cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen __func__, padapter->pnetdev->name, 3251b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt, 3252b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger dump_limit, jiffies_to_msecs(jiffies - start)); 3253b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3254b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3255b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (type) { 3256b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case P2P_GO_NEGO_CONF: 3257b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_clear_scan_deny(padapter); 3258b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 3259b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case P2P_INVIT_RESP: 3260b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->invit_info.flags & BIT(0) 3261b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger && pwdev_priv->invit_info.status == 0) { 32629cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen DBG_8723A("%s(%s): agree with invitation of " 3263b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger "persistent group\n", 32649cd613c739ee436862e681acad8ded18ff85fd9aJes Sorensen __func__, padapter->pnetdev->name); 3265b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_set_scan_deny(padapter, 5000); 3266b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_pwr_wakeup_ex(padapter, 5000); 3267b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_clear_scan_deny(padapter); 3268b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3269b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 3270b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3271b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3272b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 3273b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3274b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3275b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3276b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, 3277b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev, 3278b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 frame_type, bool reg) 3279b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3280b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) 3281b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3282b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3283b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3284b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3285b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3286b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, 3287b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int len) 3288b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3289b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 3290b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint wps_ielen = 0; 3291b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 *wps_ie; 3292c17416ef707312429aafcdc4597db73906f3572eLarry Finger#ifdef CONFIG_8723AU_AP_MODE 3293c17416ef707312429aafcdc4597db73906f3572eLarry Finger u8 wps_oui[8] = { 0x0, 0x50, 0xf2, 0x04 }; 3294c17416ef707312429aafcdc4597db73906f3572eLarry Finger#endif 3295b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(ndev); 3296b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 3297b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 3298b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3299a790d58e6832262692416d41af99670b7aa1dca4Jes Sorensen DBG_8723A("%s(%s): ielen =%d\n", __func__, ndev->name, len); 3300b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3301b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (len > 0) { 3302b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen); 3303b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wps_ie) { 3304b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("bcn_wps_ielen =%d\n", wps_ielen); 3305b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3306b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_beacon_ie) { 3307b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_beacon_ie_len = 0; 3308b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pmlmepriv->wps_beacon_ie); 3309b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_beacon_ie = NULL; 3310b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3311b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3312b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_beacon_ie = 3313b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kmalloc(wps_ielen, GFP_KERNEL); 3314b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_beacon_ie == NULL) { 3315b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s()-%d: kmalloc() ERROR!\n", 3316b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, __LINE__); 3317b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 3318b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3319b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen); 3320b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_beacon_ie_len = wps_ielen; 3321b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3322c17416ef707312429aafcdc4597db73906f3572eLarry Finger#ifdef CONFIG_8723AU_AP_MODE 33239300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen update_beacon23a(padapter, WLAN_EID_VENDOR_SPECIFIC, 33249300c94b8a817f3b96cf00d2bdeed6751c2744d8Jes Sorensen wps_oui, true); 3325c17416ef707312429aafcdc4597db73906f3572eLarry Finger#endif 3326b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3327b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3328b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmeext->bstart_bss = true; 3329b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3330b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3331b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3332b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3333b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3334b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3335b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, 3336b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger char *buf, int len) 3337b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3338b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(net); 3339b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 3340c17416ef707312429aafcdc4597db73906f3572eLarry Finger int ret = 0; 3341c17416ef707312429aafcdc4597db73906f3572eLarry Finger uint wps_ielen = 0; 3342c17416ef707312429aafcdc4597db73906f3572eLarry Finger u8 *wps_ie; 3343b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3344b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (len > 0) { 3345b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen); 3346b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (wps_ie) { 3347b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint attr_contentlen = 0; 3348b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u16 uconfig_method, *puconfig_method = NULL; 3349b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3350b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_probe_resp_ie) { 3351b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_resp_ie_len = 0; 3352b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pmlmepriv->wps_probe_resp_ie); 3353b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_resp_ie = NULL; 3354b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3355b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3356b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_resp_ie = 3357b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kmalloc(wps_ielen, GFP_KERNEL); 3358b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_probe_resp_ie == NULL) { 3359b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s()-%d: kmalloc() ERROR!\n", 3360b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, __LINE__); 3361b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 3362b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3363b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3364b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3365b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* add PUSH_BUTTON config_method by driver self in 3366b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wpsie of probe_resp at GO Mode */ 3367b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger puconfig_method = (u16 *)rtw_get_wps_attr_content23a(wps_ie, wps_ielen, 3368b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger WPS_ATTR_CONF_METHOD, 3369b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger NULL, 3370b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger &attr_contentlen); 3371b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (puconfig_method) { 3372b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uconfig_method = WPS_CM_PUSH_BUTTON; 3373b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uconfig_method = cpu_to_be16(uconfig_method); 3374b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3375b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *puconfig_method |= uconfig_method; 3376b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3377b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3378b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen); 3379b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_probe_resp_ie_len = wps_ielen; 3380b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3381b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3382b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3383b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3384b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3385b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3386b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3387b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3388b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, 3389b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger char *buf, int len) 3390b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3391b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 3392b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_adapter *padapter = netdev_priv(net); 3393b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 3394b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3395b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ielen =%d\n", __func__, len); 3396b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3397b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (len > 0) { 3398b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_assoc_resp_ie) { 3399b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_assoc_resp_ie_len = 0; 3400b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(pmlmepriv->wps_assoc_resp_ie); 3401b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_assoc_resp_ie = NULL; 3402b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3403b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3404b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_assoc_resp_ie = kmalloc(len, GFP_KERNEL); 3405b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pmlmepriv->wps_assoc_resp_ie == NULL) { 3406b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s()-%d: kmalloc() ERROR!\n", 3407b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger __func__, __LINE__); 3408b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return -EINVAL; 3409b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3410b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3411b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len); 3412b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pmlmepriv->wps_assoc_resp_ie_len = len; 3413b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3414b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3415b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3416b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3417b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3418b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, 3419b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int type) 3420b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3421b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 3422b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger uint wps_ielen = 0; 3423b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3424b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, ielen =%d\n", __func__, len); 3425b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 342698fb81291d30f83838379bf1522fead6673b5fdfJes Sorensen if (rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen) && (wps_ielen > 0)) { 3427b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (net) { 3428b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger switch (type) { 3429b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case 0x1: /* BEACON */ 3430b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 3431b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_set_beacon_wpsp2pie(net, buf, 3432b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger len); 3433b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 3434b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case 0x2: /* PROBE_RESP */ 3435b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 3436b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_set_probe_resp_wpsp2pie(net, 3437b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger buf, 3438b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger len); 3439b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 3440b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger case 0x4: /* ASSOC_RESP */ 3441b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = 3442b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_set_assoc_resp_wpsp2pie(net, 3443b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger buf, 3444b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger len); 3445b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger break; 3446b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3447b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3448b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3449b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3450b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3451b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3452b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3453b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3454b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic struct cfg80211_ops rtw_cfg80211_ops = { 3455b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_virtual_intf = cfg80211_rtw_change_iface, 3456b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .add_key = cfg80211_rtw_add_key, 3457b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .get_key = cfg80211_rtw_get_key, 3458b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_key = cfg80211_rtw_del_key, 3459b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_default_key = cfg80211_rtw_set_default_key, 3460b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .get_station = cfg80211_rtw_get_station, 3461b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .scan = cfg80211_rtw_scan, 3462b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_wiphy_params = cfg80211_rtw_set_wiphy_params, 3463b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .connect = cfg80211_rtw_connect, 3464b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .disconnect = cfg80211_rtw_disconnect, 3465b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .join_ibss = cfg80211_rtw_join_ibss, 3466b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .leave_ibss = cfg80211_rtw_leave_ibss, 3467b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_tx_power = cfg80211_rtw_set_txpower, 3468b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .get_tx_power = cfg80211_rtw_get_txpower, 3469b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_power_mgmt = cfg80211_rtw_set_power_mgmt, 3470b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .set_pmksa = cfg80211_rtw_set_pmksa, 3471b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_pmksa = cfg80211_rtw_del_pmksa, 3472b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .flush_pmksa = cfg80211_rtw_flush_pmksa, 3473b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3474b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 3475b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .add_virtual_intf = cfg80211_rtw_add_virtual_intf, 3476b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_virtual_intf = cfg80211_rtw_del_virtual_intf, 3477b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3478b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .start_ap = cfg80211_rtw_start_ap, 3479b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_beacon = cfg80211_rtw_change_beacon, 3480b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .stop_ap = cfg80211_rtw_stop_ap, 3481b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3482b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .add_station = cfg80211_rtw_add_station, 3483b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .del_station = cfg80211_rtw_del_station, 3484b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_station = cfg80211_rtw_change_station, 3485b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .dump_station = cfg80211_rtw_dump_station, 3486b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .change_bss = cfg80211_rtw_change_bss, 3487b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* CONFIG_8723AU_AP_MODE */ 3488b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3489b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .mgmt_tx = cfg80211_rtw_mgmt_tx, 3490b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, 3491b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger}; 3492b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3493b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, 3494b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger enum ieee80211_band band, u8 rf_type) 3495b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3496b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3497b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ 3498b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ 3499b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3500b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->ht_supported = true; 3501b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3502b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 3503b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | 3504b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; 3505b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3506b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3507b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *Maximum length of AMPDU that the STA can receive. 3508b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) 3509b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 3510b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 3511b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3512b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /*Minimum MPDU start spacing , */ 3513b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; 3514b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3515b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 3516b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3517b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3518b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *hw->wiphy->bands[IEEE80211_BAND_2GHZ] 3519b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *base on ant_num 3520b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *rx_mask: RX mask 3521b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7 3522b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15 3523b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if rx_ant >= 3 rx_mask[2]= 0xff; 3524b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *if BW_40 rx_mask[4]= 0x01; 3525b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger *highest supported RX rate 3526b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 3527b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (rf_type == RF_1T1R) { 3528b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[0] = 0xFF; 3529b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[1] = 0x00; 3530b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[4] = 0x01; 3531b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3532b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7; 3533b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R)) { 3534b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[0] = 0xFF; 3535b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[1] = 0xFF; 3536b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_mask[4] = 0x01; 3537b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3538b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15; 3539b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } else { 3540b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, error rf_type =%d\n", __func__, rf_type); 3541b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3542b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3543b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3544b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3545b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter) 3546b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3547b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger u8 rf_type; 3548b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct ieee80211_supported_band *bands; 3549b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *pwdev = padapter->rtw_wdev; 3550b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy = pwdev->wiphy; 3551b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3552c2370e83ab5432e2d32e9c097930c69366d27b4cJes Sorensen rf_type = rtl8723a_get_rf_type(padapter); 3553b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3554b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s:rf_type =%d\n", __func__, rf_type); 3555b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3556b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */ 3557b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 3558b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bands = wiphy->bands[IEEE80211_BAND_2GHZ]; 3559b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (bands) 3560b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_init_ht_capab(&bands->ht_cap, 3561b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_2GHZ, 3562b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rf_type); 3563b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3564b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3565b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */ 3566b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger { 3567b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger bands = wiphy->bands[IEEE80211_BAND_5GHZ]; 3568b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (bands) 3569b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_init_ht_capab(&bands->ht_cap, 3570b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger IEEE80211_BAND_5GHZ, 3571b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rf_type); 3572b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3573b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3574b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3575b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerstatic void rtw_cfg80211_preinit_wiphy(struct rtw_adapter *padapter, 3576b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy) 3577b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3578b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 3579b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3580b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT; 3581b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 3582b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS; 3583b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3584b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->max_remain_on_channel_duration = 3585b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger RTW_MAX_REMAIN_ON_CHANNEL_DURATION; 3586b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3587b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 3588b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(NL80211_IFTYPE_ADHOC) | 3589b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 3590b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | 3591b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif 3592b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 0; 3593b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3594b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#ifdef CONFIG_8723AU_AP_MODE 3595b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes; 3596b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger#endif /* CONFIG_8723AU_AP_MODE */ 3597b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3598b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); 3599b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3600b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* 3601b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->iface_combinations = &rtw_combinations; 3602b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->n_iface_combinations = 1; 3603b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger */ 3604b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3605b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->cipher_suites = rtw_cipher_suites; 3606b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites); 3607b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3608b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */ 3609b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->bands[IEEE80211_BAND_2GHZ] = 3610b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_spt_band_alloc(IEEE80211_BAND_2GHZ); 3611b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */ 3612b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->bands[IEEE80211_BAND_5GHZ] = 3613b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_spt_band_alloc(IEEE80211_BAND_5GHZ); 3614b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3615b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 3616b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; 3617b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3618b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) 3619b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; 3620b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3621b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 3622b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3623b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3624b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerint rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev) 3625b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3626b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger int ret = 0; 3627b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wiphy *wiphy; 3628b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct wireless_dev *wdev; 3629b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv; 3630b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct net_device *pnetdev = padapter->pnetdev; 3631b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3632b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(padapter =%p)\n", __func__, padapter); 3633b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3634b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wiphy */ 3635b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv)); 3636b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wiphy) { 3637b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Couldn't allocate wiphy device\n"); 3638b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 3639b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto exit; 3640b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3641b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger set_wiphy_dev(wiphy, dev); 3642b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_preinit_wiphy(padapter, wiphy); 3643b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3644b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = wiphy_register(wiphy); 3645b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (ret < 0) { 3646b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Couldn't register wiphy device\n"); 3647b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto free_wiphy; 3648b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3649b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3650b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wdev */ 3651b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 3652b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wdev) { 3653b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("Couldn't allocate wireless device\n"); 3654b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger ret = -ENOMEM; 3655b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger goto unregister_wiphy; 3656b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3657b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wdev->wiphy = wiphy; 3658b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wdev->netdev = pnetdev; 3659b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* wdev->iftype = NL80211_IFTYPE_STATION; */ 3660b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* for rtw_setopmode_cmd23a() in cfg80211_rtw_change_iface() */ 3661b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wdev->iftype = NL80211_IFTYPE_MONITOR; 3662b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger padapter->rtw_wdev = wdev; 3663b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pnetdev->ieee80211_ptr = wdev; 3664b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3665b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger /* init pwdev_priv */ 3666b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv = wdev_to_priv(wdev); 3667b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->rtw_wdev = wdev; 3668b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->pmon_ndev = NULL; 3669b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->ifname_mon[0] = '\0'; 3670b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->padapter = padapter; 3671b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->scan_request = NULL; 3672b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger spin_lock_init(&pwdev_priv->scan_req_lock); 3673b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3674b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->p2p_enabled = false; 3675b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->provdisc_req_issued = false; 3676b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_wdev_invit_info_init(&pwdev_priv->invit_info); 3677b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3678b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) 3679b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->power_mgmt = true; 3680b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger else 3681b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv->power_mgmt = false; 3682b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3683b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3684b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerunregister_wiphy: 3685b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy_unregister(wiphy); 3686b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerfree_wiphy: 3687b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy_free(wiphy); 3688b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingerexit: 3689b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return ret; 3690b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3691b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3692b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_wdev_free(struct wireless_dev *wdev) 3693b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3694b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(wdev =%p)\n", __func__, wdev); 3695b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3696b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wdev) 3697b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3698b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3699b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]); 3700b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]); 3701b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3702b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy_free(wdev->wiphy); 3703b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3704b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger kfree(wdev); 3705b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3706b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3707b1925ad84625302fac456d8671b2acafcabf57f5Larry Fingervoid rtw_wdev_unregister(struct wireless_dev *wdev) 3708b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger{ 3709b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger struct rtw_wdev_priv *pwdev_priv; 3710b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3711b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s(wdev =%p)\n", __func__, wdev); 3712b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3713b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (!wdev) 3714b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger return; 3715b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3716b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger pwdev_priv = wdev_to_priv(wdev); 3717b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3718b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger rtw_cfg80211_indicate_scan_done(pwdev_priv, true); 3719b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3720b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger if (pwdev_priv->pmon_ndev) { 3721b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger DBG_8723A("%s, unregister monitor interface\n", __func__); 3722b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger unregister_netdev(pwdev_priv->pmon_ndev); 3723b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger } 3724b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger 3725b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger wiphy_unregister(wdev->wiphy); 3726b1925ad84625302fac456d8671b2acafcabf57f5Larry Finger} 3727