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