cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cfg80211.c (127456B)


      1/*
      2 * NXP Wireless LAN device driver: CFG80211
      3 *
      4 * Copyright 2011-2020 NXP
      5 *
      6 * This software file (the "File") is distributed by NXP
      7 * under the terms of the GNU General Public License Version 2, June 1991
      8 * (the "License").  You may use, redistribute and/or modify this File in
      9 * accordance with the terms and conditions of the License, a copy of which
     10 * is available by writing to the Free Software Foundation, Inc.,
     11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
     12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
     13 *
     14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
     15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
     16 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
     17 * this warranty disclaimer.
     18 */
     19
     20#include "cfg80211.h"
     21#include "main.h"
     22#include "11n.h"
     23#include "wmm.h"
     24
     25static char *reg_alpha2;
     26module_param(reg_alpha2, charp, 0);
     27
     28static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
     29	{
     30		.max = MWIFIEX_MAX_BSS_NUM,
     31		.types = BIT(NL80211_IFTYPE_STATION) |
     32				   BIT(NL80211_IFTYPE_P2P_GO) |
     33				   BIT(NL80211_IFTYPE_P2P_CLIENT) |
     34				   BIT(NL80211_IFTYPE_AP),
     35	},
     36};
     37
     38static const struct ieee80211_iface_combination
     39mwifiex_iface_comb_ap_sta = {
     40	.limits = mwifiex_ap_sta_limits,
     41	.num_different_channels = 1,
     42	.n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
     43	.max_interfaces = MWIFIEX_MAX_BSS_NUM,
     44	.beacon_int_infra_match = true,
     45	.radar_detect_widths =	BIT(NL80211_CHAN_WIDTH_20_NOHT) |
     46				BIT(NL80211_CHAN_WIDTH_20) |
     47				BIT(NL80211_CHAN_WIDTH_40),
     48};
     49
     50static const struct ieee80211_iface_combination
     51mwifiex_iface_comb_ap_sta_vht = {
     52	.limits = mwifiex_ap_sta_limits,
     53	.num_different_channels = 1,
     54	.n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
     55	.max_interfaces = MWIFIEX_MAX_BSS_NUM,
     56	.beacon_int_infra_match = true,
     57	.radar_detect_widths =	BIT(NL80211_CHAN_WIDTH_20_NOHT) |
     58				BIT(NL80211_CHAN_WIDTH_20) |
     59				BIT(NL80211_CHAN_WIDTH_40) |
     60				BIT(NL80211_CHAN_WIDTH_80),
     61};
     62
     63static const struct
     64ieee80211_iface_combination mwifiex_iface_comb_ap_sta_drcs = {
     65	.limits = mwifiex_ap_sta_limits,
     66	.num_different_channels = 2,
     67	.n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
     68	.max_interfaces = MWIFIEX_MAX_BSS_NUM,
     69	.beacon_int_infra_match = true,
     70};
     71
     72/*
     73 * This function maps the nl802.11 channel type into driver channel type.
     74 *
     75 * The mapping is as follows -
     76 *      NL80211_CHAN_NO_HT     -> IEEE80211_HT_PARAM_CHA_SEC_NONE
     77 *      NL80211_CHAN_HT20      -> IEEE80211_HT_PARAM_CHA_SEC_NONE
     78 *      NL80211_CHAN_HT40PLUS  -> IEEE80211_HT_PARAM_CHA_SEC_ABOVE
     79 *      NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW
     80 *      Others                 -> IEEE80211_HT_PARAM_CHA_SEC_NONE
     81 */
     82u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
     83{
     84	switch (chan_type) {
     85	case NL80211_CHAN_NO_HT:
     86	case NL80211_CHAN_HT20:
     87		return IEEE80211_HT_PARAM_CHA_SEC_NONE;
     88	case NL80211_CHAN_HT40PLUS:
     89		return IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
     90	case NL80211_CHAN_HT40MINUS:
     91		return IEEE80211_HT_PARAM_CHA_SEC_BELOW;
     92	default:
     93		return IEEE80211_HT_PARAM_CHA_SEC_NONE;
     94	}
     95}
     96
     97/* This function maps IEEE HT secondary channel type to NL80211 channel type
     98 */
     99u8 mwifiex_get_chan_type(struct mwifiex_private *priv)
    100{
    101	struct mwifiex_channel_band channel_band;
    102	int ret;
    103
    104	ret = mwifiex_get_chan_info(priv, &channel_band);
    105
    106	if (!ret) {
    107		switch (channel_band.band_config.chan_width) {
    108		case CHAN_BW_20MHZ:
    109			if (IS_11N_ENABLED(priv))
    110				return NL80211_CHAN_HT20;
    111			else
    112				return NL80211_CHAN_NO_HT;
    113		case CHAN_BW_40MHZ:
    114			if (channel_band.band_config.chan2_offset ==
    115			    SEC_CHAN_ABOVE)
    116				return NL80211_CHAN_HT40PLUS;
    117			else
    118				return NL80211_CHAN_HT40MINUS;
    119		default:
    120			return NL80211_CHAN_HT20;
    121		}
    122	}
    123
    124	return NL80211_CHAN_HT20;
    125}
    126
    127/*
    128 * This function checks whether WEP is set.
    129 */
    130static int
    131mwifiex_is_alg_wep(u32 cipher)
    132{
    133	switch (cipher) {
    134	case WLAN_CIPHER_SUITE_WEP40:
    135	case WLAN_CIPHER_SUITE_WEP104:
    136		return 1;
    137	default:
    138		break;
    139	}
    140
    141	return 0;
    142}
    143
    144/*
    145 * This function retrieves the private structure from kernel wiphy structure.
    146 */
    147static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy)
    148{
    149	return (void *) (*(unsigned long *) wiphy_priv(wiphy));
    150}
    151
    152/*
    153 * CFG802.11 operation handler to delete a network key.
    154 */
    155static int
    156mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
    157			 u8 key_index, bool pairwise, const u8 *mac_addr)
    158{
    159	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
    160	static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    161	const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
    162
    163	if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index, peer_mac, 1)) {
    164		mwifiex_dbg(priv->adapter, ERROR, "deleting the crypto keys\n");
    165		return -EFAULT;
    166	}
    167
    168	mwifiex_dbg(priv->adapter, INFO, "info: crypto keys deleted\n");
    169	return 0;
    170}
    171
    172/*
    173 * This function forms an skb for management frame.
    174 */
    175static int
    176mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
    177{
    178	u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    179	u16 pkt_len;
    180	u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
    181
    182	pkt_len = len + ETH_ALEN;
    183
    184	skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN +
    185		    MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
    186	memcpy(skb_push(skb, sizeof(pkt_len)), &pkt_len, sizeof(pkt_len));
    187
    188	memcpy(skb_push(skb, sizeof(tx_control)),
    189	       &tx_control, sizeof(tx_control));
    190
    191	memcpy(skb_push(skb, sizeof(pkt_type)), &pkt_type, sizeof(pkt_type));
    192
    193	/* Add packet data and address4 */
    194	skb_put_data(skb, buf, sizeof(struct ieee80211_hdr_3addr));
    195	skb_put_data(skb, addr, ETH_ALEN);
    196	skb_put_data(skb, buf + sizeof(struct ieee80211_hdr_3addr),
    197		     len - sizeof(struct ieee80211_hdr_3addr));
    198
    199	skb->priority = LOW_PRIO_TID;
    200	__net_timestamp(skb);
    201
    202	return 0;
    203}
    204
    205/*
    206 * CFG802.11 operation handler to transmit a management frame.
    207 */
    208static int
    209mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
    210			 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
    211{
    212	const u8 *buf = params->buf;
    213	size_t len = params->len;
    214	struct sk_buff *skb;
    215	u16 pkt_len;
    216	const struct ieee80211_mgmt *mgmt;
    217	struct mwifiex_txinfo *tx_info;
    218	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
    219
    220	if (!buf || !len) {
    221		mwifiex_dbg(priv->adapter, ERROR, "invalid buffer and length\n");
    222		return -EFAULT;
    223	}
    224
    225	mgmt = (const struct ieee80211_mgmt *)buf;
    226	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA &&
    227	    ieee80211_is_probe_resp(mgmt->frame_control)) {
    228		/* Since we support offload probe resp, we need to skip probe
    229		 * resp in AP or GO mode */
    230		mwifiex_dbg(priv->adapter, INFO,
    231			    "info: skip to send probe resp in AP or GO mode\n");
    232		return 0;
    233	}
    234
    235	pkt_len = len + ETH_ALEN;
    236	skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
    237			    MWIFIEX_MGMT_FRAME_HEADER_SIZE +
    238			    pkt_len + sizeof(pkt_len));
    239
    240	if (!skb) {
    241		mwifiex_dbg(priv->adapter, ERROR,
    242			    "allocate skb failed for management frame\n");
    243		return -ENOMEM;
    244	}
    245
    246	tx_info = MWIFIEX_SKB_TXCB(skb);
    247	memset(tx_info, 0, sizeof(*tx_info));
    248	tx_info->bss_num = priv->bss_num;
    249	tx_info->bss_type = priv->bss_type;
    250	tx_info->pkt_len = pkt_len;
    251
    252	mwifiex_form_mgmt_frame(skb, buf, len);
    253	*cookie = prandom_u32() | 1;
    254
    255	if (ieee80211_is_action(mgmt->frame_control))
    256		skb = mwifiex_clone_skb_for_tx_status(priv,
    257						      skb,
    258				MWIFIEX_BUF_FLAG_ACTION_TX_STATUS, cookie);
    259	else
    260		cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
    261					GFP_ATOMIC);
    262
    263	mwifiex_queue_tx_pkt(priv, skb);
    264
    265	mwifiex_dbg(priv->adapter, INFO, "info: management frame transmitted\n");
    266	return 0;
    267}
    268
    269/*
    270 * CFG802.11 operation handler to register a mgmt frame.
    271 */
    272static void
    273mwifiex_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
    274						 struct wireless_dev *wdev,
    275						 struct mgmt_frame_regs *upd)
    276{
    277	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
    278	u32 mask = upd->interface_stypes;
    279
    280	if (mask != priv->mgmt_frame_mask) {
    281		priv->mgmt_frame_mask = mask;
    282		mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
    283				 HostCmd_ACT_GEN_SET, 0,
    284				 &priv->mgmt_frame_mask, false);
    285		mwifiex_dbg(priv->adapter, INFO, "info: mgmt frame registered\n");
    286	}
    287}
    288
    289/*
    290 * CFG802.11 operation handler to remain on channel.
    291 */
    292static int
    293mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
    294				   struct wireless_dev *wdev,
    295				   struct ieee80211_channel *chan,
    296				   unsigned int duration, u64 *cookie)
    297{
    298	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
    299	int ret;
    300
    301	if (!chan || !cookie) {
    302		mwifiex_dbg(priv->adapter, ERROR, "Invalid parameter for ROC\n");
    303		return -EINVAL;
    304	}
    305
    306	if (priv->roc_cfg.cookie) {
    307		mwifiex_dbg(priv->adapter, INFO,
    308			    "info: ongoing ROC, cookie = 0x%llx\n",
    309			    priv->roc_cfg.cookie);
    310		return -EBUSY;
    311	}
    312
    313	ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan,
    314					 duration);
    315
    316	if (!ret) {
    317		*cookie = prandom_u32() | 1;
    318		priv->roc_cfg.cookie = *cookie;
    319		priv->roc_cfg.chan = *chan;
    320
    321		cfg80211_ready_on_channel(wdev, *cookie, chan,
    322					  duration, GFP_ATOMIC);
    323
    324		mwifiex_dbg(priv->adapter, INFO,
    325			    "info: ROC, cookie = 0x%llx\n", *cookie);
    326	}
    327
    328	return ret;
    329}
    330
    331/*
    332 * CFG802.11 operation handler to cancel remain on channel.
    333 */
    334static int
    335mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
    336					  struct wireless_dev *wdev, u64 cookie)
    337{
    338	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
    339	int ret;
    340
    341	if (cookie != priv->roc_cfg.cookie)
    342		return -ENOENT;
    343
    344	ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
    345					 &priv->roc_cfg.chan, 0);
    346
    347	if (!ret) {
    348		cfg80211_remain_on_channel_expired(wdev, cookie,
    349						   &priv->roc_cfg.chan,
    350						   GFP_ATOMIC);
    351
    352		memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
    353
    354		mwifiex_dbg(priv->adapter, INFO,
    355			    "info: cancel ROC, cookie = 0x%llx\n", cookie);
    356	}
    357
    358	return ret;
    359}
    360
    361/*
    362 * CFG802.11 operation handler to set Tx power.
    363 */
    364static int
    365mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
    366			      struct wireless_dev *wdev,
    367			      enum nl80211_tx_power_setting type,
    368			      int mbm)
    369{
    370	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
    371	struct mwifiex_private *priv;
    372	struct mwifiex_power_cfg power_cfg;
    373	int dbm = MBM_TO_DBM(mbm);
    374
    375	switch (type) {
    376	case NL80211_TX_POWER_FIXED:
    377		power_cfg.is_power_auto = 0;
    378		power_cfg.is_power_fixed = 1;
    379		power_cfg.power_level = dbm;
    380		break;
    381	case NL80211_TX_POWER_LIMITED:
    382		power_cfg.is_power_auto = 0;
    383		power_cfg.is_power_fixed = 0;
    384		power_cfg.power_level = dbm;
    385		break;
    386	case NL80211_TX_POWER_AUTOMATIC:
    387		power_cfg.is_power_auto = 1;
    388		break;
    389	}
    390
    391	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
    392
    393	return mwifiex_set_tx_power(priv, &power_cfg);
    394}
    395
    396/*
    397 * CFG802.11 operation handler to get Tx power.
    398 */
    399static int
    400mwifiex_cfg80211_get_tx_power(struct wiphy *wiphy,
    401			      struct wireless_dev *wdev,
    402			      int *dbm)
    403{
    404	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
    405	struct mwifiex_private *priv = mwifiex_get_priv(adapter,
    406							MWIFIEX_BSS_ROLE_ANY);
    407	int ret = mwifiex_send_cmd(priv, HostCmd_CMD_RF_TX_PWR,
    408				   HostCmd_ACT_GEN_GET, 0, NULL, true);
    409
    410	if (ret < 0)
    411		return ret;
    412
    413	/* tx_power_level is set in HostCmd_CMD_RF_TX_PWR command handler */
    414	*dbm = priv->tx_power_level;
    415
    416	return 0;
    417}
    418
    419/*
    420 * CFG802.11 operation handler to set Power Save option.
    421 *
    422 * The timeout value, if provided, is currently ignored.
    423 */
    424static int
    425mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
    426				struct net_device *dev,
    427				bool enabled, int timeout)
    428{
    429	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
    430	u32 ps_mode;
    431
    432	if (timeout)
    433		mwifiex_dbg(priv->adapter, INFO,
    434			    "info: ignore timeout value for IEEE Power Save\n");
    435
    436	ps_mode = enabled;
    437
    438	return mwifiex_drv_set_power(priv, &ps_mode);
    439}
    440
    441/*
    442 * CFG802.11 operation handler to set the default network key.
    443 */
    444static int
    445mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
    446				 u8 key_index, bool unicast,
    447				 bool multicast)
    448{
    449	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
    450
    451	/* Return if WEP key not configured */
    452	if (!priv->sec_info.wep_enabled)
    453		return 0;
    454
    455	if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
    456		priv->wep_key_curr_index = key_index;
    457	} else if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index,
    458				      NULL, 0)) {
    459		mwifiex_dbg(priv->adapter, ERROR, "set default Tx key index\n");
    460		return -EFAULT;
    461	}
    462
    463	return 0;
    464}
    465
    466/*
    467 * CFG802.11 operation handler to add a network key.
    468 */
    469static int
    470mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
    471			 u8 key_index, bool pairwise, const u8 *mac_addr,
    472			 struct key_params *params)
    473{
    474	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
    475	struct mwifiex_wep_key *wep_key;
    476	static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    477	const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
    478
    479	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
    480	    (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
    481	     params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
    482		if (params->key && params->key_len) {
    483			wep_key = &priv->wep_key[key_index];
    484			memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
    485			memcpy(wep_key->key_material, params->key,
    486			       params->key_len);
    487			wep_key->key_index = key_index;
    488			wep_key->key_length = params->key_len;
    489			priv->sec_info.wep_enabled = 1;
    490		}
    491		return 0;
    492	}
    493
    494	if (mwifiex_set_encode(priv, params, params->key, params->key_len,
    495			       key_index, peer_mac, 0)) {
    496		mwifiex_dbg(priv->adapter, ERROR, "crypto keys added\n");
    497		return -EFAULT;
    498	}
    499
    500	return 0;
    501}
    502
    503/*
    504 * CFG802.11 operation handler to set default mgmt key.
    505 */
    506static int
    507mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
    508				      struct net_device *netdev,
    509				      u8 key_index)
    510{
    511	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
    512	struct mwifiex_ds_encrypt_key encrypt_key;
    513
    514	wiphy_dbg(wiphy, "set default mgmt key, key index=%d\n", key_index);
    515
    516	memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
    517	encrypt_key.key_len = WLAN_KEY_LEN_CCMP;
    518	encrypt_key.key_index = key_index;
    519	encrypt_key.is_igtk_def_key = true;
    520	eth_broadcast_addr(encrypt_key.mac_addr);
    521
    522	if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
    523			     HostCmd_ACT_GEN_SET, true, &encrypt_key, true)) {
    524		mwifiex_dbg(priv->adapter, ERROR,
    525			    "Sending KEY_MATERIAL command failed\n");
    526		return -1;
    527	}
    528
    529	return 0;
    530}
    531
    532/*
    533 * This function sends domain information to the firmware.
    534 *
    535 * The following information are passed to the firmware -
    536 *      - Country codes
    537 *      - Sub bands (first channel, number of channels, maximum Tx power)
    538 */
    539int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
    540{
    541	u8 no_of_triplet = 0;
    542	struct ieee80211_country_ie_triplet *t;
    543	u8 no_of_parsed_chan = 0;
    544	u8 first_chan = 0, next_chan = 0, max_pwr = 0;
    545	u8 i, flag = 0;
    546	enum nl80211_band band;
    547	struct ieee80211_supported_band *sband;
    548	struct ieee80211_channel *ch;
    549	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
    550	struct mwifiex_private *priv;
    551	struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
    552
    553	/* Set country code */
    554	domain_info->country_code[0] = adapter->country_code[0];
    555	domain_info->country_code[1] = adapter->country_code[1];
    556	domain_info->country_code[2] = ' ';
    557
    558	band = mwifiex_band_to_radio_type(adapter->config_bands);
    559	if (!wiphy->bands[band]) {
    560		mwifiex_dbg(adapter, ERROR,
    561			    "11D: setting domain info in FW\n");
    562		return -1;
    563	}
    564
    565	sband = wiphy->bands[band];
    566
    567	for (i = 0; i < sband->n_channels ; i++) {
    568		ch = &sband->channels[i];
    569		if (ch->flags & IEEE80211_CHAN_DISABLED)
    570			continue;
    571
    572		if (!flag) {
    573			flag = 1;
    574			first_chan = (u32) ch->hw_value;
    575			next_chan = first_chan;
    576			max_pwr = ch->max_power;
    577			no_of_parsed_chan = 1;
    578			continue;
    579		}
    580
    581		if (ch->hw_value == next_chan + 1 &&
    582		    ch->max_power == max_pwr) {
    583			next_chan++;
    584			no_of_parsed_chan++;
    585		} else {
    586			t = &domain_info->triplet[no_of_triplet];
    587			t->chans.first_channel = first_chan;
    588			t->chans.num_channels = no_of_parsed_chan;
    589			t->chans.max_power = max_pwr;
    590			no_of_triplet++;
    591			first_chan = (u32) ch->hw_value;
    592			next_chan = first_chan;
    593			max_pwr = ch->max_power;
    594			no_of_parsed_chan = 1;
    595		}
    596	}
    597
    598	if (flag) {
    599		t = &domain_info->triplet[no_of_triplet];
    600		t->chans.first_channel = first_chan;
    601		t->chans.num_channels = no_of_parsed_chan;
    602		t->chans.max_power = max_pwr;
    603		no_of_triplet++;
    604	}
    605
    606	domain_info->no_of_triplet = no_of_triplet;
    607
    608	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
    609
    610	if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
    611			     HostCmd_ACT_GEN_SET, 0, NULL, false)) {
    612		mwifiex_dbg(adapter, INFO,
    613			    "11D: setting domain info in FW\n");
    614		return -1;
    615	}
    616
    617	return 0;
    618}
    619
    620static void mwifiex_reg_apply_radar_flags(struct wiphy *wiphy)
    621{
    622	struct ieee80211_supported_band *sband;
    623	struct ieee80211_channel *chan;
    624	unsigned int i;
    625
    626	if (!wiphy->bands[NL80211_BAND_5GHZ])
    627		return;
    628	sband = wiphy->bands[NL80211_BAND_5GHZ];
    629
    630	for (i = 0; i < sband->n_channels; i++) {
    631		chan = &sband->channels[i];
    632		if ((!(chan->flags & IEEE80211_CHAN_DISABLED)) &&
    633		    (chan->flags & IEEE80211_CHAN_RADAR))
    634			chan->flags |= IEEE80211_CHAN_NO_IR;
    635	}
    636}
    637
    638/*
    639 * CFG802.11 regulatory domain callback function.
    640 *
    641 * This function is called when the regulatory domain is changed due to the
    642 * following reasons -
    643 *      - Set by driver
    644 *      - Set by system core
    645 *      - Set by user
    646 *      - Set bt Country IE
    647 */
    648static void mwifiex_reg_notifier(struct wiphy *wiphy,
    649				 struct regulatory_request *request)
    650{
    651	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
    652	struct mwifiex_private *priv = mwifiex_get_priv(adapter,
    653							MWIFIEX_BSS_ROLE_ANY);
    654	mwifiex_dbg(adapter, INFO,
    655		    "info: cfg80211 regulatory domain callback for %c%c\n",
    656		    request->alpha2[0], request->alpha2[1]);
    657	mwifiex_reg_apply_radar_flags(wiphy);
    658
    659	switch (request->initiator) {
    660	case NL80211_REGDOM_SET_BY_DRIVER:
    661	case NL80211_REGDOM_SET_BY_CORE:
    662	case NL80211_REGDOM_SET_BY_USER:
    663	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
    664		break;
    665	default:
    666		mwifiex_dbg(adapter, ERROR,
    667			    "unknown regdom initiator: %d\n",
    668			    request->initiator);
    669		return;
    670	}
    671
    672	/* Don't send world or same regdom info to firmware */
    673	if (strncmp(request->alpha2, "00", 2) &&
    674	    strncmp(request->alpha2, adapter->country_code,
    675		    sizeof(request->alpha2))) {
    676		memcpy(adapter->country_code, request->alpha2,
    677		       sizeof(request->alpha2));
    678		mwifiex_send_domain_info_cmd_fw(wiphy);
    679		mwifiex_dnld_txpwr_table(priv);
    680	}
    681}
    682
    683/*
    684 * This function sets the fragmentation threshold.
    685 *
    686 * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE
    687 * and MWIFIEX_FRAG_MAX_VALUE.
    688 */
    689static int
    690mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
    691{
    692	if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
    693	    frag_thr > MWIFIEX_FRAG_MAX_VALUE)
    694		frag_thr = MWIFIEX_FRAG_MAX_VALUE;
    695
    696	return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
    697				HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
    698				&frag_thr, true);
    699}
    700
    701/*
    702 * This function sets the RTS threshold.
    703
    704 * The rts value must lie between MWIFIEX_RTS_MIN_VALUE
    705 * and MWIFIEX_RTS_MAX_VALUE.
    706 */
    707static int
    708mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
    709{
    710	if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
    711		rts_thr = MWIFIEX_RTS_MAX_VALUE;
    712
    713	return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
    714				HostCmd_ACT_GEN_SET, RTS_THRESH_I,
    715				&rts_thr, true);
    716}
    717
    718/*
    719 * CFG802.11 operation handler to set wiphy parameters.
    720 *
    721 * This function can be used to set the RTS threshold and the
    722 * Fragmentation threshold of the driver.
    723 */
    724static int
    725mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
    726{
    727	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
    728	struct mwifiex_private *priv;
    729	struct mwifiex_uap_bss_param *bss_cfg;
    730	int ret;
    731
    732	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
    733
    734	switch (priv->bss_role) {
    735	case MWIFIEX_BSS_ROLE_UAP:
    736		if (priv->bss_started) {
    737			mwifiex_dbg(adapter, ERROR,
    738				    "cannot change wiphy params when bss started");
    739			return -EINVAL;
    740		}
    741
    742		bss_cfg = kzalloc(sizeof(*bss_cfg), GFP_KERNEL);
    743		if (!bss_cfg)
    744			return -ENOMEM;
    745
    746		mwifiex_set_sys_config_invalid_data(bss_cfg);
    747
    748		if (changed & WIPHY_PARAM_RTS_THRESHOLD)
    749			bss_cfg->rts_threshold = wiphy->rts_threshold;
    750		if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
    751			bss_cfg->frag_threshold = wiphy->frag_threshold;
    752		if (changed & WIPHY_PARAM_RETRY_LONG)
    753			bss_cfg->retry_limit = wiphy->retry_long;
    754
    755		ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
    756				       HostCmd_ACT_GEN_SET,
    757				       UAP_BSS_PARAMS_I, bss_cfg,
    758				       false);
    759
    760		kfree(bss_cfg);
    761		if (ret) {
    762			mwifiex_dbg(adapter, ERROR,
    763				    "Failed to set wiphy phy params\n");
    764			return ret;
    765		}
    766		break;
    767
    768	case MWIFIEX_BSS_ROLE_STA:
    769		if (priv->media_connected) {
    770			mwifiex_dbg(adapter, ERROR,
    771				    "cannot change wiphy params when connected");
    772			return -EINVAL;
    773		}
    774		if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
    775			ret = mwifiex_set_rts(priv,
    776					      wiphy->rts_threshold);
    777			if (ret)
    778				return ret;
    779		}
    780		if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
    781			ret = mwifiex_set_frag(priv,
    782					       wiphy->frag_threshold);
    783			if (ret)
    784				return ret;
    785		}
    786		break;
    787	}
    788
    789	return 0;
    790}
    791
    792static int
    793mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
    794{
    795	u16 mode = P2P_MODE_DISABLE;
    796
    797	if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
    798			     HostCmd_ACT_GEN_SET, 0, &mode, true))
    799		return -1;
    800
    801	return 0;
    802}
    803
    804/*
    805 * This function initializes the functionalities for P2P client.
    806 * The P2P client initialization sequence is:
    807 * disable -> device -> client
    808 */
    809static int
    810mwifiex_cfg80211_init_p2p_client(struct mwifiex_private *priv)
    811{
    812	u16 mode;
    813
    814	if (mwifiex_cfg80211_deinit_p2p(priv))
    815		return -1;
    816
    817	mode = P2P_MODE_DEVICE;
    818	if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
    819			     HostCmd_ACT_GEN_SET, 0, &mode, true))
    820		return -1;
    821
    822	mode = P2P_MODE_CLIENT;
    823	if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
    824			     HostCmd_ACT_GEN_SET, 0, &mode, true))
    825		return -1;
    826
    827	return 0;
    828}
    829
    830/*
    831 * This function initializes the functionalities for P2P GO.
    832 * The P2P GO initialization sequence is:
    833 * disable -> device -> GO
    834 */
    835static int
    836mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
    837{
    838	u16 mode;
    839
    840	if (mwifiex_cfg80211_deinit_p2p(priv))
    841		return -1;
    842
    843	mode = P2P_MODE_DEVICE;
    844	if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
    845			     HostCmd_ACT_GEN_SET, 0, &mode, true))
    846		return -1;
    847
    848	mode = P2P_MODE_GO;
    849	if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
    850			     HostCmd_ACT_GEN_SET, 0, &mode, true))
    851		return -1;
    852
    853	return 0;
    854}
    855
    856static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
    857{
    858	struct mwifiex_adapter *adapter = priv->adapter;
    859	unsigned long flags;
    860
    861	priv->mgmt_frame_mask = 0;
    862	if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
    863			     HostCmd_ACT_GEN_SET, 0,
    864			     &priv->mgmt_frame_mask, false)) {
    865		mwifiex_dbg(adapter, ERROR,
    866			    "could not unregister mgmt frame rx\n");
    867		return -1;
    868	}
    869
    870	mwifiex_deauthenticate(priv, NULL);
    871
    872	spin_lock_irqsave(&adapter->main_proc_lock, flags);
    873	adapter->main_locked = true;
    874	if (adapter->mwifiex_processing) {
    875		spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
    876		flush_workqueue(adapter->workqueue);
    877	} else {
    878		spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
    879	}
    880
    881	spin_lock_bh(&adapter->rx_proc_lock);
    882	adapter->rx_locked = true;
    883	if (adapter->rx_processing) {
    884		spin_unlock_bh(&adapter->rx_proc_lock);
    885		flush_workqueue(adapter->rx_workqueue);
    886	} else {
    887	spin_unlock_bh(&adapter->rx_proc_lock);
    888	}
    889
    890	mwifiex_free_priv(priv);
    891	priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
    892	priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
    893	priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
    894
    895	return 0;
    896}
    897
    898static int
    899mwifiex_init_new_priv_params(struct mwifiex_private *priv,
    900			     struct net_device *dev,
    901			     enum nl80211_iftype type)
    902{
    903	struct mwifiex_adapter *adapter = priv->adapter;
    904	unsigned long flags;
    905
    906	mwifiex_init_priv(priv);
    907
    908	priv->bss_mode = type;
    909	priv->wdev.iftype = type;
    910
    911	mwifiex_init_priv_params(priv, priv->netdev);
    912	priv->bss_started = 0;
    913
    914	switch (type) {
    915	case NL80211_IFTYPE_STATION:
    916	case NL80211_IFTYPE_ADHOC:
    917		priv->bss_role = MWIFIEX_BSS_ROLE_STA;
    918		priv->bss_type = MWIFIEX_BSS_TYPE_STA;
    919		break;
    920	case NL80211_IFTYPE_P2P_CLIENT:
    921		priv->bss_role = MWIFIEX_BSS_ROLE_STA;
    922		priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
    923		break;
    924	case NL80211_IFTYPE_P2P_GO:
    925		priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
    926		priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
    927		break;
    928	case NL80211_IFTYPE_AP:
    929		priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
    930		priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
    931		break;
    932	default:
    933		mwifiex_dbg(adapter, ERROR,
    934			    "%s: changing to %d not supported\n",
    935			    dev->name, type);
    936		return -EOPNOTSUPP;
    937	}
    938
    939	spin_lock_irqsave(&adapter->main_proc_lock, flags);
    940	adapter->main_locked = false;
    941	spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
    942
    943	spin_lock_bh(&adapter->rx_proc_lock);
    944	adapter->rx_locked = false;
    945	spin_unlock_bh(&adapter->rx_proc_lock);
    946
    947	mwifiex_set_mac_address(priv, dev, false, NULL);
    948
    949	return 0;
    950}
    951
    952static bool
    953is_vif_type_change_allowed(struct mwifiex_adapter *adapter,
    954			   enum nl80211_iftype old_iftype,
    955			   enum nl80211_iftype new_iftype)
    956{
    957	switch (old_iftype) {
    958	case NL80211_IFTYPE_ADHOC:
    959		switch (new_iftype) {
    960		case NL80211_IFTYPE_STATION:
    961			return true;
    962		case NL80211_IFTYPE_P2P_CLIENT:
    963		case NL80211_IFTYPE_P2P_GO:
    964			return adapter->curr_iface_comb.p2p_intf !=
    965			       adapter->iface_limit.p2p_intf;
    966		case NL80211_IFTYPE_AP:
    967			return adapter->curr_iface_comb.uap_intf !=
    968			       adapter->iface_limit.uap_intf;
    969		default:
    970			return false;
    971		}
    972
    973	case NL80211_IFTYPE_STATION:
    974		switch (new_iftype) {
    975		case NL80211_IFTYPE_ADHOC:
    976			return true;
    977		case NL80211_IFTYPE_P2P_CLIENT:
    978		case NL80211_IFTYPE_P2P_GO:
    979			return adapter->curr_iface_comb.p2p_intf !=
    980			       adapter->iface_limit.p2p_intf;
    981		case NL80211_IFTYPE_AP:
    982			return adapter->curr_iface_comb.uap_intf !=
    983			       adapter->iface_limit.uap_intf;
    984		default:
    985			return false;
    986		}
    987
    988	case NL80211_IFTYPE_AP:
    989		switch (new_iftype) {
    990		case NL80211_IFTYPE_ADHOC:
    991		case NL80211_IFTYPE_STATION:
    992			return adapter->curr_iface_comb.sta_intf !=
    993			       adapter->iface_limit.sta_intf;
    994		case NL80211_IFTYPE_P2P_CLIENT:
    995		case NL80211_IFTYPE_P2P_GO:
    996			return adapter->curr_iface_comb.p2p_intf !=
    997			       adapter->iface_limit.p2p_intf;
    998		default:
    999			return false;
   1000		}
   1001
   1002	case NL80211_IFTYPE_P2P_CLIENT:
   1003		switch (new_iftype) {
   1004		case NL80211_IFTYPE_ADHOC:
   1005		case NL80211_IFTYPE_STATION:
   1006			return true;
   1007		case NL80211_IFTYPE_P2P_GO:
   1008			return true;
   1009		case NL80211_IFTYPE_AP:
   1010			return adapter->curr_iface_comb.uap_intf !=
   1011			       adapter->iface_limit.uap_intf;
   1012		default:
   1013			return false;
   1014		}
   1015
   1016	case NL80211_IFTYPE_P2P_GO:
   1017		switch (new_iftype) {
   1018		case NL80211_IFTYPE_ADHOC:
   1019		case NL80211_IFTYPE_STATION:
   1020			return true;
   1021		case NL80211_IFTYPE_P2P_CLIENT:
   1022			return true;
   1023		case NL80211_IFTYPE_AP:
   1024			return adapter->curr_iface_comb.uap_intf !=
   1025			       adapter->iface_limit.uap_intf;
   1026		default:
   1027			return false;
   1028		}
   1029
   1030	default:
   1031		break;
   1032	}
   1033
   1034	return false;
   1035}
   1036
   1037static void
   1038update_vif_type_counter(struct mwifiex_adapter *adapter,
   1039			enum nl80211_iftype iftype,
   1040			int change)
   1041{
   1042	switch (iftype) {
   1043	case NL80211_IFTYPE_UNSPECIFIED:
   1044	case NL80211_IFTYPE_ADHOC:
   1045	case NL80211_IFTYPE_STATION:
   1046		adapter->curr_iface_comb.sta_intf += change;
   1047		break;
   1048	case NL80211_IFTYPE_AP:
   1049		adapter->curr_iface_comb.uap_intf += change;
   1050		break;
   1051	case NL80211_IFTYPE_P2P_CLIENT:
   1052	case NL80211_IFTYPE_P2P_GO:
   1053		adapter->curr_iface_comb.p2p_intf += change;
   1054		break;
   1055	default:
   1056		mwifiex_dbg(adapter, ERROR,
   1057			    "%s: Unsupported iftype passed: %d\n",
   1058			    __func__, iftype);
   1059		break;
   1060	}
   1061}
   1062
   1063static int
   1064mwifiex_change_vif_to_p2p(struct net_device *dev,
   1065			  enum nl80211_iftype curr_iftype,
   1066			  enum nl80211_iftype type,
   1067			  struct vif_params *params)
   1068{
   1069	struct mwifiex_private *priv;
   1070	struct mwifiex_adapter *adapter;
   1071
   1072	priv = mwifiex_netdev_get_priv(dev);
   1073
   1074	if (!priv)
   1075		return -1;
   1076
   1077	adapter = priv->adapter;
   1078
   1079	mwifiex_dbg(adapter, INFO,
   1080		    "%s: changing role to p2p\n", dev->name);
   1081
   1082	if (mwifiex_deinit_priv_params(priv))
   1083		return -1;
   1084	if (mwifiex_init_new_priv_params(priv, dev, type))
   1085		return -1;
   1086
   1087	update_vif_type_counter(adapter, curr_iftype, -1);
   1088	update_vif_type_counter(adapter, type, +1);
   1089	dev->ieee80211_ptr->iftype = type;
   1090
   1091	switch (type) {
   1092	case NL80211_IFTYPE_P2P_CLIENT:
   1093		if (mwifiex_cfg80211_init_p2p_client(priv))
   1094			return -EFAULT;
   1095		break;
   1096	case NL80211_IFTYPE_P2P_GO:
   1097		if (mwifiex_cfg80211_init_p2p_go(priv))
   1098			return -EFAULT;
   1099		break;
   1100	default:
   1101		mwifiex_dbg(adapter, ERROR,
   1102			    "%s: changing to %d not supported\n",
   1103			    dev->name, type);
   1104		return -EOPNOTSUPP;
   1105	}
   1106
   1107	if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
   1108			     HostCmd_ACT_GEN_SET, 0, NULL, true))
   1109		return -1;
   1110
   1111	if (mwifiex_sta_init_cmd(priv, false, false))
   1112		return -1;
   1113
   1114	return 0;
   1115}
   1116
   1117static int
   1118mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
   1119				enum nl80211_iftype curr_iftype,
   1120				enum nl80211_iftype type,
   1121				struct vif_params *params)
   1122{
   1123	struct mwifiex_private *priv;
   1124	struct mwifiex_adapter *adapter;
   1125
   1126	priv = mwifiex_netdev_get_priv(dev);
   1127
   1128	if (!priv)
   1129		return -1;
   1130
   1131	adapter = priv->adapter;
   1132
   1133	if (type == NL80211_IFTYPE_STATION)
   1134		mwifiex_dbg(adapter, INFO,
   1135			    "%s: changing role to station\n", dev->name);
   1136	else
   1137		mwifiex_dbg(adapter, INFO,
   1138			    "%s: changing role to adhoc\n", dev->name);
   1139
   1140	if (mwifiex_deinit_priv_params(priv))
   1141		return -1;
   1142	if (mwifiex_init_new_priv_params(priv, dev, type))
   1143		return -1;
   1144
   1145	update_vif_type_counter(adapter, curr_iftype, -1);
   1146	update_vif_type_counter(adapter, type, +1);
   1147	dev->ieee80211_ptr->iftype = type;
   1148
   1149	if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
   1150			     HostCmd_ACT_GEN_SET, 0, NULL, true))
   1151		return -1;
   1152	if (mwifiex_sta_init_cmd(priv, false, false))
   1153		return -1;
   1154
   1155	return 0;
   1156}
   1157
   1158static int
   1159mwifiex_change_vif_to_ap(struct net_device *dev,
   1160			 enum nl80211_iftype curr_iftype,
   1161			 enum nl80211_iftype type,
   1162			 struct vif_params *params)
   1163{
   1164	struct mwifiex_private *priv;
   1165	struct mwifiex_adapter *adapter;
   1166
   1167	priv = mwifiex_netdev_get_priv(dev);
   1168
   1169	if (!priv)
   1170		return -1;
   1171
   1172	adapter = priv->adapter;
   1173
   1174	mwifiex_dbg(adapter, INFO,
   1175		    "%s: changing role to AP\n", dev->name);
   1176
   1177	if (mwifiex_deinit_priv_params(priv))
   1178		return -1;
   1179	if (mwifiex_init_new_priv_params(priv, dev, type))
   1180		return -1;
   1181
   1182	update_vif_type_counter(adapter, curr_iftype, -1);
   1183	update_vif_type_counter(adapter, type, +1);
   1184	dev->ieee80211_ptr->iftype = type;
   1185
   1186	if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
   1187			     HostCmd_ACT_GEN_SET, 0, NULL, true))
   1188		return -1;
   1189	if (mwifiex_sta_init_cmd(priv, false, false))
   1190		return -1;
   1191
   1192	return 0;
   1193}
   1194/*
   1195 * CFG802.11 operation handler to change interface type.
   1196 */
   1197static int
   1198mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
   1199				     struct net_device *dev,
   1200				     enum nl80211_iftype type,
   1201				     struct vif_params *params)
   1202{
   1203	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1204	enum nl80211_iftype curr_iftype = dev->ieee80211_ptr->iftype;
   1205
   1206	if (priv->scan_request) {
   1207		mwifiex_dbg(priv->adapter, ERROR,
   1208			    "change virtual interface: scan in process\n");
   1209		return -EBUSY;
   1210	}
   1211
   1212	if (type == NL80211_IFTYPE_UNSPECIFIED) {
   1213		mwifiex_dbg(priv->adapter, INFO,
   1214			    "%s: no new type specified, keeping old type %d\n",
   1215			    dev->name, curr_iftype);
   1216		return 0;
   1217	}
   1218
   1219	if (curr_iftype == type) {
   1220		mwifiex_dbg(priv->adapter, INFO,
   1221			    "%s: interface already is of type %d\n",
   1222			    dev->name, curr_iftype);
   1223		return 0;
   1224	}
   1225
   1226	if (!is_vif_type_change_allowed(priv->adapter, curr_iftype, type)) {
   1227		mwifiex_dbg(priv->adapter, ERROR,
   1228			    "%s: change from type %d to %d is not allowed\n",
   1229			    dev->name, curr_iftype, type);
   1230		return -EOPNOTSUPP;
   1231	}
   1232
   1233	switch (curr_iftype) {
   1234	case NL80211_IFTYPE_ADHOC:
   1235		switch (type) {
   1236		case NL80211_IFTYPE_STATION:
   1237			priv->bss_mode = type;
   1238			priv->sec_info.authentication_mode =
   1239						   NL80211_AUTHTYPE_OPEN_SYSTEM;
   1240			dev->ieee80211_ptr->iftype = type;
   1241			mwifiex_deauthenticate(priv, NULL);
   1242			return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
   1243						HostCmd_ACT_GEN_SET, 0, NULL,
   1244						true);
   1245		case NL80211_IFTYPE_P2P_CLIENT:
   1246		case NL80211_IFTYPE_P2P_GO:
   1247			return mwifiex_change_vif_to_p2p(dev, curr_iftype,
   1248							 type, params);
   1249		case NL80211_IFTYPE_AP:
   1250			return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
   1251							params);
   1252		default:
   1253			goto errnotsupp;
   1254		}
   1255
   1256	case NL80211_IFTYPE_STATION:
   1257		switch (type) {
   1258		case NL80211_IFTYPE_ADHOC:
   1259			priv->bss_mode = type;
   1260			priv->sec_info.authentication_mode =
   1261						   NL80211_AUTHTYPE_OPEN_SYSTEM;
   1262			dev->ieee80211_ptr->iftype = type;
   1263			mwifiex_deauthenticate(priv, NULL);
   1264			return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
   1265						HostCmd_ACT_GEN_SET, 0, NULL,
   1266						true);
   1267		case NL80211_IFTYPE_P2P_CLIENT:
   1268		case NL80211_IFTYPE_P2P_GO:
   1269			return mwifiex_change_vif_to_p2p(dev, curr_iftype,
   1270							 type, params);
   1271		case NL80211_IFTYPE_AP:
   1272			return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
   1273							params);
   1274		default:
   1275			goto errnotsupp;
   1276		}
   1277
   1278	case NL80211_IFTYPE_AP:
   1279		switch (type) {
   1280		case NL80211_IFTYPE_ADHOC:
   1281		case NL80211_IFTYPE_STATION:
   1282			return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
   1283							       type, params);
   1284			break;
   1285		case NL80211_IFTYPE_P2P_CLIENT:
   1286		case NL80211_IFTYPE_P2P_GO:
   1287			return mwifiex_change_vif_to_p2p(dev, curr_iftype,
   1288							 type, params);
   1289		default:
   1290			goto errnotsupp;
   1291		}
   1292
   1293	case NL80211_IFTYPE_P2P_CLIENT:
   1294		if (mwifiex_cfg80211_deinit_p2p(priv))
   1295			return -EFAULT;
   1296
   1297		switch (type) {
   1298		case NL80211_IFTYPE_ADHOC:
   1299		case NL80211_IFTYPE_STATION:
   1300			return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
   1301							       type, params);
   1302		case NL80211_IFTYPE_P2P_GO:
   1303			return mwifiex_change_vif_to_p2p(dev, curr_iftype,
   1304							 type, params);
   1305		case NL80211_IFTYPE_AP:
   1306			return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
   1307							params);
   1308		default:
   1309			goto errnotsupp;
   1310		}
   1311
   1312	case NL80211_IFTYPE_P2P_GO:
   1313		if (mwifiex_cfg80211_deinit_p2p(priv))
   1314			return -EFAULT;
   1315
   1316		switch (type) {
   1317		case NL80211_IFTYPE_ADHOC:
   1318		case NL80211_IFTYPE_STATION:
   1319			return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
   1320							       type, params);
   1321		case NL80211_IFTYPE_P2P_CLIENT:
   1322			return mwifiex_change_vif_to_p2p(dev, curr_iftype,
   1323							 type, params);
   1324		case NL80211_IFTYPE_AP:
   1325			return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
   1326							params);
   1327		default:
   1328			goto errnotsupp;
   1329		}
   1330
   1331	default:
   1332		goto errnotsupp;
   1333	}
   1334
   1335
   1336	return 0;
   1337
   1338errnotsupp:
   1339	mwifiex_dbg(priv->adapter, ERROR,
   1340		    "unsupported interface type transition: %d to %d\n",
   1341		    curr_iftype, type);
   1342	return -EOPNOTSUPP;
   1343}
   1344
   1345static void
   1346mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 rateinfo, u8 htinfo,
   1347		     struct rate_info *rate)
   1348{
   1349	struct mwifiex_adapter *adapter = priv->adapter;
   1350
   1351	if (adapter->is_hw_11ac_capable) {
   1352		/* bit[1-0]: 00=LG 01=HT 10=VHT */
   1353		if (htinfo & BIT(0)) {
   1354			/* HT */
   1355			rate->mcs = rateinfo;
   1356			rate->flags |= RATE_INFO_FLAGS_MCS;
   1357		}
   1358		if (htinfo & BIT(1)) {
   1359			/* VHT */
   1360			rate->mcs = rateinfo & 0x0F;
   1361			rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
   1362		}
   1363
   1364		if (htinfo & (BIT(1) | BIT(0))) {
   1365			/* HT or VHT */
   1366			switch (htinfo & (BIT(3) | BIT(2))) {
   1367			case 0:
   1368				rate->bw = RATE_INFO_BW_20;
   1369				break;
   1370			case (BIT(2)):
   1371				rate->bw = RATE_INFO_BW_40;
   1372				break;
   1373			case (BIT(3)):
   1374				rate->bw = RATE_INFO_BW_80;
   1375				break;
   1376			case (BIT(3) | BIT(2)):
   1377				rate->bw = RATE_INFO_BW_160;
   1378				break;
   1379			}
   1380
   1381			if (htinfo & BIT(4))
   1382				rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
   1383
   1384			if ((rateinfo >> 4) == 1)
   1385				rate->nss = 2;
   1386			else
   1387				rate->nss = 1;
   1388		}
   1389	} else {
   1390		/*
   1391		 * Bit 0 in htinfo indicates that current rate is 11n. Valid
   1392		 * MCS index values for us are 0 to 15.
   1393		 */
   1394		if ((htinfo & BIT(0)) && (rateinfo < 16)) {
   1395			rate->mcs = rateinfo;
   1396			rate->flags |= RATE_INFO_FLAGS_MCS;
   1397			rate->bw = RATE_INFO_BW_20;
   1398			if (htinfo & BIT(1))
   1399				rate->bw = RATE_INFO_BW_40;
   1400			if (htinfo & BIT(2))
   1401				rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
   1402		}
   1403	}
   1404
   1405	/* Decode legacy rates for non-HT. */
   1406	if (!(htinfo & (BIT(0) | BIT(1)))) {
   1407		/* Bitrates in multiples of 100kb/s. */
   1408		static const int legacy_rates[] = {
   1409			[0] = 10,
   1410			[1] = 20,
   1411			[2] = 55,
   1412			[3] = 110,
   1413			[4] = 60, /* MWIFIEX_RATE_INDEX_OFDM0 */
   1414			[5] = 60,
   1415			[6] = 90,
   1416			[7] = 120,
   1417			[8] = 180,
   1418			[9] = 240,
   1419			[10] = 360,
   1420			[11] = 480,
   1421			[12] = 540,
   1422		};
   1423		if (rateinfo < ARRAY_SIZE(legacy_rates))
   1424			rate->legacy = legacy_rates[rateinfo];
   1425	}
   1426}
   1427
   1428/*
   1429 * This function dumps the station information on a buffer.
   1430 *
   1431 * The following information are shown -
   1432 *      - Total bytes transmitted
   1433 *      - Total bytes received
   1434 *      - Total packets transmitted
   1435 *      - Total packets received
   1436 *      - Signal quality level
   1437 *      - Transmission rate
   1438 */
   1439static int
   1440mwifiex_dump_station_info(struct mwifiex_private *priv,
   1441			  struct mwifiex_sta_node *node,
   1442			  struct station_info *sinfo)
   1443{
   1444	u32 rate;
   1445
   1446	sinfo->filled = BIT_ULL(NL80211_STA_INFO_RX_BYTES) | BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
   1447			BIT_ULL(NL80211_STA_INFO_RX_PACKETS) | BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
   1448			BIT_ULL(NL80211_STA_INFO_TX_BITRATE) |
   1449			BIT_ULL(NL80211_STA_INFO_SIGNAL) | BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
   1450
   1451	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
   1452		if (!node)
   1453			return -ENOENT;
   1454
   1455		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) |
   1456				BIT_ULL(NL80211_STA_INFO_TX_FAILED);
   1457		sinfo->inactive_time =
   1458			jiffies_to_msecs(jiffies - node->stats.last_rx);
   1459
   1460		sinfo->signal = node->stats.rssi;
   1461		sinfo->signal_avg = node->stats.rssi;
   1462		sinfo->rx_bytes = node->stats.rx_bytes;
   1463		sinfo->tx_bytes = node->stats.tx_bytes;
   1464		sinfo->rx_packets = node->stats.rx_packets;
   1465		sinfo->tx_packets = node->stats.tx_packets;
   1466		sinfo->tx_failed = node->stats.tx_failed;
   1467
   1468		mwifiex_parse_htinfo(priv, priv->tx_rate,
   1469				     node->stats.last_tx_htinfo,
   1470				     &sinfo->txrate);
   1471		sinfo->txrate.legacy = node->stats.last_tx_rate * 5;
   1472
   1473		return 0;
   1474	}
   1475
   1476	/* Get signal information from the firmware */
   1477	if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
   1478			     HostCmd_ACT_GEN_GET, 0, NULL, true)) {
   1479		mwifiex_dbg(priv->adapter, ERROR,
   1480			    "failed to get signal information\n");
   1481		return -EFAULT;
   1482	}
   1483
   1484	if (mwifiex_drv_get_data_rate(priv, &rate)) {
   1485		mwifiex_dbg(priv->adapter, ERROR,
   1486			    "getting data rate error\n");
   1487		return -EFAULT;
   1488	}
   1489
   1490	/* Get DTIM period information from firmware */
   1491	mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
   1492			 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
   1493			 &priv->dtim_period, true);
   1494
   1495	mwifiex_parse_htinfo(priv, priv->tx_rate, priv->tx_htinfo,
   1496			     &sinfo->txrate);
   1497
   1498	sinfo->signal_avg = priv->bcn_rssi_avg;
   1499	sinfo->rx_bytes = priv->stats.rx_bytes;
   1500	sinfo->tx_bytes = priv->stats.tx_bytes;
   1501	sinfo->rx_packets = priv->stats.rx_packets;
   1502	sinfo->tx_packets = priv->stats.tx_packets;
   1503	sinfo->signal = priv->bcn_rssi_avg;
   1504	/* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
   1505	sinfo->txrate.legacy = rate * 5;
   1506
   1507	sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
   1508	mwifiex_parse_htinfo(priv, priv->rxpd_rate, priv->rxpd_htinfo,
   1509			     &sinfo->rxrate);
   1510
   1511	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
   1512		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
   1513		sinfo->bss_param.flags = 0;
   1514		if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
   1515						WLAN_CAPABILITY_SHORT_PREAMBLE)
   1516			sinfo->bss_param.flags |=
   1517					BSS_PARAM_FLAGS_SHORT_PREAMBLE;
   1518		if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
   1519						WLAN_CAPABILITY_SHORT_SLOT_TIME)
   1520			sinfo->bss_param.flags |=
   1521					BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
   1522		sinfo->bss_param.dtim_period = priv->dtim_period;
   1523		sinfo->bss_param.beacon_interval =
   1524			priv->curr_bss_params.bss_descriptor.beacon_period;
   1525	}
   1526
   1527	return 0;
   1528}
   1529
   1530/*
   1531 * CFG802.11 operation handler to get station information.
   1532 *
   1533 * This function only works in connected mode, and dumps the
   1534 * requested station information, if available.
   1535 */
   1536static int
   1537mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
   1538			     const u8 *mac, struct station_info *sinfo)
   1539{
   1540	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1541
   1542	if (!priv->media_connected)
   1543		return -ENOENT;
   1544	if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
   1545		return -ENOENT;
   1546
   1547	return mwifiex_dump_station_info(priv, NULL, sinfo);
   1548}
   1549
   1550/*
   1551 * CFG802.11 operation handler to dump station information.
   1552 */
   1553static int
   1554mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
   1555			      int idx, u8 *mac, struct station_info *sinfo)
   1556{
   1557	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1558	struct mwifiex_sta_node *node;
   1559	int i;
   1560
   1561	if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
   1562	    priv->media_connected && idx == 0) {
   1563		ether_addr_copy(mac, priv->cfg_bssid);
   1564		return mwifiex_dump_station_info(priv, NULL, sinfo);
   1565	} else if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
   1566		mwifiex_send_cmd(priv, HOST_CMD_APCMD_STA_LIST,
   1567				 HostCmd_ACT_GEN_GET, 0, NULL, true);
   1568
   1569		i = 0;
   1570		list_for_each_entry(node, &priv->sta_list, list) {
   1571			if (i++ != idx)
   1572				continue;
   1573			ether_addr_copy(mac, node->mac_addr);
   1574			return mwifiex_dump_station_info(priv, node, sinfo);
   1575		}
   1576	}
   1577
   1578	return -ENOENT;
   1579}
   1580
   1581static int
   1582mwifiex_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
   1583			     int idx, struct survey_info *survey)
   1584{
   1585	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1586	struct mwifiex_chan_stats *pchan_stats = priv->adapter->chan_stats;
   1587	enum nl80211_band band;
   1588
   1589	mwifiex_dbg(priv->adapter, DUMP, "dump_survey idx=%d\n", idx);
   1590
   1591	memset(survey, 0, sizeof(struct survey_info));
   1592
   1593	if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
   1594	    priv->media_connected && idx == 0) {
   1595			u8 curr_bss_band = priv->curr_bss_params.band;
   1596			u32 chan = priv->curr_bss_params.bss_descriptor.channel;
   1597
   1598			band = mwifiex_band_to_radio_type(curr_bss_band);
   1599			survey->channel = ieee80211_get_channel(wiphy,
   1600				ieee80211_channel_to_frequency(chan, band));
   1601
   1602			if (priv->bcn_nf_last) {
   1603				survey->filled = SURVEY_INFO_NOISE_DBM;
   1604				survey->noise = priv->bcn_nf_last;
   1605			}
   1606			return 0;
   1607	}
   1608
   1609	if (idx >= priv->adapter->num_in_chan_stats)
   1610		return -ENOENT;
   1611
   1612	if (!pchan_stats[idx].cca_scan_dur)
   1613		return 0;
   1614
   1615	band = pchan_stats[idx].bandcfg;
   1616	survey->channel = ieee80211_get_channel(wiphy,
   1617	    ieee80211_channel_to_frequency(pchan_stats[idx].chan_num, band));
   1618	survey->filled = SURVEY_INFO_NOISE_DBM |
   1619			 SURVEY_INFO_TIME |
   1620			 SURVEY_INFO_TIME_BUSY;
   1621	survey->noise = pchan_stats[idx].noise;
   1622	survey->time = pchan_stats[idx].cca_scan_dur;
   1623	survey->time_busy = pchan_stats[idx].cca_busy_dur;
   1624
   1625	return 0;
   1626}
   1627
   1628/* Supported rates to be advertised to the cfg80211 */
   1629static struct ieee80211_rate mwifiex_rates[] = {
   1630	{.bitrate = 10, .hw_value = 2, },
   1631	{.bitrate = 20, .hw_value = 4, },
   1632	{.bitrate = 55, .hw_value = 11, },
   1633	{.bitrate = 110, .hw_value = 22, },
   1634	{.bitrate = 60, .hw_value = 12, },
   1635	{.bitrate = 90, .hw_value = 18, },
   1636	{.bitrate = 120, .hw_value = 24, },
   1637	{.bitrate = 180, .hw_value = 36, },
   1638	{.bitrate = 240, .hw_value = 48, },
   1639	{.bitrate = 360, .hw_value = 72, },
   1640	{.bitrate = 480, .hw_value = 96, },
   1641	{.bitrate = 540, .hw_value = 108, },
   1642};
   1643
   1644/* Channel definitions to be advertised to cfg80211 */
   1645static struct ieee80211_channel mwifiex_channels_2ghz[] = {
   1646	{.center_freq = 2412, .hw_value = 1, },
   1647	{.center_freq = 2417, .hw_value = 2, },
   1648	{.center_freq = 2422, .hw_value = 3, },
   1649	{.center_freq = 2427, .hw_value = 4, },
   1650	{.center_freq = 2432, .hw_value = 5, },
   1651	{.center_freq = 2437, .hw_value = 6, },
   1652	{.center_freq = 2442, .hw_value = 7, },
   1653	{.center_freq = 2447, .hw_value = 8, },
   1654	{.center_freq = 2452, .hw_value = 9, },
   1655	{.center_freq = 2457, .hw_value = 10, },
   1656	{.center_freq = 2462, .hw_value = 11, },
   1657	{.center_freq = 2467, .hw_value = 12, },
   1658	{.center_freq = 2472, .hw_value = 13, },
   1659	{.center_freq = 2484, .hw_value = 14, },
   1660};
   1661
   1662static struct ieee80211_supported_band mwifiex_band_2ghz = {
   1663	.channels = mwifiex_channels_2ghz,
   1664	.n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
   1665	.bitrates = mwifiex_rates,
   1666	.n_bitrates = ARRAY_SIZE(mwifiex_rates),
   1667};
   1668
   1669static struct ieee80211_channel mwifiex_channels_5ghz[] = {
   1670	{.center_freq = 5040, .hw_value = 8, },
   1671	{.center_freq = 5060, .hw_value = 12, },
   1672	{.center_freq = 5080, .hw_value = 16, },
   1673	{.center_freq = 5170, .hw_value = 34, },
   1674	{.center_freq = 5190, .hw_value = 38, },
   1675	{.center_freq = 5210, .hw_value = 42, },
   1676	{.center_freq = 5230, .hw_value = 46, },
   1677	{.center_freq = 5180, .hw_value = 36, },
   1678	{.center_freq = 5200, .hw_value = 40, },
   1679	{.center_freq = 5220, .hw_value = 44, },
   1680	{.center_freq = 5240, .hw_value = 48, },
   1681	{.center_freq = 5260, .hw_value = 52, },
   1682	{.center_freq = 5280, .hw_value = 56, },
   1683	{.center_freq = 5300, .hw_value = 60, },
   1684	{.center_freq = 5320, .hw_value = 64, },
   1685	{.center_freq = 5500, .hw_value = 100, },
   1686	{.center_freq = 5520, .hw_value = 104, },
   1687	{.center_freq = 5540, .hw_value = 108, },
   1688	{.center_freq = 5560, .hw_value = 112, },
   1689	{.center_freq = 5580, .hw_value = 116, },
   1690	{.center_freq = 5600, .hw_value = 120, },
   1691	{.center_freq = 5620, .hw_value = 124, },
   1692	{.center_freq = 5640, .hw_value = 128, },
   1693	{.center_freq = 5660, .hw_value = 132, },
   1694	{.center_freq = 5680, .hw_value = 136, },
   1695	{.center_freq = 5700, .hw_value = 140, },
   1696	{.center_freq = 5745, .hw_value = 149, },
   1697	{.center_freq = 5765, .hw_value = 153, },
   1698	{.center_freq = 5785, .hw_value = 157, },
   1699	{.center_freq = 5805, .hw_value = 161, },
   1700	{.center_freq = 5825, .hw_value = 165, },
   1701};
   1702
   1703static struct ieee80211_supported_band mwifiex_band_5ghz = {
   1704	.channels = mwifiex_channels_5ghz,
   1705	.n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
   1706	.bitrates = mwifiex_rates + 4,
   1707	.n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4,
   1708};
   1709
   1710
   1711/* Supported crypto cipher suits to be advertised to cfg80211 */
   1712static const u32 mwifiex_cipher_suites[] = {
   1713	WLAN_CIPHER_SUITE_WEP40,
   1714	WLAN_CIPHER_SUITE_WEP104,
   1715	WLAN_CIPHER_SUITE_TKIP,
   1716	WLAN_CIPHER_SUITE_CCMP,
   1717	WLAN_CIPHER_SUITE_SMS4,
   1718	WLAN_CIPHER_SUITE_AES_CMAC,
   1719};
   1720
   1721/* Supported mgmt frame types to be advertised to cfg80211 */
   1722static const struct ieee80211_txrx_stypes
   1723mwifiex_mgmt_stypes[NUM_NL80211_IFTYPES] = {
   1724	[NL80211_IFTYPE_STATION] = {
   1725		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1726		      BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
   1727		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1728		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
   1729	},
   1730	[NL80211_IFTYPE_AP] = {
   1731		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1732		      BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
   1733		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1734		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
   1735	},
   1736	[NL80211_IFTYPE_P2P_CLIENT] = {
   1737		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1738		      BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
   1739		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1740		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
   1741	},
   1742	[NL80211_IFTYPE_P2P_GO] = {
   1743		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1744		      BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
   1745		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   1746		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
   1747	},
   1748};
   1749
   1750/*
   1751 * CFG802.11 operation handler for setting bit rates.
   1752 *
   1753 * Function configures data rates to firmware using bitrate mask
   1754 * provided by cfg80211.
   1755 */
   1756static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
   1757				struct net_device *dev,
   1758				const u8 *peer,
   1759				const struct cfg80211_bitrate_mask *mask)
   1760{
   1761	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1762	u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
   1763	enum nl80211_band band;
   1764	struct mwifiex_adapter *adapter = priv->adapter;
   1765
   1766	if (!priv->media_connected) {
   1767		mwifiex_dbg(adapter, ERROR,
   1768			    "Can not set Tx data rate in disconnected state\n");
   1769		return -EINVAL;
   1770	}
   1771
   1772	band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
   1773
   1774	memset(bitmap_rates, 0, sizeof(bitmap_rates));
   1775
   1776	/* Fill HR/DSSS rates. */
   1777	if (band == NL80211_BAND_2GHZ)
   1778		bitmap_rates[0] = mask->control[band].legacy & 0x000f;
   1779
   1780	/* Fill OFDM rates */
   1781	if (band == NL80211_BAND_2GHZ)
   1782		bitmap_rates[1] = (mask->control[band].legacy & 0x0ff0) >> 4;
   1783	else
   1784		bitmap_rates[1] = mask->control[band].legacy;
   1785
   1786	/* Fill HT MCS rates */
   1787	bitmap_rates[2] = mask->control[band].ht_mcs[0];
   1788	if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
   1789		bitmap_rates[2] |= mask->control[band].ht_mcs[1] << 8;
   1790
   1791       /* Fill VHT MCS rates */
   1792	if (adapter->fw_api_ver == MWIFIEX_FW_V15) {
   1793		bitmap_rates[10] = mask->control[band].vht_mcs[0];
   1794		if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
   1795			bitmap_rates[11] = mask->control[band].vht_mcs[1];
   1796	}
   1797
   1798	return mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
   1799				HostCmd_ACT_GEN_SET, 0, bitmap_rates, true);
   1800}
   1801
   1802/*
   1803 * CFG802.11 operation handler for connection quality monitoring.
   1804 *
   1805 * This function subscribes/unsubscribes HIGH_RSSI and LOW_RSSI
   1806 * events to FW.
   1807 */
   1808static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
   1809						struct net_device *dev,
   1810						s32 rssi_thold, u32 rssi_hyst)
   1811{
   1812	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1813	struct mwifiex_ds_misc_subsc_evt subsc_evt;
   1814
   1815	priv->cqm_rssi_thold = rssi_thold;
   1816	priv->cqm_rssi_hyst = rssi_hyst;
   1817
   1818	memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
   1819	subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
   1820
   1821	/* Subscribe/unsubscribe low and high rssi events */
   1822	if (rssi_thold && rssi_hyst) {
   1823		subsc_evt.action = HostCmd_ACT_BITWISE_SET;
   1824		subsc_evt.bcn_l_rssi_cfg.abs_value = abs(rssi_thold);
   1825		subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold);
   1826		subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
   1827		subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
   1828		return mwifiex_send_cmd(priv,
   1829					HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
   1830					0, 0, &subsc_evt, true);
   1831	} else {
   1832		subsc_evt.action = HostCmd_ACT_BITWISE_CLR;
   1833		return mwifiex_send_cmd(priv,
   1834					HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
   1835					0, 0, &subsc_evt, true);
   1836	}
   1837
   1838	return 0;
   1839}
   1840
   1841/* cfg80211 operation handler for change_beacon.
   1842 * Function retrieves and sets modified management IEs to FW.
   1843 */
   1844static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
   1845					  struct net_device *dev,
   1846					  struct cfg80211_beacon_data *data)
   1847{
   1848	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1849	struct mwifiex_adapter *adapter = priv->adapter;
   1850
   1851	mwifiex_cancel_scan(adapter);
   1852
   1853	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
   1854		mwifiex_dbg(priv->adapter, ERROR,
   1855			    "%s: bss_type mismatched\n", __func__);
   1856		return -EINVAL;
   1857	}
   1858
   1859	if (!priv->bss_started) {
   1860		mwifiex_dbg(priv->adapter, ERROR,
   1861			    "%s: bss not started\n", __func__);
   1862		return -EINVAL;
   1863	}
   1864
   1865	if (mwifiex_set_mgmt_ies(priv, data)) {
   1866		mwifiex_dbg(priv->adapter, ERROR,
   1867			    "%s: setting mgmt ies failed\n", __func__);
   1868		return -EFAULT;
   1869	}
   1870
   1871	return 0;
   1872}
   1873
   1874/* cfg80211 operation handler for del_station.
   1875 * Function deauthenticates station which value is provided in mac parameter.
   1876 * If mac is NULL/broadcast, all stations in associated station list are
   1877 * deauthenticated. If bss is not started or there are no stations in
   1878 * associated stations list, no action is taken.
   1879 */
   1880static int
   1881mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
   1882			     struct station_del_parameters *params)
   1883{
   1884	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   1885	struct mwifiex_sta_node *sta_node;
   1886	u8 deauth_mac[ETH_ALEN];
   1887
   1888	if (!priv->bss_started && priv->wdev.cac_started) {
   1889		mwifiex_dbg(priv->adapter, INFO, "%s: abort CAC!\n", __func__);
   1890		mwifiex_abort_cac(priv);
   1891	}
   1892
   1893	if (list_empty(&priv->sta_list) || !priv->bss_started)
   1894		return 0;
   1895
   1896	if (!params->mac || is_broadcast_ether_addr(params->mac))
   1897		return 0;
   1898
   1899	mwifiex_dbg(priv->adapter, INFO, "%s: mac address %pM\n",
   1900		    __func__, params->mac);
   1901
   1902	eth_zero_addr(deauth_mac);
   1903
   1904	spin_lock_bh(&priv->sta_list_spinlock);
   1905	sta_node = mwifiex_get_sta_entry(priv, params->mac);
   1906	if (sta_node)
   1907		ether_addr_copy(deauth_mac, params->mac);
   1908	spin_unlock_bh(&priv->sta_list_spinlock);
   1909
   1910	if (is_valid_ether_addr(deauth_mac)) {
   1911		if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
   1912				     HostCmd_ACT_GEN_SET, 0,
   1913				     deauth_mac, true))
   1914			return -1;
   1915	}
   1916
   1917	return 0;
   1918}
   1919
   1920static int
   1921mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
   1922{
   1923	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
   1924	struct mwifiex_private *priv = mwifiex_get_priv(adapter,
   1925							MWIFIEX_BSS_ROLE_ANY);
   1926	struct mwifiex_ds_ant_cfg ant_cfg;
   1927
   1928	if (!tx_ant || !rx_ant)
   1929		return -EOPNOTSUPP;
   1930
   1931	if (adapter->hw_dev_mcs_support != HT_STREAM_2X2) {
   1932		/* Not a MIMO chip. User should provide specific antenna number
   1933		 * for Tx/Rx path or enable all antennas for diversity
   1934		 */
   1935		if (tx_ant != rx_ant)
   1936			return -EOPNOTSUPP;
   1937
   1938		if ((tx_ant & (tx_ant - 1)) &&
   1939		    (tx_ant != BIT(adapter->number_of_antenna) - 1))
   1940			return -EOPNOTSUPP;
   1941
   1942		if ((tx_ant == BIT(adapter->number_of_antenna) - 1) &&
   1943		    (priv->adapter->number_of_antenna > 1)) {
   1944			tx_ant = RF_ANTENNA_AUTO;
   1945			rx_ant = RF_ANTENNA_AUTO;
   1946		}
   1947	} else {
   1948		struct ieee80211_sta_ht_cap *ht_info;
   1949		int rx_mcs_supp;
   1950		enum nl80211_band band;
   1951
   1952		if ((tx_ant == 0x1 && rx_ant == 0x1)) {
   1953			adapter->user_dev_mcs_support = HT_STREAM_1X1;
   1954			if (adapter->is_hw_11ac_capable)
   1955				adapter->usr_dot_11ac_mcs_support =
   1956						MWIFIEX_11AC_MCS_MAP_1X1;
   1957		} else {
   1958			adapter->user_dev_mcs_support = HT_STREAM_2X2;
   1959			if (adapter->is_hw_11ac_capable)
   1960				adapter->usr_dot_11ac_mcs_support =
   1961						MWIFIEX_11AC_MCS_MAP_2X2;
   1962		}
   1963
   1964		for (band = 0; band < NUM_NL80211_BANDS; band++) {
   1965			if (!adapter->wiphy->bands[band])
   1966				continue;
   1967
   1968			ht_info = &adapter->wiphy->bands[band]->ht_cap;
   1969			rx_mcs_supp =
   1970				GET_RXMCSSUPP(adapter->user_dev_mcs_support);
   1971			memset(&ht_info->mcs, 0, adapter->number_of_antenna);
   1972			memset(&ht_info->mcs, 0xff, rx_mcs_supp);
   1973		}
   1974	}
   1975
   1976	ant_cfg.tx_ant = tx_ant;
   1977	ant_cfg.rx_ant = rx_ant;
   1978
   1979	return mwifiex_send_cmd(priv, HostCmd_CMD_RF_ANTENNA,
   1980				HostCmd_ACT_GEN_SET, 0, &ant_cfg, true);
   1981}
   1982
   1983static int
   1984mwifiex_cfg80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
   1985{
   1986	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
   1987	struct mwifiex_private *priv = mwifiex_get_priv(adapter,
   1988							MWIFIEX_BSS_ROLE_ANY);
   1989	mwifiex_send_cmd(priv, HostCmd_CMD_RF_ANTENNA,
   1990			 HostCmd_ACT_GEN_GET, 0, NULL, true);
   1991
   1992	*tx_ant = priv->tx_ant;
   1993	*rx_ant = priv->rx_ant;
   1994
   1995	return 0;
   1996}
   1997
   1998/* cfg80211 operation handler for stop ap.
   1999 * Function stops BSS running at uAP interface.
   2000 */
   2001static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
   2002{
   2003	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2004
   2005	mwifiex_abort_cac(priv);
   2006
   2007	if (mwifiex_del_mgmt_ies(priv))
   2008		mwifiex_dbg(priv->adapter, ERROR,
   2009			    "Failed to delete mgmt IEs!\n");
   2010
   2011	priv->ap_11n_enabled = 0;
   2012	memset(&priv->bss_cfg, 0, sizeof(priv->bss_cfg));
   2013
   2014	if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
   2015			     HostCmd_ACT_GEN_SET, 0, NULL, true)) {
   2016		mwifiex_dbg(priv->adapter, ERROR,
   2017			    "Failed to stop the BSS\n");
   2018		return -1;
   2019	}
   2020
   2021	if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET,
   2022			     HostCmd_ACT_GEN_SET, 0, NULL, true)) {
   2023		mwifiex_dbg(priv->adapter, ERROR,
   2024			    "Failed to reset BSS\n");
   2025		return -1;
   2026	}
   2027
   2028	if (netif_carrier_ok(priv->netdev))
   2029		netif_carrier_off(priv->netdev);
   2030	mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
   2031
   2032	return 0;
   2033}
   2034
   2035/* cfg80211 operation handler for start_ap.
   2036 * Function sets beacon period, DTIM period, SSID and security into
   2037 * AP config structure.
   2038 * AP is configured with these settings and BSS is started.
   2039 */
   2040static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
   2041				     struct net_device *dev,
   2042				     struct cfg80211_ap_settings *params)
   2043{
   2044	struct mwifiex_uap_bss_param *bss_cfg;
   2045	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2046
   2047	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
   2048		return -1;
   2049
   2050	bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
   2051	if (!bss_cfg)
   2052		return -ENOMEM;
   2053
   2054	mwifiex_set_sys_config_invalid_data(bss_cfg);
   2055
   2056	if (params->beacon_interval)
   2057		bss_cfg->beacon_period = params->beacon_interval;
   2058	if (params->dtim_period)
   2059		bss_cfg->dtim_period = params->dtim_period;
   2060
   2061	if (params->ssid && params->ssid_len) {
   2062		memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len);
   2063		bss_cfg->ssid.ssid_len = params->ssid_len;
   2064	}
   2065	if (params->inactivity_timeout > 0) {
   2066		/* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */
   2067		bss_cfg->sta_ao_timer = 10 * params->inactivity_timeout;
   2068		bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout;
   2069	}
   2070
   2071	switch (params->hidden_ssid) {
   2072	case NL80211_HIDDEN_SSID_NOT_IN_USE:
   2073		bss_cfg->bcast_ssid_ctl = 1;
   2074		break;
   2075	case NL80211_HIDDEN_SSID_ZERO_LEN:
   2076		bss_cfg->bcast_ssid_ctl = 0;
   2077		break;
   2078	case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
   2079		bss_cfg->bcast_ssid_ctl = 2;
   2080		break;
   2081	default:
   2082		kfree(bss_cfg);
   2083		return -EINVAL;
   2084	}
   2085
   2086	mwifiex_uap_set_channel(priv, bss_cfg, params->chandef);
   2087	mwifiex_set_uap_rates(bss_cfg, params);
   2088
   2089	if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
   2090		mwifiex_dbg(priv->adapter, ERROR,
   2091			    "Failed to parse security parameters!\n");
   2092		goto out;
   2093	}
   2094
   2095	mwifiex_set_ht_params(priv, bss_cfg, params);
   2096
   2097	if (priv->adapter->is_hw_11ac_capable) {
   2098		mwifiex_set_vht_params(priv, bss_cfg, params);
   2099		mwifiex_set_vht_width(priv, params->chandef.width,
   2100				      priv->ap_11ac_enabled);
   2101	}
   2102
   2103	if (priv->ap_11ac_enabled)
   2104		mwifiex_set_11ac_ba_params(priv);
   2105	else
   2106		mwifiex_set_ba_params(priv);
   2107
   2108	mwifiex_set_wmm_params(priv, bss_cfg, params);
   2109
   2110	if (mwifiex_is_11h_active(priv))
   2111		mwifiex_set_tpc_params(priv, bss_cfg, params);
   2112
   2113	if (mwifiex_is_11h_active(priv) &&
   2114	    !cfg80211_chandef_dfs_required(wiphy, &params->chandef,
   2115					   priv->bss_mode)) {
   2116		mwifiex_dbg(priv->adapter, INFO,
   2117			    "Disable 11h extensions in FW\n");
   2118		if (mwifiex_11h_activate(priv, false)) {
   2119			mwifiex_dbg(priv->adapter, ERROR,
   2120				    "Failed to disable 11h extensions!!");
   2121			goto out;
   2122		}
   2123		priv->state_11h.is_11h_active = false;
   2124	}
   2125
   2126	mwifiex_config_uap_11d(priv, &params->beacon);
   2127
   2128	if (mwifiex_config_start_uap(priv, bss_cfg)) {
   2129		mwifiex_dbg(priv->adapter, ERROR,
   2130			    "Failed to start AP\n");
   2131		goto out;
   2132	}
   2133
   2134	if (mwifiex_set_mgmt_ies(priv, &params->beacon))
   2135		goto out;
   2136
   2137	if (!netif_carrier_ok(priv->netdev))
   2138		netif_carrier_on(priv->netdev);
   2139	mwifiex_wake_up_net_dev_queue(priv->netdev, priv->adapter);
   2140
   2141	memcpy(&priv->bss_cfg, bss_cfg, sizeof(priv->bss_cfg));
   2142	kfree(bss_cfg);
   2143	return 0;
   2144
   2145out:
   2146	kfree(bss_cfg);
   2147	return -1;
   2148}
   2149
   2150/*
   2151 * CFG802.11 operation handler for disconnection request.
   2152 *
   2153 * This function does not work when there is already a disconnection
   2154 * procedure going on.
   2155 */
   2156static int
   2157mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
   2158			    u16 reason_code)
   2159{
   2160	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2161
   2162	if (!mwifiex_stop_bg_scan(priv))
   2163		cfg80211_sched_scan_stopped_locked(priv->wdev.wiphy, 0);
   2164
   2165	if (mwifiex_deauthenticate(priv, NULL))
   2166		return -EFAULT;
   2167
   2168	eth_zero_addr(priv->cfg_bssid);
   2169	priv->hs2_enabled = false;
   2170
   2171	return 0;
   2172}
   2173
   2174/*
   2175 * This function informs the CFG802.11 subsystem of a new IBSS.
   2176 *
   2177 * The following information are sent to the CFG802.11 subsystem
   2178 * to register the new IBSS. If we do not register the new IBSS,
   2179 * a kernel panic will result.
   2180 *      - SSID
   2181 *      - SSID length
   2182 *      - BSSID
   2183 *      - Channel
   2184 */
   2185static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
   2186{
   2187	struct ieee80211_channel *chan;
   2188	struct mwifiex_bss_info bss_info;
   2189	struct cfg80211_bss *bss;
   2190	int ie_len;
   2191	u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
   2192	enum nl80211_band band;
   2193
   2194	if (mwifiex_get_bss_info(priv, &bss_info))
   2195		return -1;
   2196
   2197	ie_buf[0] = WLAN_EID_SSID;
   2198	ie_buf[1] = bss_info.ssid.ssid_len;
   2199
   2200	memcpy(&ie_buf[sizeof(struct ieee_types_header)],
   2201	       &bss_info.ssid.ssid, bss_info.ssid.ssid_len);
   2202	ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
   2203
   2204	band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
   2205	chan = ieee80211_get_channel(priv->wdev.wiphy,
   2206			ieee80211_channel_to_frequency(bss_info.bss_chan,
   2207						       band));
   2208
   2209	bss = cfg80211_inform_bss(priv->wdev.wiphy, chan,
   2210				  CFG80211_BSS_FTYPE_UNKNOWN,
   2211				  bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
   2212				  0, ie_buf, ie_len, 0, GFP_KERNEL);
   2213	if (bss) {
   2214		cfg80211_put_bss(priv->wdev.wiphy, bss);
   2215		ether_addr_copy(priv->cfg_bssid, bss_info.bssid);
   2216	}
   2217
   2218	return 0;
   2219}
   2220
   2221/*
   2222 * This function connects with a BSS.
   2223 *
   2224 * This function handles both Infra and Ad-Hoc modes. It also performs
   2225 * validity checking on the provided parameters, disconnects from the
   2226 * current BSS (if any), sets up the association/scan parameters,
   2227 * including security settings, and performs specific SSID scan before
   2228 * trying to connect.
   2229 *
   2230 * For Infra mode, the function returns failure if the specified SSID
   2231 * is not found in scan table. However, for Ad-Hoc mode, it can create
   2232 * the IBSS if it does not exist. On successful completion in either case,
   2233 * the function notifies the CFG802.11 subsystem of the new BSS connection.
   2234 */
   2235static int
   2236mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
   2237		       const u8 *ssid, const u8 *bssid, int mode,
   2238		       struct ieee80211_channel *channel,
   2239		       struct cfg80211_connect_params *sme, bool privacy,
   2240		       struct cfg80211_bss **sel_bss)
   2241{
   2242	struct cfg80211_ssid req_ssid;
   2243	int ret, auth_type = 0;
   2244	struct cfg80211_bss *bss = NULL;
   2245	u8 is_scanning_required = 0;
   2246
   2247	memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
   2248
   2249	req_ssid.ssid_len = ssid_len;
   2250	if (ssid_len > IEEE80211_MAX_SSID_LEN) {
   2251		mwifiex_dbg(priv->adapter, ERROR, "invalid SSID - aborting\n");
   2252		return -EINVAL;
   2253	}
   2254
   2255	memcpy(req_ssid.ssid, ssid, ssid_len);
   2256	if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
   2257		mwifiex_dbg(priv->adapter, ERROR, "invalid SSID - aborting\n");
   2258		return -EINVAL;
   2259	}
   2260
   2261	/* As this is new association, clear locally stored
   2262	 * keys and security related flags */
   2263	priv->sec_info.wpa_enabled = false;
   2264	priv->sec_info.wpa2_enabled = false;
   2265	priv->wep_key_curr_index = 0;
   2266	priv->sec_info.encryption_mode = 0;
   2267	priv->sec_info.is_authtype_auto = 0;
   2268	ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
   2269
   2270	if (mode == NL80211_IFTYPE_ADHOC) {
   2271		u16 enable = true;
   2272
   2273		/* set ibss coalescing_status */
   2274		ret = mwifiex_send_cmd(
   2275				priv,
   2276				HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
   2277				HostCmd_ACT_GEN_SET, 0, &enable, true);
   2278		if (ret)
   2279			return ret;
   2280
   2281		/* "privacy" is set only for ad-hoc mode */
   2282		if (privacy) {
   2283			/*
   2284			 * Keep WLAN_CIPHER_SUITE_WEP104 for now so that
   2285			 * the firmware can find a matching network from the
   2286			 * scan. The cfg80211 does not give us the encryption
   2287			 * mode at this stage so just setting it to WEP here.
   2288			 */
   2289			priv->sec_info.encryption_mode =
   2290					WLAN_CIPHER_SUITE_WEP104;
   2291			priv->sec_info.authentication_mode =
   2292					NL80211_AUTHTYPE_OPEN_SYSTEM;
   2293		}
   2294
   2295		goto done;
   2296	}
   2297
   2298	/* Now handle infra mode. "sme" is valid for infra mode only */
   2299	if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
   2300		auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
   2301		priv->sec_info.is_authtype_auto = 1;
   2302	} else {
   2303		auth_type = sme->auth_type;
   2304	}
   2305
   2306	if (sme->crypto.n_ciphers_pairwise) {
   2307		priv->sec_info.encryption_mode =
   2308						sme->crypto.ciphers_pairwise[0];
   2309		priv->sec_info.authentication_mode = auth_type;
   2310	}
   2311
   2312	if (sme->crypto.cipher_group) {
   2313		priv->sec_info.encryption_mode = sme->crypto.cipher_group;
   2314		priv->sec_info.authentication_mode = auth_type;
   2315	}
   2316	if (sme->ie)
   2317		ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
   2318
   2319	if (sme->key) {
   2320		if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) {
   2321			mwifiex_dbg(priv->adapter, INFO,
   2322				    "info: setting wep encryption\t"
   2323				    "with key len %d\n", sme->key_len);
   2324			priv->wep_key_curr_index = sme->key_idx;
   2325			ret = mwifiex_set_encode(priv, NULL, sme->key,
   2326						 sme->key_len, sme->key_idx,
   2327						 NULL, 0);
   2328		}
   2329	}
   2330done:
   2331	/*
   2332	 * Scan entries are valid for some time (15 sec). So we can save one
   2333	 * active scan time if we just try cfg80211_get_bss first. If it fails
   2334	 * then request scan and cfg80211_get_bss() again for final output.
   2335	 */
   2336	while (1) {
   2337		if (is_scanning_required) {
   2338			/* Do specific SSID scanning */
   2339			if (mwifiex_request_scan(priv, &req_ssid)) {
   2340				mwifiex_dbg(priv->adapter, ERROR, "scan error\n");
   2341				return -EFAULT;
   2342			}
   2343		}
   2344
   2345		/* Find the BSS we want using available scan results */
   2346		if (mode == NL80211_IFTYPE_ADHOC)
   2347			bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
   2348					       bssid, ssid, ssid_len,
   2349					       IEEE80211_BSS_TYPE_IBSS,
   2350					       IEEE80211_PRIVACY_ANY);
   2351		else
   2352			bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
   2353					       bssid, ssid, ssid_len,
   2354					       IEEE80211_BSS_TYPE_ESS,
   2355					       IEEE80211_PRIVACY_ANY);
   2356
   2357		if (!bss) {
   2358			if (is_scanning_required) {
   2359				mwifiex_dbg(priv->adapter, MSG,
   2360					    "assoc: requested bss not found in scan results\n");
   2361				break;
   2362			}
   2363			is_scanning_required = 1;
   2364		} else {
   2365			mwifiex_dbg(priv->adapter, MSG,
   2366				    "info: trying to associate to bssid %pM\n",
   2367				    bss->bssid);
   2368			memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
   2369			break;
   2370		}
   2371	}
   2372
   2373	if (bss)
   2374		cfg80211_ref_bss(priv->adapter->wiphy, bss);
   2375
   2376	ret = mwifiex_bss_start(priv, bss, &req_ssid);
   2377	if (ret)
   2378		goto cleanup;
   2379
   2380	if (mode == NL80211_IFTYPE_ADHOC) {
   2381		/* Inform the BSS information to kernel, otherwise
   2382		 * kernel will give a panic after successful assoc */
   2383		if (mwifiex_cfg80211_inform_ibss_bss(priv)) {
   2384			ret = -EFAULT;
   2385			goto cleanup;
   2386		}
   2387	}
   2388
   2389	/* Pass the selected BSS entry to caller. */
   2390	if (sel_bss) {
   2391		*sel_bss = bss;
   2392		bss = NULL;
   2393	}
   2394
   2395cleanup:
   2396	if (bss)
   2397		cfg80211_put_bss(priv->adapter->wiphy, bss);
   2398	return ret;
   2399}
   2400
   2401/*
   2402 * CFG802.11 operation handler for association request.
   2403 *
   2404 * This function does not work when the current mode is set to Ad-Hoc, or
   2405 * when there is already an association procedure going on. The given BSS
   2406 * information is used to associate.
   2407 */
   2408static int
   2409mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
   2410			 struct cfg80211_connect_params *sme)
   2411{
   2412	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2413	struct mwifiex_adapter *adapter = priv->adapter;
   2414	struct cfg80211_bss *bss = NULL;
   2415	int ret;
   2416
   2417	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
   2418		mwifiex_dbg(adapter, ERROR,
   2419			    "%s: reject infra assoc request in non-STA role\n",
   2420			    dev->name);
   2421		return -EINVAL;
   2422	}
   2423
   2424	if (priv->wdev.current_bss) {
   2425		mwifiex_dbg(adapter, ERROR,
   2426			    "%s: already connected\n", dev->name);
   2427		return -EALREADY;
   2428	}
   2429
   2430	if (priv->scan_block)
   2431		priv->scan_block = false;
   2432
   2433	if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags) ||
   2434	    test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags)) {
   2435		mwifiex_dbg(adapter, ERROR,
   2436			    "%s: Ignore connection.\t"
   2437			    "Card removed or FW in bad state\n",
   2438			    dev->name);
   2439		return -EFAULT;
   2440	}
   2441
   2442	mwifiex_dbg(adapter, INFO,
   2443		    "info: Trying to associate to bssid %pM\n", sme->bssid);
   2444
   2445	if (!mwifiex_stop_bg_scan(priv))
   2446		cfg80211_sched_scan_stopped_locked(priv->wdev.wiphy, 0);
   2447
   2448	ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
   2449				     priv->bss_mode, sme->channel, sme, 0,
   2450				     &bss);
   2451	if (!ret) {
   2452		cfg80211_connect_bss(priv->netdev, priv->cfg_bssid, bss, NULL,
   2453				     0, NULL, 0, WLAN_STATUS_SUCCESS,
   2454				     GFP_KERNEL, NL80211_TIMEOUT_UNSPECIFIED);
   2455		mwifiex_dbg(priv->adapter, MSG,
   2456			    "info: associated to bssid %pM successfully\n",
   2457			    priv->cfg_bssid);
   2458		if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
   2459		    priv->adapter->auto_tdls &&
   2460		    priv->bss_type == MWIFIEX_BSS_TYPE_STA)
   2461			mwifiex_setup_auto_tdls_timer(priv);
   2462	} else {
   2463		mwifiex_dbg(priv->adapter, ERROR,
   2464			    "info: association to bssid %pM failed\n",
   2465			    priv->cfg_bssid);
   2466		eth_zero_addr(priv->cfg_bssid);
   2467
   2468		if (ret > 0)
   2469			cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
   2470						NULL, 0, NULL, 0, ret,
   2471						GFP_KERNEL);
   2472		else
   2473			cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
   2474						NULL, 0, NULL, 0,
   2475						WLAN_STATUS_UNSPECIFIED_FAILURE,
   2476						GFP_KERNEL);
   2477	}
   2478
   2479	return 0;
   2480}
   2481
   2482/*
   2483 * This function sets following parameters for ibss network.
   2484 *  -  channel
   2485 *  -  start band
   2486 *  -  11n flag
   2487 *  -  secondary channel offset
   2488 */
   2489static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
   2490				   struct cfg80211_ibss_params *params)
   2491{
   2492	struct mwifiex_adapter *adapter = priv->adapter;
   2493	int index = 0, i;
   2494	u8 config_bands = 0;
   2495
   2496	if (params->chandef.chan->band == NL80211_BAND_2GHZ) {
   2497		if (!params->basic_rates) {
   2498			config_bands = BAND_B | BAND_G;
   2499		} else {
   2500			for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) {
   2501				/*
   2502				 * Rates below 6 Mbps in the table are CCK
   2503				 * rates; 802.11b and from 6 they are OFDM;
   2504				 * 802.11G
   2505				 */
   2506				if (mwifiex_rates[i].bitrate == 60) {
   2507					index = 1 << i;
   2508					break;
   2509				}
   2510			}
   2511
   2512			if (params->basic_rates < index) {
   2513				config_bands = BAND_B;
   2514			} else {
   2515				config_bands = BAND_G;
   2516				if (params->basic_rates % index)
   2517					config_bands |= BAND_B;
   2518			}
   2519		}
   2520
   2521		if (cfg80211_get_chandef_type(&params->chandef) !=
   2522						NL80211_CHAN_NO_HT)
   2523			config_bands |= BAND_G | BAND_GN;
   2524	} else {
   2525		if (cfg80211_get_chandef_type(&params->chandef) ==
   2526						NL80211_CHAN_NO_HT)
   2527			config_bands = BAND_A;
   2528		else
   2529			config_bands = BAND_AN | BAND_A;
   2530	}
   2531
   2532	if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) {
   2533		adapter->config_bands = config_bands;
   2534		adapter->adhoc_start_band = config_bands;
   2535
   2536		if ((config_bands & BAND_GN) || (config_bands & BAND_AN))
   2537			adapter->adhoc_11n_enabled = true;
   2538		else
   2539			adapter->adhoc_11n_enabled = false;
   2540	}
   2541
   2542	adapter->sec_chan_offset =
   2543		mwifiex_chan_type_to_sec_chan_offset(
   2544			cfg80211_get_chandef_type(&params->chandef));
   2545	priv->adhoc_channel = ieee80211_frequency_to_channel(
   2546				params->chandef.chan->center_freq);
   2547
   2548	mwifiex_dbg(adapter, INFO,
   2549		    "info: set ibss band %d, chan %d, chan offset %d\n",
   2550		    config_bands, priv->adhoc_channel,
   2551		    adapter->sec_chan_offset);
   2552
   2553	return 0;
   2554}
   2555
   2556/*
   2557 * CFG802.11 operation handler to join an IBSS.
   2558 *
   2559 * This function does not work in any mode other than Ad-Hoc, or if
   2560 * a join operation is already in progress.
   2561 */
   2562static int
   2563mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
   2564			   struct cfg80211_ibss_params *params)
   2565{
   2566	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2567	int ret = 0;
   2568
   2569	if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
   2570		mwifiex_dbg(priv->adapter, ERROR,
   2571			    "request to join ibss received\t"
   2572			    "when station is not in ibss mode\n");
   2573		goto done;
   2574	}
   2575
   2576	mwifiex_dbg(priv->adapter, MSG, "info: trying to join to bssid %pM\n",
   2577		    params->bssid);
   2578
   2579	mwifiex_set_ibss_params(priv, params);
   2580
   2581	ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
   2582				     params->bssid, priv->bss_mode,
   2583				     params->chandef.chan, NULL,
   2584				     params->privacy, NULL);
   2585done:
   2586	if (!ret) {
   2587		cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
   2588				     params->chandef.chan, GFP_KERNEL);
   2589		mwifiex_dbg(priv->adapter, MSG,
   2590			    "info: joined/created adhoc network with bssid\t"
   2591			    "%pM successfully\n", priv->cfg_bssid);
   2592	} else {
   2593		mwifiex_dbg(priv->adapter, ERROR,
   2594			    "info: failed creating/joining adhoc network\n");
   2595	}
   2596
   2597	return ret;
   2598}
   2599
   2600/*
   2601 * CFG802.11 operation handler to leave an IBSS.
   2602 *
   2603 * This function does not work if a leave operation is
   2604 * already in progress.
   2605 */
   2606static int
   2607mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
   2608{
   2609	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2610
   2611	mwifiex_dbg(priv->adapter, MSG, "info: disconnecting from essid %pM\n",
   2612		    priv->cfg_bssid);
   2613	if (mwifiex_deauthenticate(priv, NULL))
   2614		return -EFAULT;
   2615
   2616	eth_zero_addr(priv->cfg_bssid);
   2617
   2618	return 0;
   2619}
   2620
   2621/*
   2622 * CFG802.11 operation handler for scan request.
   2623 *
   2624 * This function issues a scan request to the firmware based upon
   2625 * the user specified scan configuration. On successful completion,
   2626 * it also informs the results.
   2627 */
   2628static int
   2629mwifiex_cfg80211_scan(struct wiphy *wiphy,
   2630		      struct cfg80211_scan_request *request)
   2631{
   2632	struct net_device *dev = request->wdev->netdev;
   2633	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2634	int i, offset, ret;
   2635	struct ieee80211_channel *chan;
   2636	struct ieee_types_header *ie;
   2637	struct mwifiex_user_scan_cfg *user_scan_cfg;
   2638	u8 mac_addr[ETH_ALEN];
   2639
   2640	mwifiex_dbg(priv->adapter, CMD,
   2641		    "info: received scan request on %s\n", dev->name);
   2642
   2643	/* Block scan request if scan operation or scan cleanup when interface
   2644	 * is disabled is in process
   2645	 */
   2646	if (priv->scan_request || priv->scan_aborting) {
   2647		mwifiex_dbg(priv->adapter, WARN,
   2648			    "cmd: Scan already in process..\n");
   2649		return -EBUSY;
   2650	}
   2651
   2652	if (!priv->wdev.current_bss && priv->scan_block)
   2653		priv->scan_block = false;
   2654
   2655	if (!mwifiex_stop_bg_scan(priv))
   2656		cfg80211_sched_scan_stopped_locked(priv->wdev.wiphy, 0);
   2657
   2658	user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
   2659	if (!user_scan_cfg)
   2660		return -ENOMEM;
   2661
   2662	priv->scan_request = request;
   2663
   2664	if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
   2665		get_random_mask_addr(mac_addr, request->mac_addr,
   2666				     request->mac_addr_mask);
   2667		ether_addr_copy(request->mac_addr, mac_addr);
   2668		ether_addr_copy(user_scan_cfg->random_mac, mac_addr);
   2669	}
   2670
   2671	user_scan_cfg->num_ssids = request->n_ssids;
   2672	user_scan_cfg->ssid_list = request->ssids;
   2673
   2674	if (request->ie && request->ie_len) {
   2675		offset = 0;
   2676		for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
   2677			if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR)
   2678				continue;
   2679			priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN;
   2680			ie = (struct ieee_types_header *)(request->ie + offset);
   2681			memcpy(&priv->vs_ie[i].ie, ie, sizeof(*ie) + ie->len);
   2682			offset += sizeof(*ie) + ie->len;
   2683
   2684			if (offset >= request->ie_len)
   2685				break;
   2686		}
   2687	}
   2688
   2689	for (i = 0; i < min_t(u32, request->n_channels,
   2690			      MWIFIEX_USER_SCAN_CHAN_MAX); i++) {
   2691		chan = request->channels[i];
   2692		user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
   2693		user_scan_cfg->chan_list[i].radio_type = chan->band;
   2694
   2695		if ((chan->flags & IEEE80211_CHAN_NO_IR) || !request->n_ssids)
   2696			user_scan_cfg->chan_list[i].scan_type =
   2697						MWIFIEX_SCAN_TYPE_PASSIVE;
   2698		else
   2699			user_scan_cfg->chan_list[i].scan_type =
   2700						MWIFIEX_SCAN_TYPE_ACTIVE;
   2701
   2702		user_scan_cfg->chan_list[i].scan_time = 0;
   2703	}
   2704
   2705	if (priv->adapter->scan_chan_gap_enabled &&
   2706	    mwifiex_is_any_intf_active(priv))
   2707		user_scan_cfg->scan_chan_gap =
   2708					      priv->adapter->scan_chan_gap_time;
   2709
   2710	ret = mwifiex_scan_networks(priv, user_scan_cfg);
   2711	kfree(user_scan_cfg);
   2712	if (ret) {
   2713		mwifiex_dbg(priv->adapter, ERROR,
   2714			    "scan failed: %d\n", ret);
   2715		priv->scan_aborting = false;
   2716		priv->scan_request = NULL;
   2717		return ret;
   2718	}
   2719
   2720	if (request->ie && request->ie_len) {
   2721		for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
   2722			if (priv->vs_ie[i].mask == MWIFIEX_VSIE_MASK_SCAN) {
   2723				priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_CLEAR;
   2724				memset(&priv->vs_ie[i].ie, 0,
   2725				       MWIFIEX_MAX_VSIE_LEN);
   2726			}
   2727		}
   2728	}
   2729	return 0;
   2730}
   2731
   2732/* CFG802.11 operation handler for sched_scan_start.
   2733 *
   2734 * This function issues a bgscan config request to the firmware based upon
   2735 * the user specified sched_scan configuration. On successful completion,
   2736 * firmware will generate BGSCAN_REPORT event, driver should issue bgscan
   2737 * query command to get sched_scan results from firmware.
   2738 */
   2739static int
   2740mwifiex_cfg80211_sched_scan_start(struct wiphy *wiphy,
   2741				  struct net_device *dev,
   2742				  struct cfg80211_sched_scan_request *request)
   2743{
   2744	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2745	int i, offset;
   2746	struct ieee80211_channel *chan;
   2747	struct mwifiex_bg_scan_cfg *bgscan_cfg;
   2748	struct ieee_types_header *ie;
   2749
   2750	if (!request || (!request->n_ssids && !request->n_match_sets)) {
   2751		wiphy_err(wiphy, "%s : Invalid Sched_scan parameters",
   2752			  __func__);
   2753		return -EINVAL;
   2754	}
   2755
   2756	wiphy_info(wiphy, "sched_scan start : n_ssids=%d n_match_sets=%d ",
   2757		   request->n_ssids, request->n_match_sets);
   2758	wiphy_info(wiphy, "n_channels=%d interval=%d ie_len=%d\n",
   2759		   request->n_channels, request->scan_plans->interval,
   2760		   (int)request->ie_len);
   2761
   2762	bgscan_cfg = kzalloc(sizeof(*bgscan_cfg), GFP_KERNEL);
   2763	if (!bgscan_cfg)
   2764		return -ENOMEM;
   2765
   2766	if (priv->scan_request || priv->scan_aborting)
   2767		bgscan_cfg->start_later = true;
   2768
   2769	bgscan_cfg->num_ssids = request->n_match_sets;
   2770	bgscan_cfg->ssid_list = request->match_sets;
   2771
   2772	if (request->ie && request->ie_len) {
   2773		offset = 0;
   2774		for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
   2775			if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR)
   2776				continue;
   2777			priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_BGSCAN;
   2778			ie = (struct ieee_types_header *)(request->ie + offset);
   2779			memcpy(&priv->vs_ie[i].ie, ie, sizeof(*ie) + ie->len);
   2780			offset += sizeof(*ie) + ie->len;
   2781
   2782			if (offset >= request->ie_len)
   2783				break;
   2784		}
   2785	}
   2786
   2787	for (i = 0; i < min_t(u32, request->n_channels,
   2788			      MWIFIEX_BG_SCAN_CHAN_MAX); i++) {
   2789		chan = request->channels[i];
   2790		bgscan_cfg->chan_list[i].chan_number = chan->hw_value;
   2791		bgscan_cfg->chan_list[i].radio_type = chan->band;
   2792
   2793		if ((chan->flags & IEEE80211_CHAN_NO_IR) || !request->n_ssids)
   2794			bgscan_cfg->chan_list[i].scan_type =
   2795						MWIFIEX_SCAN_TYPE_PASSIVE;
   2796		else
   2797			bgscan_cfg->chan_list[i].scan_type =
   2798						MWIFIEX_SCAN_TYPE_ACTIVE;
   2799
   2800		bgscan_cfg->chan_list[i].scan_time = 0;
   2801	}
   2802
   2803	bgscan_cfg->chan_per_scan = min_t(u32, request->n_channels,
   2804					  MWIFIEX_BG_SCAN_CHAN_MAX);
   2805
   2806	/* Use at least 15 second for per scan cycle */
   2807	bgscan_cfg->scan_interval = (request->scan_plans->interval >
   2808				     MWIFIEX_BGSCAN_INTERVAL) ?
   2809				request->scan_plans->interval :
   2810				MWIFIEX_BGSCAN_INTERVAL;
   2811
   2812	bgscan_cfg->repeat_count = MWIFIEX_BGSCAN_REPEAT_COUNT;
   2813	bgscan_cfg->report_condition = MWIFIEX_BGSCAN_SSID_MATCH |
   2814				MWIFIEX_BGSCAN_WAIT_ALL_CHAN_DONE;
   2815	bgscan_cfg->bss_type = MWIFIEX_BSS_MODE_INFRA;
   2816	bgscan_cfg->action = MWIFIEX_BGSCAN_ACT_SET;
   2817	bgscan_cfg->enable = true;
   2818	if (request->min_rssi_thold != NL80211_SCAN_RSSI_THOLD_OFF) {
   2819		bgscan_cfg->report_condition |= MWIFIEX_BGSCAN_SSID_RSSI_MATCH;
   2820		bgscan_cfg->rssi_threshold = request->min_rssi_thold;
   2821	}
   2822
   2823	if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_CONFIG,
   2824			     HostCmd_ACT_GEN_SET, 0, bgscan_cfg, true)) {
   2825		kfree(bgscan_cfg);
   2826		return -EFAULT;
   2827	}
   2828
   2829	priv->sched_scanning = true;
   2830
   2831	kfree(bgscan_cfg);
   2832	return 0;
   2833}
   2834
   2835/* CFG802.11 operation handler for sched_scan_stop.
   2836 *
   2837 * This function issues a bgscan config command to disable
   2838 * previous bgscan configuration in the firmware
   2839 */
   2840static int mwifiex_cfg80211_sched_scan_stop(struct wiphy *wiphy,
   2841					    struct net_device *dev, u64 reqid)
   2842{
   2843	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   2844
   2845	wiphy_info(wiphy, "sched scan stop!");
   2846	mwifiex_stop_bg_scan(priv);
   2847
   2848	return 0;
   2849}
   2850
   2851static void mwifiex_setup_vht_caps(struct ieee80211_sta_vht_cap *vht_info,
   2852				   struct mwifiex_private *priv)
   2853{
   2854	struct mwifiex_adapter *adapter = priv->adapter;
   2855
   2856	vht_info->vht_supported = true;
   2857
   2858	vht_info->cap = adapter->hw_dot_11ac_dev_cap;
   2859	/* Update MCS support for VHT */
   2860	vht_info->vht_mcs.rx_mcs_map = cpu_to_le16(
   2861				adapter->hw_dot_11ac_mcs_support & 0xFFFF);
   2862	vht_info->vht_mcs.rx_highest = 0;
   2863	vht_info->vht_mcs.tx_mcs_map = cpu_to_le16(
   2864				adapter->hw_dot_11ac_mcs_support >> 16);
   2865	vht_info->vht_mcs.tx_highest = 0;
   2866}
   2867
   2868/*
   2869 * This function sets up the CFG802.11 specific HT capability fields
   2870 * with default values.
   2871 *
   2872 * The following default values are set -
   2873 *      - HT Supported = True
   2874 *      - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K
   2875 *      - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE
   2876 *      - HT Capabilities supported by firmware
   2877 *      - MCS information, Rx mask = 0xff
   2878 *      - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01)
   2879 */
   2880static void
   2881mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
   2882		      struct mwifiex_private *priv)
   2883{
   2884	int rx_mcs_supp;
   2885	struct ieee80211_mcs_info mcs_set;
   2886	u8 *mcs = (u8 *)&mcs_set;
   2887	struct mwifiex_adapter *adapter = priv->adapter;
   2888
   2889	ht_info->ht_supported = true;
   2890	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
   2891	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
   2892
   2893	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
   2894
   2895	/* Fill HT capability information */
   2896	if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
   2897		ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
   2898	else
   2899		ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
   2900
   2901	if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap))
   2902		ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
   2903	else
   2904		ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20;
   2905
   2906	if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap))
   2907		ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
   2908	else
   2909		ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40;
   2910
   2911	if (adapter->user_dev_mcs_support == HT_STREAM_2X2)
   2912		ht_info->cap |= 2 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
   2913	else
   2914		ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
   2915
   2916	if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap))
   2917		ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
   2918	else
   2919		ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC;
   2920
   2921	if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap))
   2922		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
   2923	else
   2924		ht_info->cap &= ~IEEE80211_HT_CAP_GRN_FLD;
   2925
   2926	if (ISENABLED_40MHZ_INTOLERANT(adapter->hw_dot_11n_dev_cap))
   2927		ht_info->cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
   2928	else
   2929		ht_info->cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT;
   2930
   2931	if (ISSUPP_RXLDPC(adapter->hw_dot_11n_dev_cap))
   2932		ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
   2933	else
   2934		ht_info->cap &= ~IEEE80211_HT_CAP_LDPC_CODING;
   2935
   2936	ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
   2937	ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
   2938
   2939	rx_mcs_supp = GET_RXMCSSUPP(adapter->user_dev_mcs_support);
   2940	/* Set MCS for 1x1/2x2 */
   2941	memset(mcs, 0xff, rx_mcs_supp);
   2942	/* Clear all the other values */
   2943	memset(&mcs[rx_mcs_supp], 0,
   2944	       sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
   2945	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
   2946	    ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
   2947		/* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
   2948		SETHT_MCS32(mcs_set.rx_mask);
   2949
   2950	memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info));
   2951
   2952	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
   2953}
   2954
   2955/*
   2956 *  create a new virtual interface with the given name and name assign type
   2957 */
   2958struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
   2959					      const char *name,
   2960					      unsigned char name_assign_type,
   2961					      enum nl80211_iftype type,
   2962					      struct vif_params *params)
   2963{
   2964	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
   2965	struct mwifiex_private *priv;
   2966	struct net_device *dev;
   2967	void *mdev_priv;
   2968	int ret;
   2969
   2970	if (!adapter)
   2971		return ERR_PTR(-EFAULT);
   2972
   2973	switch (type) {
   2974	case NL80211_IFTYPE_UNSPECIFIED:
   2975	case NL80211_IFTYPE_STATION:
   2976	case NL80211_IFTYPE_ADHOC:
   2977		if (adapter->curr_iface_comb.sta_intf ==
   2978		    adapter->iface_limit.sta_intf) {
   2979			mwifiex_dbg(adapter, ERROR,
   2980				    "cannot create multiple sta/adhoc ifaces\n");
   2981			return ERR_PTR(-EINVAL);
   2982		}
   2983
   2984		priv = mwifiex_get_unused_priv_by_bss_type(
   2985						adapter, MWIFIEX_BSS_TYPE_STA);
   2986		if (!priv) {
   2987			mwifiex_dbg(adapter, ERROR,
   2988				    "could not get free private struct\n");
   2989			return ERR_PTR(-EFAULT);
   2990		}
   2991
   2992		priv->wdev.wiphy = wiphy;
   2993		priv->wdev.iftype = NL80211_IFTYPE_STATION;
   2994
   2995		if (type == NL80211_IFTYPE_UNSPECIFIED)
   2996			priv->bss_mode = NL80211_IFTYPE_STATION;
   2997		else
   2998			priv->bss_mode = type;
   2999
   3000		priv->bss_type = MWIFIEX_BSS_TYPE_STA;
   3001		priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
   3002		priv->bss_priority = 0;
   3003		priv->bss_role = MWIFIEX_BSS_ROLE_STA;
   3004
   3005		break;
   3006	case NL80211_IFTYPE_AP:
   3007		if (adapter->curr_iface_comb.uap_intf ==
   3008		    adapter->iface_limit.uap_intf) {
   3009			mwifiex_dbg(adapter, ERROR,
   3010				    "cannot create multiple AP ifaces\n");
   3011			return ERR_PTR(-EINVAL);
   3012		}
   3013
   3014		priv = mwifiex_get_unused_priv_by_bss_type(
   3015						adapter, MWIFIEX_BSS_TYPE_UAP);
   3016		if (!priv) {
   3017			mwifiex_dbg(adapter, ERROR,
   3018				    "could not get free private struct\n");
   3019			return ERR_PTR(-EFAULT);
   3020		}
   3021
   3022		priv->wdev.wiphy = wiphy;
   3023		priv->wdev.iftype = NL80211_IFTYPE_AP;
   3024
   3025		priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
   3026		priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
   3027		priv->bss_priority = 0;
   3028		priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
   3029		priv->bss_started = 0;
   3030		priv->bss_mode = type;
   3031
   3032		break;
   3033	case NL80211_IFTYPE_P2P_CLIENT:
   3034		if (adapter->curr_iface_comb.p2p_intf ==
   3035		    adapter->iface_limit.p2p_intf) {
   3036			mwifiex_dbg(adapter, ERROR,
   3037				    "cannot create multiple P2P ifaces\n");
   3038			return ERR_PTR(-EINVAL);
   3039		}
   3040
   3041		priv = mwifiex_get_unused_priv_by_bss_type(
   3042						adapter, MWIFIEX_BSS_TYPE_P2P);
   3043		if (!priv) {
   3044			mwifiex_dbg(adapter, ERROR,
   3045				    "could not get free private struct\n");
   3046			return ERR_PTR(-EFAULT);
   3047		}
   3048
   3049		priv->wdev.wiphy = wiphy;
   3050		/* At start-up, wpa_supplicant tries to change the interface
   3051		 * to NL80211_IFTYPE_STATION if it is not managed mode.
   3052		 */
   3053		priv->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
   3054		priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT;
   3055
   3056		/* Setting bss_type to P2P tells firmware that this interface
   3057		 * is receiving P2P peers found during find phase and doing
   3058		 * action frame handshake.
   3059		 */
   3060		priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
   3061
   3062		priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
   3063		priv->bss_priority = 0;
   3064		priv->bss_role = MWIFIEX_BSS_ROLE_STA;
   3065		priv->bss_started = 0;
   3066
   3067		if (mwifiex_cfg80211_init_p2p_client(priv)) {
   3068			memset(&priv->wdev, 0, sizeof(priv->wdev));
   3069			priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
   3070			return ERR_PTR(-EFAULT);
   3071		}
   3072
   3073		break;
   3074	default:
   3075		mwifiex_dbg(adapter, ERROR, "type not supported\n");
   3076		return ERR_PTR(-EINVAL);
   3077	}
   3078
   3079	dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name,
   3080			       name_assign_type, ether_setup,
   3081			       IEEE80211_NUM_ACS, 1);
   3082	if (!dev) {
   3083		mwifiex_dbg(adapter, ERROR,
   3084			    "no memory available for netdevice\n");
   3085		ret = -ENOMEM;
   3086		goto err_alloc_netdev;
   3087	}
   3088
   3089	mwifiex_init_priv_params(priv, dev);
   3090
   3091	priv->netdev = dev;
   3092
   3093	if (!adapter->mfg_mode) {
   3094		mwifiex_set_mac_address(priv, dev, false, NULL);
   3095
   3096		ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
   3097				       HostCmd_ACT_GEN_SET, 0, NULL, true);
   3098		if (ret)
   3099			goto err_set_bss_mode;
   3100
   3101		ret = mwifiex_sta_init_cmd(priv, false, false);
   3102		if (ret)
   3103			goto err_sta_init;
   3104	}
   3105
   3106	mwifiex_setup_ht_caps(&wiphy->bands[NL80211_BAND_2GHZ]->ht_cap, priv);
   3107	if (adapter->is_hw_11ac_capable)
   3108		mwifiex_setup_vht_caps(
   3109			&wiphy->bands[NL80211_BAND_2GHZ]->vht_cap, priv);
   3110
   3111	if (adapter->config_bands & BAND_A)
   3112		mwifiex_setup_ht_caps(
   3113			&wiphy->bands[NL80211_BAND_5GHZ]->ht_cap, priv);
   3114
   3115	if ((adapter->config_bands & BAND_A) && adapter->is_hw_11ac_capable)
   3116		mwifiex_setup_vht_caps(
   3117			&wiphy->bands[NL80211_BAND_5GHZ]->vht_cap, priv);
   3118
   3119	dev_net_set(dev, wiphy_net(wiphy));
   3120	dev->ieee80211_ptr = &priv->wdev;
   3121	dev->ieee80211_ptr->iftype = priv->bss_mode;
   3122	SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
   3123
   3124	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
   3125	dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
   3126	dev->needed_headroom = MWIFIEX_MIN_DATA_HEADER_LEN;
   3127	dev->ethtool_ops = &mwifiex_ethtool_ops;
   3128
   3129	mdev_priv = netdev_priv(dev);
   3130	*((unsigned long *) mdev_priv) = (unsigned long) priv;
   3131
   3132	SET_NETDEV_DEV(dev, adapter->dev);
   3133
   3134	priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC%s",
   3135						  WQ_HIGHPRI |
   3136						  WQ_MEM_RECLAIM |
   3137						  WQ_UNBOUND, 1, name);
   3138	if (!priv->dfs_cac_workqueue) {
   3139		mwifiex_dbg(adapter, ERROR, "cannot alloc DFS CAC queue\n");
   3140		ret = -ENOMEM;
   3141		goto err_alloc_cac;
   3142	}
   3143
   3144	INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue);
   3145
   3146	priv->dfs_chan_sw_workqueue = alloc_workqueue("MWIFIEX_DFS_CHSW%s",
   3147						      WQ_HIGHPRI | WQ_UNBOUND |
   3148						      WQ_MEM_RECLAIM, 1, name);
   3149	if (!priv->dfs_chan_sw_workqueue) {
   3150		mwifiex_dbg(adapter, ERROR, "cannot alloc DFS channel sw queue\n");
   3151		ret = -ENOMEM;
   3152		goto err_alloc_chsw;
   3153	}
   3154
   3155	INIT_DELAYED_WORK(&priv->dfs_chan_sw_work,
   3156			  mwifiex_dfs_chan_sw_work_queue);
   3157
   3158	mutex_init(&priv->async_mutex);
   3159
   3160	/* Register network device */
   3161	if (cfg80211_register_netdevice(dev)) {
   3162		mwifiex_dbg(adapter, ERROR, "cannot register network device\n");
   3163		ret = -EFAULT;
   3164		goto err_reg_netdev;
   3165	}
   3166
   3167	mwifiex_dbg(adapter, INFO,
   3168		    "info: %s: Marvell 802.11 Adapter\n", dev->name);
   3169
   3170#ifdef CONFIG_DEBUG_FS
   3171	mwifiex_dev_debugfs_init(priv);
   3172#endif
   3173
   3174	update_vif_type_counter(adapter, type, +1);
   3175
   3176	return &priv->wdev;
   3177
   3178err_reg_netdev:
   3179	destroy_workqueue(priv->dfs_chan_sw_workqueue);
   3180	priv->dfs_chan_sw_workqueue = NULL;
   3181err_alloc_chsw:
   3182	destroy_workqueue(priv->dfs_cac_workqueue);
   3183	priv->dfs_cac_workqueue = NULL;
   3184err_alloc_cac:
   3185	free_netdev(dev);
   3186	priv->netdev = NULL;
   3187err_sta_init:
   3188err_set_bss_mode:
   3189err_alloc_netdev:
   3190	memset(&priv->wdev, 0, sizeof(priv->wdev));
   3191	priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
   3192	priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
   3193	return ERR_PTR(ret);
   3194}
   3195EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
   3196
   3197/*
   3198 * del_virtual_intf: remove the virtual interface determined by dev
   3199 */
   3200int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
   3201{
   3202	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
   3203	struct mwifiex_adapter *adapter = priv->adapter;
   3204	struct sk_buff *skb, *tmp;
   3205
   3206#ifdef CONFIG_DEBUG_FS
   3207	mwifiex_dev_debugfs_remove(priv);
   3208#endif
   3209
   3210	if (priv->sched_scanning)
   3211		priv->sched_scanning = false;
   3212
   3213	mwifiex_stop_net_dev_queue(priv->netdev, adapter);
   3214
   3215	skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) {
   3216		skb_unlink(skb, &priv->bypass_txq);
   3217		mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
   3218	}
   3219
   3220	if (netif_carrier_ok(priv->netdev))
   3221		netif_carrier_off(priv->netdev);
   3222
   3223	if (wdev->netdev->reg_state == NETREG_REGISTERED)
   3224		cfg80211_unregister_netdevice(wdev->netdev);
   3225
   3226	if (priv->dfs_cac_workqueue) {
   3227		destroy_workqueue(priv->dfs_cac_workqueue);
   3228		priv->dfs_cac_workqueue = NULL;
   3229	}
   3230
   3231	if (priv->dfs_chan_sw_workqueue) {
   3232		destroy_workqueue(priv->dfs_chan_sw_workqueue);
   3233		priv->dfs_chan_sw_workqueue = NULL;
   3234	}
   3235	/* Clear the priv in adapter */
   3236	priv->netdev = NULL;
   3237
   3238	update_vif_type_counter(adapter, priv->bss_mode, -1);
   3239
   3240	priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
   3241
   3242	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
   3243	    GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
   3244		kfree(priv->hist_data);
   3245
   3246	return 0;
   3247}
   3248EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
   3249
   3250static bool
   3251mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
   3252			     u8 max_byte_seq)
   3253{
   3254	int j, k, valid_byte_cnt = 0;
   3255	bool dont_care_byte = false;
   3256
   3257	for (j = 0; j < DIV_ROUND_UP(pat->pattern_len, 8); j++) {
   3258		for (k = 0; k < 8; k++) {
   3259			if (pat->mask[j] & 1 << k) {
   3260				memcpy(byte_seq + valid_byte_cnt,
   3261				       &pat->pattern[j * 8 + k], 1);
   3262				valid_byte_cnt++;
   3263				if (dont_care_byte)
   3264					return false;
   3265			} else {
   3266				if (valid_byte_cnt)
   3267					dont_care_byte = true;
   3268			}
   3269
   3270			/* wildcard bytes record as the offset
   3271			 * before the valid byte
   3272			 */
   3273			if (!valid_byte_cnt && !dont_care_byte)
   3274				pat->pkt_offset++;
   3275
   3276			if (valid_byte_cnt > max_byte_seq)
   3277				return false;
   3278		}
   3279	}
   3280
   3281	byte_seq[max_byte_seq] = valid_byte_cnt;
   3282
   3283	return true;
   3284}
   3285
   3286#ifdef CONFIG_PM
   3287static void mwifiex_set_auto_arp_mef_entry(struct mwifiex_private *priv,
   3288					   struct mwifiex_mef_entry *mef_entry)
   3289{
   3290	int i, filt_num = 0, num_ipv4 = 0;
   3291	struct in_device *in_dev;
   3292	struct in_ifaddr *ifa;
   3293	__be32 ips[MWIFIEX_MAX_SUPPORTED_IPADDR];
   3294	struct mwifiex_adapter *adapter = priv->adapter;
   3295
   3296	mef_entry->mode = MEF_MODE_HOST_SLEEP;
   3297	mef_entry->action = MEF_ACTION_AUTO_ARP;
   3298
   3299	/* Enable ARP offload feature */
   3300	memset(ips, 0, sizeof(ips));
   3301	for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
   3302		if (adapter->priv[i]->netdev) {
   3303			in_dev = __in_dev_get_rtnl(adapter->priv[i]->netdev);
   3304			if (!in_dev)
   3305				continue;
   3306			ifa = rtnl_dereference(in_dev->ifa_list);
   3307			if (!ifa || !ifa->ifa_local)
   3308				continue;
   3309			ips[i] = ifa->ifa_local;
   3310			num_ipv4++;
   3311		}
   3312	}
   3313
   3314	for (i = 0; i < num_ipv4; i++) {
   3315		if (!ips[i])
   3316			continue;
   3317		mef_entry->filter[filt_num].repeat = 1;
   3318		memcpy(mef_entry->filter[filt_num].byte_seq,
   3319		       (u8 *)&ips[i], sizeof(ips[i]));
   3320		mef_entry->filter[filt_num].
   3321			byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
   3322			sizeof(ips[i]);
   3323		mef_entry->filter[filt_num].offset = 46;
   3324		mef_entry->filter[filt_num].filt_type = TYPE_EQ;
   3325		if (filt_num) {
   3326			mef_entry->filter[filt_num].filt_action =
   3327				TYPE_OR;
   3328		}
   3329		filt_num++;
   3330	}
   3331
   3332	mef_entry->filter[filt_num].repeat = 1;
   3333	mef_entry->filter[filt_num].byte_seq[0] = 0x08;
   3334	mef_entry->filter[filt_num].byte_seq[1] = 0x06;
   3335	mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2;
   3336	mef_entry->filter[filt_num].offset = 20;
   3337	mef_entry->filter[filt_num].filt_type = TYPE_EQ;
   3338	mef_entry->filter[filt_num].filt_action = TYPE_AND;
   3339}
   3340
   3341static int mwifiex_set_wowlan_mef_entry(struct mwifiex_private *priv,
   3342					struct mwifiex_ds_mef_cfg *mef_cfg,
   3343					struct mwifiex_mef_entry *mef_entry,
   3344					struct cfg80211_wowlan *wowlan)
   3345{
   3346	int i, filt_num = 0, ret = 0;
   3347	bool first_pat = true;
   3348	u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
   3349	static const u8 ipv4_mc_mac[] = {0x33, 0x33};
   3350	static const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
   3351
   3352	mef_entry->mode = MEF_MODE_HOST_SLEEP;
   3353	mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST;
   3354
   3355	for (i = 0; i < wowlan->n_patterns; i++) {
   3356		memset(byte_seq, 0, sizeof(byte_seq));
   3357		if (!mwifiex_is_pattern_supported(&wowlan->patterns[i],
   3358					byte_seq,
   3359					MWIFIEX_MEF_MAX_BYTESEQ)) {
   3360			mwifiex_dbg(priv->adapter, ERROR,
   3361				    "Pattern not supported\n");
   3362			return -EOPNOTSUPP;
   3363		}
   3364
   3365		if (!wowlan->patterns[i].pkt_offset) {
   3366			if (!(byte_seq[0] & 0x01) &&
   3367			    (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 1)) {
   3368				mef_cfg->criteria |= MWIFIEX_CRITERIA_UNICAST;
   3369				continue;
   3370			} else if (is_broadcast_ether_addr(byte_seq)) {
   3371				mef_cfg->criteria |= MWIFIEX_CRITERIA_BROADCAST;
   3372				continue;
   3373			} else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) &&
   3374				    (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 2)) ||
   3375				   (!memcmp(byte_seq, ipv6_mc_mac, 3) &&
   3376				    (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 3))) {
   3377				mef_cfg->criteria |= MWIFIEX_CRITERIA_MULTICAST;
   3378				continue;
   3379			}
   3380		}
   3381		mef_entry->filter[filt_num].repeat = 1;
   3382		mef_entry->filter[filt_num].offset =
   3383			wowlan->patterns[i].pkt_offset;
   3384		memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq,
   3385				sizeof(byte_seq));
   3386		mef_entry->filter[filt_num].filt_type = TYPE_EQ;
   3387
   3388		if (first_pat) {
   3389			first_pat = false;
   3390			mwifiex_dbg(priv->adapter, INFO, "Wake on patterns\n");
   3391		} else {
   3392			mef_entry->filter[filt_num].filt_action = TYPE_AND;
   3393		}
   3394
   3395		filt_num++;
   3396	}
   3397
   3398	if (wowlan->magic_pkt) {
   3399		mef_cfg->criteria |= MWIFIEX_CRITERIA_UNICAST;
   3400		mef_entry->filter[filt_num].repeat = 16;
   3401		memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
   3402				ETH_ALEN);
   3403		mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
   3404			ETH_ALEN;
   3405		mef_entry->filter[filt_num].offset = 28;
   3406		mef_entry->filter[filt_num].filt_type = TYPE_EQ;
   3407		if (filt_num)
   3408			mef_entry->filter[filt_num].filt_action = TYPE_OR;
   3409
   3410		filt_num++;
   3411		mef_entry->filter[filt_num].repeat = 16;
   3412		memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
   3413				ETH_ALEN);
   3414		mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
   3415			ETH_ALEN;
   3416		mef_entry->filter[filt_num].offset = 56;
   3417		mef_entry->filter[filt_num].filt_type = TYPE_EQ;
   3418		mef_entry->filter[filt_num].filt_action = TYPE_OR;
   3419		mwifiex_dbg(priv->adapter, INFO, "Wake on magic packet\n");
   3420	}
   3421	return ret;
   3422}
   3423
   3424static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
   3425				  struct cfg80211_wowlan *wowlan)
   3426{
   3427	int ret = 0, num_entries = 1;
   3428	struct mwifiex_ds_mef_cfg mef_cfg;
   3429	struct mwifiex_mef_entry *mef_entry;
   3430
   3431	if (wowlan->n_patterns || wowlan->magic_pkt)
   3432		num_entries++;
   3433
   3434	mef_entry = kcalloc(num_entries, sizeof(*mef_entry), GFP_KERNEL);
   3435	if (!mef_entry)
   3436		return -ENOMEM;
   3437
   3438	memset(&mef_cfg, 0, sizeof(mef_cfg));
   3439	mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST |
   3440		MWIFIEX_CRITERIA_UNICAST;
   3441	mef_cfg.num_entries = num_entries;
   3442	mef_cfg.mef_entry = mef_entry;
   3443
   3444	mwifiex_set_auto_arp_mef_entry(priv, &mef_entry[0]);
   3445
   3446	if (wowlan->n_patterns || wowlan->magic_pkt) {
   3447		ret = mwifiex_set_wowlan_mef_entry(priv, &mef_cfg,
   3448						   &mef_entry[1], wowlan);
   3449		if (ret)
   3450			goto err;
   3451	}
   3452
   3453	if (!mef_cfg.criteria)
   3454		mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
   3455			MWIFIEX_CRITERIA_UNICAST |
   3456			MWIFIEX_CRITERIA_MULTICAST;
   3457
   3458	ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
   3459			HostCmd_ACT_GEN_SET, 0,
   3460			&mef_cfg, true);
   3461
   3462err:
   3463	kfree(mef_entry);
   3464	return ret;
   3465}
   3466
   3467static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
   3468				    struct cfg80211_wowlan *wowlan)
   3469{
   3470	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
   3471	struct mwifiex_ds_hs_cfg hs_cfg;
   3472	int i, ret = 0, retry_num = 10;
   3473	struct mwifiex_private *priv;
   3474	struct mwifiex_private *sta_priv =
   3475			mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
   3476
   3477	sta_priv->scan_aborting = true;
   3478	for (i = 0; i < adapter->priv_num; i++) {
   3479		priv = adapter->priv[i];
   3480		mwifiex_abort_cac(priv);
   3481	}
   3482
   3483	mwifiex_cancel_all_pending_cmd(adapter);
   3484
   3485	for (i = 0; i < adapter->priv_num; i++) {
   3486		priv = adapter->priv[i];
   3487		if (priv && priv->netdev)
   3488			netif_device_detach(priv->netdev);
   3489	}
   3490
   3491	for (i = 0; i < retry_num; i++) {
   3492		if (!mwifiex_wmm_lists_empty(adapter) ||
   3493		    !mwifiex_bypass_txlist_empty(adapter) ||
   3494		    !skb_queue_empty(&adapter->tx_data_q))
   3495			usleep_range(10000, 15000);
   3496		else
   3497			break;
   3498	}
   3499
   3500	if (!wowlan) {
   3501		mwifiex_dbg(adapter, INFO,
   3502			    "None of the WOWLAN triggers enabled\n");
   3503		ret = 0;
   3504		goto done;
   3505	}
   3506
   3507	if (!sta_priv->media_connected && !wowlan->nd_config) {
   3508		mwifiex_dbg(adapter, ERROR,
   3509			    "Can not configure WOWLAN in disconnected state\n");
   3510		ret = 0;
   3511		goto done;
   3512	}
   3513
   3514	ret = mwifiex_set_mef_filter(sta_priv, wowlan);
   3515	if (ret) {
   3516		mwifiex_dbg(adapter, ERROR, "Failed to set MEF filter\n");
   3517		goto done;
   3518	}
   3519
   3520	memset(&hs_cfg, 0, sizeof(hs_cfg));
   3521	hs_cfg.conditions = le32_to_cpu(adapter->hs_cfg.conditions);
   3522
   3523	if (wowlan->nd_config) {
   3524		mwifiex_dbg(adapter, INFO, "Wake on net detect\n");
   3525		hs_cfg.conditions |= HS_CFG_COND_MAC_EVENT;
   3526		mwifiex_cfg80211_sched_scan_start(wiphy, sta_priv->netdev,
   3527						  wowlan->nd_config);
   3528	}
   3529
   3530	if (wowlan->disconnect) {
   3531		hs_cfg.conditions |= HS_CFG_COND_MAC_EVENT;
   3532		mwifiex_dbg(sta_priv->adapter, INFO, "Wake on device disconnect\n");
   3533	}
   3534
   3535	hs_cfg.is_invoke_hostcmd = false;
   3536	hs_cfg.gpio = adapter->hs_cfg.gpio;
   3537	hs_cfg.gap = adapter->hs_cfg.gap;
   3538	ret = mwifiex_set_hs_params(sta_priv, HostCmd_ACT_GEN_SET,
   3539				    MWIFIEX_SYNC_CMD, &hs_cfg);
   3540	if (ret)
   3541		mwifiex_dbg(adapter, ERROR, "Failed to set HS params\n");
   3542
   3543done:
   3544	sta_priv->scan_aborting = false;
   3545	return ret;
   3546}
   3547
   3548static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
   3549{
   3550	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
   3551	struct mwifiex_private *priv;
   3552	struct mwifiex_ds_wakeup_reason wakeup_reason;
   3553	struct cfg80211_wowlan_wakeup wakeup_report;
   3554	int i;
   3555	bool report_wakeup_reason = true;
   3556
   3557	for (i = 0; i < adapter->priv_num; i++) {
   3558		priv = adapter->priv[i];
   3559		if (priv && priv->netdev)
   3560			netif_device_attach(priv->netdev);
   3561	}
   3562
   3563	if (!wiphy->wowlan_config)
   3564		goto done;
   3565
   3566	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
   3567	mwifiex_get_wakeup_reason(priv, HostCmd_ACT_GEN_GET, MWIFIEX_SYNC_CMD,
   3568				  &wakeup_reason);
   3569	memset(&wakeup_report, 0, sizeof(struct cfg80211_wowlan_wakeup));
   3570
   3571	wakeup_report.pattern_idx = -1;
   3572
   3573	switch (wakeup_reason.hs_wakeup_reason) {
   3574	case NO_HSWAKEUP_REASON:
   3575		break;
   3576	case BCAST_DATA_MATCHED:
   3577		break;
   3578	case MCAST_DATA_MATCHED:
   3579		break;
   3580	case UCAST_DATA_MATCHED:
   3581		break;
   3582	case MASKTABLE_EVENT_MATCHED:
   3583		break;
   3584	case NON_MASKABLE_EVENT_MATCHED:
   3585		if (wiphy->wowlan_config->disconnect)
   3586			wakeup_report.disconnect = true;
   3587		if (wiphy->wowlan_config->nd_config)
   3588			wakeup_report.net_detect = adapter->nd_info;
   3589		break;
   3590	case NON_MASKABLE_CONDITION_MATCHED:
   3591		break;
   3592	case MAGIC_PATTERN_MATCHED:
   3593		if (wiphy->wowlan_config->magic_pkt)
   3594			wakeup_report.magic_pkt = true;
   3595		if (wiphy->wowlan_config->n_patterns)
   3596			wakeup_report.pattern_idx = 1;
   3597		break;
   3598	case GTK_REKEY_FAILURE:
   3599		if (wiphy->wowlan_config->gtk_rekey_failure)
   3600			wakeup_report.gtk_rekey_failure = true;
   3601		break;
   3602	default:
   3603		report_wakeup_reason = false;
   3604		break;
   3605	}
   3606
   3607	if (report_wakeup_reason)
   3608		cfg80211_report_wowlan_wakeup(&priv->wdev, &wakeup_report,
   3609					      GFP_KERNEL);
   3610
   3611done:
   3612	if (adapter->nd_info) {
   3613		for (i = 0 ; i < adapter->nd_info->n_matches ; i++)
   3614			kfree(adapter->nd_info->matches[i]);
   3615		kfree(adapter->nd_info);
   3616		adapter->nd_info = NULL;
   3617	}
   3618
   3619	return 0;
   3620}
   3621
   3622static void mwifiex_cfg80211_set_wakeup(struct wiphy *wiphy,
   3623				       bool enabled)
   3624{
   3625	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
   3626
   3627	device_set_wakeup_enable(adapter->dev, enabled);
   3628}
   3629
   3630static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
   3631				  struct cfg80211_gtk_rekey_data *data)
   3632{
   3633	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   3634
   3635	if (!ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
   3636		return -EOPNOTSUPP;
   3637
   3638	return mwifiex_send_cmd(priv, HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG,
   3639				HostCmd_ACT_GEN_SET, 0, data, true);
   3640}
   3641
   3642#endif
   3643
   3644static int mwifiex_get_coalesce_pkt_type(u8 *byte_seq)
   3645{
   3646	static const u8 ipv4_mc_mac[] = {0x33, 0x33};
   3647	static const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
   3648	static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff};
   3649
   3650	if ((byte_seq[0] & 0x01) &&
   3651	    (byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 1))
   3652		return PACKET_TYPE_UNICAST;
   3653	else if (!memcmp(byte_seq, bc_mac, 4))
   3654		return PACKET_TYPE_BROADCAST;
   3655	else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) &&
   3656		  byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 2) ||
   3657		 (!memcmp(byte_seq, ipv6_mc_mac, 3) &&
   3658		  byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 3))
   3659		return PACKET_TYPE_MULTICAST;
   3660
   3661	return 0;
   3662}
   3663
   3664static int
   3665mwifiex_fill_coalesce_rule_info(struct mwifiex_private *priv,
   3666				struct cfg80211_coalesce_rules *crule,
   3667				struct mwifiex_coalesce_rule *mrule)
   3668{
   3669	u8 byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ + 1];
   3670	struct filt_field_param *param;
   3671	int i;
   3672
   3673	mrule->max_coalescing_delay = crule->delay;
   3674
   3675	param = mrule->params;
   3676
   3677	for (i = 0; i < crule->n_patterns; i++) {
   3678		memset(byte_seq, 0, sizeof(byte_seq));
   3679		if (!mwifiex_is_pattern_supported(&crule->patterns[i],
   3680						  byte_seq,
   3681						MWIFIEX_COALESCE_MAX_BYTESEQ)) {
   3682			mwifiex_dbg(priv->adapter, ERROR,
   3683				    "Pattern not supported\n");
   3684			return -EOPNOTSUPP;
   3685		}
   3686
   3687		if (!crule->patterns[i].pkt_offset) {
   3688			u8 pkt_type;
   3689
   3690			pkt_type = mwifiex_get_coalesce_pkt_type(byte_seq);
   3691			if (pkt_type && mrule->pkt_type) {
   3692				mwifiex_dbg(priv->adapter, ERROR,
   3693					    "Multiple packet types not allowed\n");
   3694				return -EOPNOTSUPP;
   3695			} else if (pkt_type) {
   3696				mrule->pkt_type = pkt_type;
   3697				continue;
   3698			}
   3699		}
   3700
   3701		if (crule->condition == NL80211_COALESCE_CONDITION_MATCH)
   3702			param->operation = RECV_FILTER_MATCH_TYPE_EQ;
   3703		else
   3704			param->operation = RECV_FILTER_MATCH_TYPE_NE;
   3705
   3706		param->operand_len = byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ];
   3707		memcpy(param->operand_byte_stream, byte_seq,
   3708		       param->operand_len);
   3709		param->offset = crule->patterns[i].pkt_offset;
   3710		param++;
   3711
   3712		mrule->num_of_fields++;
   3713	}
   3714
   3715	if (!mrule->pkt_type) {
   3716		mwifiex_dbg(priv->adapter, ERROR,
   3717			    "Packet type can not be determined\n");
   3718		return -EOPNOTSUPP;
   3719	}
   3720
   3721	return 0;
   3722}
   3723
   3724static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
   3725					 struct cfg80211_coalesce *coalesce)
   3726{
   3727	struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
   3728	int i, ret;
   3729	struct mwifiex_ds_coalesce_cfg coalesce_cfg;
   3730	struct mwifiex_private *priv =
   3731			mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
   3732
   3733	memset(&coalesce_cfg, 0, sizeof(coalesce_cfg));
   3734	if (!coalesce) {
   3735		mwifiex_dbg(adapter, WARN,
   3736			    "Disable coalesce and reset all previous rules\n");
   3737		return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
   3738					HostCmd_ACT_GEN_SET, 0,
   3739					&coalesce_cfg, true);
   3740	}
   3741
   3742	coalesce_cfg.num_of_rules = coalesce->n_rules;
   3743	for (i = 0; i < coalesce->n_rules; i++) {
   3744		ret = mwifiex_fill_coalesce_rule_info(priv, &coalesce->rules[i],
   3745						      &coalesce_cfg.rule[i]);
   3746		if (ret) {
   3747			mwifiex_dbg(adapter, ERROR,
   3748				    "Recheck the patterns provided for rule %d\n",
   3749				i + 1);
   3750			return ret;
   3751		}
   3752	}
   3753
   3754	return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
   3755				HostCmd_ACT_GEN_SET, 0, &coalesce_cfg, true);
   3756}
   3757
   3758/* cfg80211 ops handler for tdls_mgmt.
   3759 * Function prepares TDLS action frame packets and forwards them to FW
   3760 */
   3761static int
   3762mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
   3763			   const u8 *peer, u8 action_code, u8 dialog_token,
   3764			   u16 status_code, u32 peer_capability,
   3765			   bool initiator, const u8 *extra_ies,
   3766			   size_t extra_ies_len)
   3767{
   3768	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   3769	int ret;
   3770
   3771	if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
   3772		return -EOPNOTSUPP;
   3773
   3774	/* make sure we are in station mode and connected */
   3775	if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
   3776		return -EOPNOTSUPP;
   3777
   3778	switch (action_code) {
   3779	case WLAN_TDLS_SETUP_REQUEST:
   3780		mwifiex_dbg(priv->adapter, MSG,
   3781			    "Send TDLS Setup Request to %pM status_code=%d\n",
   3782			    peer, status_code);
   3783		mwifiex_add_auto_tdls_peer(priv, peer);
   3784		ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
   3785						   dialog_token, status_code,
   3786						   extra_ies, extra_ies_len);
   3787		break;
   3788	case WLAN_TDLS_SETUP_RESPONSE:
   3789		mwifiex_add_auto_tdls_peer(priv, peer);
   3790		mwifiex_dbg(priv->adapter, MSG,
   3791			    "Send TDLS Setup Response to %pM status_code=%d\n",
   3792			    peer, status_code);
   3793		ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
   3794						   dialog_token, status_code,
   3795						   extra_ies, extra_ies_len);
   3796		break;
   3797	case WLAN_TDLS_SETUP_CONFIRM:
   3798		mwifiex_dbg(priv->adapter, MSG,
   3799			    "Send TDLS Confirm to %pM status_code=%d\n", peer,
   3800			    status_code);
   3801		ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
   3802						   dialog_token, status_code,
   3803						   extra_ies, extra_ies_len);
   3804		break;
   3805	case WLAN_TDLS_TEARDOWN:
   3806		mwifiex_dbg(priv->adapter, MSG,
   3807			    "Send TDLS Tear down to %pM\n", peer);
   3808		ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
   3809						   dialog_token, status_code,
   3810						   extra_ies, extra_ies_len);
   3811		break;
   3812	case WLAN_TDLS_DISCOVERY_REQUEST:
   3813		mwifiex_dbg(priv->adapter, MSG,
   3814			    "Send TDLS Discovery Request to %pM\n", peer);
   3815		ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
   3816						   dialog_token, status_code,
   3817						   extra_ies, extra_ies_len);
   3818		break;
   3819	case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
   3820		mwifiex_dbg(priv->adapter, MSG,
   3821			    "Send TDLS Discovery Response to %pM\n", peer);
   3822		ret = mwifiex_send_tdls_action_frame(priv, peer, action_code,
   3823						   dialog_token, status_code,
   3824						   extra_ies, extra_ies_len);
   3825		break;
   3826	default:
   3827		mwifiex_dbg(priv->adapter, ERROR,
   3828			    "Unknown TDLS mgmt/action frame %pM\n", peer);
   3829		ret = -EINVAL;
   3830		break;
   3831	}
   3832
   3833	return ret;
   3834}
   3835
   3836static int
   3837mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
   3838			   const u8 *peer, enum nl80211_tdls_operation action)
   3839{
   3840	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   3841
   3842	if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
   3843	    !(wiphy->flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
   3844		return -EOPNOTSUPP;
   3845
   3846	/* make sure we are in station mode and connected */
   3847	if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
   3848		return -EOPNOTSUPP;
   3849
   3850	mwifiex_dbg(priv->adapter, MSG,
   3851		    "TDLS peer=%pM, oper=%d\n", peer, action);
   3852
   3853	switch (action) {
   3854	case NL80211_TDLS_ENABLE_LINK:
   3855		action = MWIFIEX_TDLS_ENABLE_LINK;
   3856		break;
   3857	case NL80211_TDLS_DISABLE_LINK:
   3858		action = MWIFIEX_TDLS_DISABLE_LINK;
   3859		break;
   3860	case NL80211_TDLS_TEARDOWN:
   3861		/* shouldn't happen!*/
   3862		mwifiex_dbg(priv->adapter, ERROR,
   3863			    "tdls_oper: teardown from driver not supported\n");
   3864		return -EINVAL;
   3865	case NL80211_TDLS_SETUP:
   3866		/* shouldn't happen!*/
   3867		mwifiex_dbg(priv->adapter, ERROR,
   3868			    "tdls_oper: setup from driver not supported\n");
   3869		return -EINVAL;
   3870	case NL80211_TDLS_DISCOVERY_REQ:
   3871		/* shouldn't happen!*/
   3872		mwifiex_dbg(priv->adapter, ERROR,
   3873			    "tdls_oper: discovery from driver not supported\n");
   3874		return -EINVAL;
   3875	default:
   3876		mwifiex_dbg(priv->adapter, ERROR,
   3877			    "tdls_oper: operation not supported\n");
   3878		return -EOPNOTSUPP;
   3879	}
   3880
   3881	return mwifiex_tdls_oper(priv, peer, action);
   3882}
   3883
   3884static int
   3885mwifiex_cfg80211_tdls_chan_switch(struct wiphy *wiphy, struct net_device *dev,
   3886				  const u8 *addr, u8 oper_class,
   3887				  struct cfg80211_chan_def *chandef)
   3888{
   3889	struct mwifiex_sta_node *sta_ptr;
   3890	u16 chan;
   3891	u8 second_chan_offset, band;
   3892	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   3893
   3894	spin_lock_bh(&priv->sta_list_spinlock);
   3895	sta_ptr = mwifiex_get_sta_entry(priv, addr);
   3896	if (!sta_ptr) {
   3897		spin_unlock_bh(&priv->sta_list_spinlock);
   3898		wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n",
   3899			  __func__, addr);
   3900		return -ENOENT;
   3901	}
   3902
   3903	if (!(sta_ptr->tdls_cap.extcap.ext_capab[3] &
   3904	      WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH)) {
   3905		spin_unlock_bh(&priv->sta_list_spinlock);
   3906		wiphy_err(wiphy, "%pM do not support tdls cs\n", addr);
   3907		return -ENOENT;
   3908	}
   3909
   3910	if (sta_ptr->tdls_status == TDLS_CHAN_SWITCHING ||
   3911	    sta_ptr->tdls_status == TDLS_IN_OFF_CHAN) {
   3912		spin_unlock_bh(&priv->sta_list_spinlock);
   3913		wiphy_err(wiphy, "channel switch is running, abort request\n");
   3914		return -EALREADY;
   3915	}
   3916	spin_unlock_bh(&priv->sta_list_spinlock);
   3917
   3918	chan = chandef->chan->hw_value;
   3919	second_chan_offset = mwifiex_get_sec_chan_offset(chan);
   3920	band = chandef->chan->band;
   3921	mwifiex_start_tdls_cs(priv, addr, chan, second_chan_offset, band);
   3922
   3923	return 0;
   3924}
   3925
   3926static void
   3927mwifiex_cfg80211_tdls_cancel_chan_switch(struct wiphy *wiphy,
   3928					 struct net_device *dev,
   3929					 const u8 *addr)
   3930{
   3931	struct mwifiex_sta_node *sta_ptr;
   3932	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   3933
   3934	spin_lock_bh(&priv->sta_list_spinlock);
   3935	sta_ptr = mwifiex_get_sta_entry(priv, addr);
   3936	if (!sta_ptr) {
   3937		spin_unlock_bh(&priv->sta_list_spinlock);
   3938		wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n",
   3939			  __func__, addr);
   3940	} else if (!(sta_ptr->tdls_status == TDLS_CHAN_SWITCHING ||
   3941		     sta_ptr->tdls_status == TDLS_IN_BASE_CHAN ||
   3942		     sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)) {
   3943		spin_unlock_bh(&priv->sta_list_spinlock);
   3944		wiphy_err(wiphy, "tdls chan switch not initialize by %pM\n",
   3945			  addr);
   3946	} else {
   3947		spin_unlock_bh(&priv->sta_list_spinlock);
   3948		mwifiex_stop_tdls_cs(priv, addr);
   3949	}
   3950}
   3951
   3952static int
   3953mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
   3954			     const u8 *mac, struct station_parameters *params)
   3955{
   3956	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   3957
   3958	if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
   3959		return -EOPNOTSUPP;
   3960
   3961	/* make sure we are in station mode and connected */
   3962	if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
   3963		return -EOPNOTSUPP;
   3964
   3965	return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK);
   3966}
   3967
   3968static int
   3969mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
   3970				struct cfg80211_csa_settings *params)
   3971{
   3972	struct ieee_types_header *chsw_ie;
   3973	struct ieee80211_channel_sw_ie *channel_sw;
   3974	int chsw_msec;
   3975	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   3976
   3977	if (priv->adapter->scan_processing) {
   3978		mwifiex_dbg(priv->adapter, ERROR,
   3979			    "radar detection: scan in process...\n");
   3980		return -EBUSY;
   3981	}
   3982
   3983	if (priv->wdev.cac_started)
   3984		return -EBUSY;
   3985
   3986	if (cfg80211_chandef_identical(&params->chandef,
   3987				       &priv->dfs_chandef))
   3988		return -EINVAL;
   3989
   3990	chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH,
   3991					   params->beacon_csa.tail,
   3992					   params->beacon_csa.tail_len);
   3993	if (!chsw_ie) {
   3994		mwifiex_dbg(priv->adapter, ERROR,
   3995			    "Could not parse channel switch announcement IE\n");
   3996		return -EINVAL;
   3997	}
   3998
   3999	channel_sw = (void *)(chsw_ie + 1);
   4000	if (channel_sw->mode) {
   4001		if (netif_carrier_ok(priv->netdev))
   4002			netif_carrier_off(priv->netdev);
   4003		mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
   4004	}
   4005
   4006	if (mwifiex_del_mgmt_ies(priv))
   4007		mwifiex_dbg(priv->adapter, ERROR,
   4008			    "Failed to delete mgmt IEs!\n");
   4009
   4010	if (mwifiex_set_mgmt_ies(priv, &params->beacon_csa)) {
   4011		mwifiex_dbg(priv->adapter, ERROR,
   4012			    "%s: setting mgmt ies failed\n", __func__);
   4013		return -EFAULT;
   4014	}
   4015
   4016	memcpy(&priv->dfs_chandef, &params->chandef, sizeof(priv->dfs_chandef));
   4017	memcpy(&priv->beacon_after, &params->beacon_after,
   4018	       sizeof(priv->beacon_after));
   4019
   4020	chsw_msec = max(channel_sw->count * priv->bss_cfg.beacon_period, 100);
   4021	queue_delayed_work(priv->dfs_chan_sw_workqueue, &priv->dfs_chan_sw_work,
   4022			   msecs_to_jiffies(chsw_msec));
   4023	return 0;
   4024}
   4025
   4026static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
   4027					struct wireless_dev *wdev,
   4028					struct cfg80211_chan_def *chandef)
   4029{
   4030	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
   4031	struct mwifiex_bssdescriptor *curr_bss;
   4032	struct ieee80211_channel *chan;
   4033	enum nl80211_channel_type chan_type;
   4034	enum nl80211_band band;
   4035	int freq;
   4036	int ret = -ENODATA;
   4037
   4038	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
   4039	    cfg80211_chandef_valid(&priv->bss_chandef)) {
   4040		*chandef = priv->bss_chandef;
   4041		ret = 0;
   4042	} else if (priv->media_connected) {
   4043		curr_bss = &priv->curr_bss_params.bss_descriptor;
   4044		band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
   4045		freq = ieee80211_channel_to_frequency(curr_bss->channel, band);
   4046		chan = ieee80211_get_channel(wiphy, freq);
   4047
   4048		if (priv->ht_param_present) {
   4049			chan_type = mwifiex_get_chan_type(priv);
   4050			cfg80211_chandef_create(chandef, chan, chan_type);
   4051		} else {
   4052			cfg80211_chandef_create(chandef, chan,
   4053						NL80211_CHAN_NO_HT);
   4054		}
   4055		ret = 0;
   4056	}
   4057
   4058	return ret;
   4059}
   4060
   4061#ifdef CONFIG_NL80211_TESTMODE
   4062
   4063enum mwifiex_tm_attr {
   4064	__MWIFIEX_TM_ATTR_INVALID	= 0,
   4065	MWIFIEX_TM_ATTR_CMD		= 1,
   4066	MWIFIEX_TM_ATTR_DATA		= 2,
   4067
   4068	/* keep last */
   4069	__MWIFIEX_TM_ATTR_AFTER_LAST,
   4070	MWIFIEX_TM_ATTR_MAX		= __MWIFIEX_TM_ATTR_AFTER_LAST - 1,
   4071};
   4072
   4073static const struct nla_policy mwifiex_tm_policy[MWIFIEX_TM_ATTR_MAX + 1] = {
   4074	[MWIFIEX_TM_ATTR_CMD]		= { .type = NLA_U32 },
   4075	[MWIFIEX_TM_ATTR_DATA]		= { .type = NLA_BINARY,
   4076					    .len = MWIFIEX_SIZE_OF_CMD_BUFFER },
   4077};
   4078
   4079enum mwifiex_tm_command {
   4080	MWIFIEX_TM_CMD_HOSTCMD	= 0,
   4081};
   4082
   4083static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
   4084			  void *data, int len)
   4085{
   4086	struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
   4087	struct mwifiex_ds_misc_cmd *hostcmd;
   4088	struct nlattr *tb[MWIFIEX_TM_ATTR_MAX + 1];
   4089	struct sk_buff *skb;
   4090	int err;
   4091
   4092	if (!priv)
   4093		return -EINVAL;
   4094
   4095	err = nla_parse_deprecated(tb, MWIFIEX_TM_ATTR_MAX, data, len,
   4096				   mwifiex_tm_policy, NULL);
   4097	if (err)
   4098		return err;
   4099
   4100	if (!tb[MWIFIEX_TM_ATTR_CMD])
   4101		return -EINVAL;
   4102
   4103	switch (nla_get_u32(tb[MWIFIEX_TM_ATTR_CMD])) {
   4104	case MWIFIEX_TM_CMD_HOSTCMD:
   4105		if (!tb[MWIFIEX_TM_ATTR_DATA])
   4106			return -EINVAL;
   4107
   4108		hostcmd = kzalloc(sizeof(*hostcmd), GFP_KERNEL);
   4109		if (!hostcmd)
   4110			return -ENOMEM;
   4111
   4112		hostcmd->len = nla_len(tb[MWIFIEX_TM_ATTR_DATA]);
   4113		memcpy(hostcmd->cmd, nla_data(tb[MWIFIEX_TM_ATTR_DATA]),
   4114		       hostcmd->len);
   4115
   4116		if (mwifiex_send_cmd(priv, 0, 0, 0, hostcmd, true)) {
   4117			dev_err(priv->adapter->dev, "Failed to process hostcmd\n");
   4118			kfree(hostcmd);
   4119			return -EFAULT;
   4120		}
   4121
   4122		/* process hostcmd response*/
   4123		skb = cfg80211_testmode_alloc_reply_skb(wiphy, hostcmd->len);
   4124		if (!skb) {
   4125			kfree(hostcmd);
   4126			return -ENOMEM;
   4127		}
   4128		err = nla_put(skb, MWIFIEX_TM_ATTR_DATA,
   4129			      hostcmd->len, hostcmd->cmd);
   4130		if (err) {
   4131			kfree(hostcmd);
   4132			kfree_skb(skb);
   4133			return -EMSGSIZE;
   4134		}
   4135
   4136		err = cfg80211_testmode_reply(skb);
   4137		kfree(hostcmd);
   4138		return err;
   4139	default:
   4140		return -EOPNOTSUPP;
   4141	}
   4142}
   4143#endif
   4144
   4145static int
   4146mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
   4147				       struct net_device *dev,
   4148				       struct cfg80211_chan_def *chandef,
   4149				       u32 cac_time_ms)
   4150{
   4151	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   4152	struct mwifiex_radar_params radar_params;
   4153
   4154	if (priv->adapter->scan_processing) {
   4155		mwifiex_dbg(priv->adapter, ERROR,
   4156			    "radar detection: scan already in process...\n");
   4157		return -EBUSY;
   4158	}
   4159
   4160	if (!mwifiex_is_11h_active(priv)) {
   4161		mwifiex_dbg(priv->adapter, INFO,
   4162			    "Enable 11h extensions in FW\n");
   4163		if (mwifiex_11h_activate(priv, true)) {
   4164			mwifiex_dbg(priv->adapter, ERROR,
   4165				    "Failed to activate 11h extensions!!");
   4166			return -1;
   4167		}
   4168		priv->state_11h.is_11h_active = true;
   4169	}
   4170
   4171	memset(&radar_params, 0, sizeof(struct mwifiex_radar_params));
   4172	radar_params.chandef = chandef;
   4173	radar_params.cac_time_ms = cac_time_ms;
   4174
   4175	memcpy(&priv->dfs_chandef, chandef, sizeof(priv->dfs_chandef));
   4176
   4177	if (mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST,
   4178			     HostCmd_ACT_GEN_SET, 0, &radar_params, true))
   4179		return -1;
   4180
   4181	queue_delayed_work(priv->dfs_cac_workqueue, &priv->dfs_cac_work,
   4182			   msecs_to_jiffies(cac_time_ms));
   4183	return 0;
   4184}
   4185
   4186static int
   4187mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
   4188				const u8 *mac,
   4189				struct station_parameters *params)
   4190{
   4191	int ret;
   4192	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
   4193
   4194	/* we support change_station handler only for TDLS peers*/
   4195	if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
   4196		return -EOPNOTSUPP;
   4197
   4198	/* make sure we are in station mode and connected */
   4199	if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
   4200		return -EOPNOTSUPP;
   4201
   4202	priv->sta_params = params;
   4203
   4204	ret = mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CONFIG_LINK);
   4205	priv->sta_params = NULL;
   4206
   4207	return ret;
   4208}
   4209
   4210/* station cfg80211 operations */
   4211static struct cfg80211_ops mwifiex_cfg80211_ops = {
   4212	.add_virtual_intf = mwifiex_add_virtual_intf,
   4213	.del_virtual_intf = mwifiex_del_virtual_intf,
   4214	.change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
   4215	.scan = mwifiex_cfg80211_scan,
   4216	.connect = mwifiex_cfg80211_connect,
   4217	.disconnect = mwifiex_cfg80211_disconnect,
   4218	.get_station = mwifiex_cfg80211_get_station,
   4219	.dump_station = mwifiex_cfg80211_dump_station,
   4220	.dump_survey = mwifiex_cfg80211_dump_survey,
   4221	.set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
   4222	.join_ibss = mwifiex_cfg80211_join_ibss,
   4223	.leave_ibss = mwifiex_cfg80211_leave_ibss,
   4224	.add_key = mwifiex_cfg80211_add_key,
   4225	.del_key = mwifiex_cfg80211_del_key,
   4226	.set_default_mgmt_key = mwifiex_cfg80211_set_default_mgmt_key,
   4227	.mgmt_tx = mwifiex_cfg80211_mgmt_tx,
   4228	.update_mgmt_frame_registrations =
   4229		mwifiex_cfg80211_update_mgmt_frame_registrations,
   4230	.remain_on_channel = mwifiex_cfg80211_remain_on_channel,
   4231	.cancel_remain_on_channel = mwifiex_cfg80211_cancel_remain_on_channel,
   4232	.set_default_key = mwifiex_cfg80211_set_default_key,
   4233	.set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
   4234	.set_tx_power = mwifiex_cfg80211_set_tx_power,
   4235	.get_tx_power = mwifiex_cfg80211_get_tx_power,
   4236	.set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
   4237	.start_ap = mwifiex_cfg80211_start_ap,
   4238	.stop_ap = mwifiex_cfg80211_stop_ap,
   4239	.change_beacon = mwifiex_cfg80211_change_beacon,
   4240	.set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
   4241	.set_antenna = mwifiex_cfg80211_set_antenna,
   4242	.get_antenna = mwifiex_cfg80211_get_antenna,
   4243	.del_station = mwifiex_cfg80211_del_station,
   4244	.sched_scan_start = mwifiex_cfg80211_sched_scan_start,
   4245	.sched_scan_stop = mwifiex_cfg80211_sched_scan_stop,
   4246#ifdef CONFIG_PM
   4247	.suspend = mwifiex_cfg80211_suspend,
   4248	.resume = mwifiex_cfg80211_resume,
   4249	.set_wakeup = mwifiex_cfg80211_set_wakeup,
   4250	.set_rekey_data = mwifiex_set_rekey_data,
   4251#endif
   4252	.set_coalesce = mwifiex_cfg80211_set_coalesce,
   4253	.tdls_mgmt = mwifiex_cfg80211_tdls_mgmt,
   4254	.tdls_oper = mwifiex_cfg80211_tdls_oper,
   4255	.tdls_channel_switch = mwifiex_cfg80211_tdls_chan_switch,
   4256	.tdls_cancel_channel_switch = mwifiex_cfg80211_tdls_cancel_chan_switch,
   4257	.add_station = mwifiex_cfg80211_add_station,
   4258	.change_station = mwifiex_cfg80211_change_station,
   4259	CFG80211_TESTMODE_CMD(mwifiex_tm_cmd)
   4260	.get_channel = mwifiex_cfg80211_get_channel,
   4261	.start_radar_detection = mwifiex_cfg80211_start_radar_detection,
   4262	.channel_switch = mwifiex_cfg80211_channel_switch,
   4263};
   4264
   4265#ifdef CONFIG_PM
   4266static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
   4267	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
   4268		WIPHY_WOWLAN_NET_DETECT | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
   4269		WIPHY_WOWLAN_GTK_REKEY_FAILURE,
   4270	.n_patterns = MWIFIEX_MEF_MAX_FILTERS,
   4271	.pattern_min_len = 1,
   4272	.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
   4273	.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
   4274	.max_nd_match_sets = MWIFIEX_MAX_ND_MATCH_SETS,
   4275};
   4276
   4277static const struct wiphy_wowlan_support mwifiex_wowlan_support_no_gtk = {
   4278	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
   4279		 WIPHY_WOWLAN_NET_DETECT,
   4280	.n_patterns = MWIFIEX_MEF_MAX_FILTERS,
   4281	.pattern_min_len = 1,
   4282	.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
   4283	.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
   4284	.max_nd_match_sets = MWIFIEX_MAX_ND_MATCH_SETS,
   4285};
   4286#endif
   4287
   4288static bool mwifiex_is_valid_alpha2(const char *alpha2)
   4289{
   4290	if (!alpha2 || strlen(alpha2) != 2)
   4291		return false;
   4292
   4293	if (isalpha(alpha2[0]) && isalpha(alpha2[1]))
   4294		return true;
   4295
   4296	return false;
   4297}
   4298
   4299static const struct wiphy_coalesce_support mwifiex_coalesce_support = {
   4300	.n_rules = MWIFIEX_COALESCE_MAX_RULES,
   4301	.max_delay = MWIFIEX_MAX_COALESCING_DELAY,
   4302	.n_patterns = MWIFIEX_COALESCE_MAX_FILTERS,
   4303	.pattern_min_len = 1,
   4304	.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
   4305	.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
   4306};
   4307
   4308int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter)
   4309{
   4310	u32 n_channels_bg, n_channels_a = 0;
   4311
   4312	n_channels_bg = mwifiex_band_2ghz.n_channels;
   4313
   4314	if (adapter->config_bands & BAND_A)
   4315		n_channels_a = mwifiex_band_5ghz.n_channels;
   4316
   4317	/* allocate twice the number total channels, since the driver issues an
   4318	 * additional active scan request for hidden SSIDs on passive channels.
   4319	 */
   4320	adapter->num_in_chan_stats = 2 * (n_channels_bg + n_channels_a);
   4321	adapter->chan_stats = vmalloc(array_size(sizeof(*adapter->chan_stats),
   4322						 adapter->num_in_chan_stats));
   4323
   4324	if (!adapter->chan_stats)
   4325		return -ENOMEM;
   4326
   4327	return 0;
   4328}
   4329
   4330/*
   4331 * This function registers the device with CFG802.11 subsystem.
   4332 *
   4333 * The function creates the wireless device/wiphy, populates it with
   4334 * default parameters and handler function pointers, and finally
   4335 * registers the device.
   4336 */
   4337
   4338int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
   4339{
   4340	int ret;
   4341	void *wdev_priv;
   4342	struct wiphy *wiphy;
   4343	struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
   4344	u8 *country_code;
   4345	u32 thr, retry;
   4346
   4347	/* create a new wiphy for use with cfg80211 */
   4348	wiphy = wiphy_new(&mwifiex_cfg80211_ops,
   4349			  sizeof(struct mwifiex_adapter *));
   4350	if (!wiphy) {
   4351		mwifiex_dbg(adapter, ERROR,
   4352			    "%s: creating new wiphy\n", __func__);
   4353		return -ENOMEM;
   4354	}
   4355	wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
   4356	wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
   4357	wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
   4358	wiphy->max_remain_on_channel_duration = 5000;
   4359	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
   4360				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
   4361				 BIT(NL80211_IFTYPE_P2P_GO) |
   4362				 BIT(NL80211_IFTYPE_AP);
   4363
   4364	if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info))
   4365		wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
   4366
   4367	wiphy->bands[NL80211_BAND_2GHZ] = &mwifiex_band_2ghz;
   4368	if (adapter->config_bands & BAND_A)
   4369		wiphy->bands[NL80211_BAND_5GHZ] = &mwifiex_band_5ghz;
   4370	else
   4371		wiphy->bands[NL80211_BAND_5GHZ] = NULL;
   4372
   4373	if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info))
   4374		wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_drcs;
   4375	else if (adapter->is_hw_11ac_capable)
   4376		wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_vht;
   4377	else
   4378		wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta;
   4379	wiphy->n_iface_combinations = 1;
   4380
   4381	if (adapter->max_sta_conn > adapter->max_p2p_conn)
   4382		wiphy->max_ap_assoc_sta = adapter->max_sta_conn;
   4383	else
   4384		wiphy->max_ap_assoc_sta = adapter->max_p2p_conn;
   4385
   4386	/* Initialize cipher suits */
   4387	wiphy->cipher_suites = mwifiex_cipher_suites;
   4388	wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
   4389
   4390	if (adapter->regd) {
   4391		wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
   4392					   REGULATORY_DISABLE_BEACON_HINTS |
   4393					   REGULATORY_COUNTRY_IE_IGNORE;
   4394		wiphy_apply_custom_regulatory(wiphy, adapter->regd);
   4395	}
   4396
   4397	ether_addr_copy(wiphy->perm_addr, adapter->perm_addr);
   4398	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
   4399	wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
   4400			WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
   4401			WIPHY_FLAG_AP_UAPSD |
   4402			WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
   4403			WIPHY_FLAG_HAS_CHANNEL_SWITCH |
   4404			WIPHY_FLAG_PS_ON_BY_DEFAULT;
   4405
   4406	if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
   4407		wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
   4408				WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
   4409
   4410#ifdef CONFIG_PM
   4411	if (ISSUPP_FIRMWARE_SUPPLICANT(priv->adapter->fw_cap_info))
   4412		wiphy->wowlan = &mwifiex_wowlan_support;
   4413	else
   4414		wiphy->wowlan = &mwifiex_wowlan_support_no_gtk;
   4415#endif
   4416
   4417	wiphy->coalesce = &mwifiex_coalesce_support;
   4418
   4419	wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
   4420				    NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
   4421				    NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
   4422
   4423	wiphy->max_sched_scan_reqs = 1;
   4424	wiphy->max_sched_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
   4425	wiphy->max_sched_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
   4426	wiphy->max_match_sets = MWIFIEX_MAX_SSID_LIST_LENGTH;
   4427
   4428	wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1;
   4429	wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1;
   4430
   4431	wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER |
   4432			   NL80211_FEATURE_LOW_PRIORITY_SCAN |
   4433			   NL80211_FEATURE_NEED_OBSS_SCAN;
   4434
   4435	if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info))
   4436		wiphy->features |= NL80211_FEATURE_HT_IBSS;
   4437
   4438	if (ISSUPP_RANDOM_MAC(adapter->fw_cap_info))
   4439		wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
   4440				   NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
   4441				   NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
   4442
   4443	if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
   4444		wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
   4445
   4446	if (adapter->fw_api_ver == MWIFIEX_FW_V15)
   4447		wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
   4448
   4449	/* Reserve space for mwifiex specific private data for BSS */
   4450	wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
   4451
   4452	wiphy->reg_notifier = mwifiex_reg_notifier;
   4453
   4454	/* Set struct mwifiex_adapter pointer in wiphy_priv */
   4455	wdev_priv = wiphy_priv(wiphy);
   4456	*(unsigned long *)wdev_priv = (unsigned long)adapter;
   4457
   4458	set_wiphy_dev(wiphy, priv->adapter->dev);
   4459
   4460	ret = wiphy_register(wiphy);
   4461	if (ret < 0) {
   4462		mwifiex_dbg(adapter, ERROR,
   4463			    "%s: wiphy_register failed: %d\n", __func__, ret);
   4464		wiphy_free(wiphy);
   4465		return ret;
   4466	}
   4467
   4468	if (!adapter->regd) {
   4469		if (reg_alpha2 && mwifiex_is_valid_alpha2(reg_alpha2)) {
   4470			mwifiex_dbg(adapter, INFO,
   4471				    "driver hint alpha2: %2.2s\n", reg_alpha2);
   4472			regulatory_hint(wiphy, reg_alpha2);
   4473		} else {
   4474			if (adapter->region_code == 0x00) {
   4475				mwifiex_dbg(adapter, WARN,
   4476					    "Ignore world regulatory domain\n");
   4477			} else {
   4478				wiphy->regulatory_flags |=
   4479					REGULATORY_DISABLE_BEACON_HINTS |
   4480					REGULATORY_COUNTRY_IE_IGNORE;
   4481				country_code =
   4482					mwifiex_11d_code_2_region(
   4483						adapter->region_code);
   4484				if (country_code &&
   4485				    regulatory_hint(wiphy, country_code))
   4486					mwifiex_dbg(priv->adapter, ERROR,
   4487						    "regulatory_hint() failed\n");
   4488			}
   4489		}
   4490	}
   4491
   4492	mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
   4493			 HostCmd_ACT_GEN_GET, FRAG_THRESH_I, &thr, true);
   4494	wiphy->frag_threshold = thr;
   4495	mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
   4496			 HostCmd_ACT_GEN_GET, RTS_THRESH_I, &thr, true);
   4497	wiphy->rts_threshold = thr;
   4498	mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
   4499			 HostCmd_ACT_GEN_GET, SHORT_RETRY_LIM_I, &retry, true);
   4500	wiphy->retry_short = (u8) retry;
   4501	mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
   4502			 HostCmd_ACT_GEN_GET, LONG_RETRY_LIM_I, &retry, true);
   4503	wiphy->retry_long = (u8) retry;
   4504
   4505	adapter->wiphy = wiphy;
   4506	return ret;
   4507}