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