]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/mwifiex/cfg80211.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[karo-tx-linux.git] / drivers / net / wireless / mwifiex / cfg80211.c
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
23 static char *reg_alpha2;
24 module_param(reg_alpha2, charp, 0);
25
26 static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
27         {
28                 .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
29                                    BIT(NL80211_IFTYPE_P2P_GO) |
30                                    BIT(NL80211_IFTYPE_P2P_CLIENT),
31         },
32         {
33                 .max = 1, .types = BIT(NL80211_IFTYPE_AP),
34         },
35 };
36
37 static const struct ieee80211_iface_combination 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 };
44
45 /*
46  * This function maps the nl802.11 channel type into driver channel type.
47  *
48  * The mapping is as follows -
49  *      NL80211_CHAN_NO_HT     -> IEEE80211_HT_PARAM_CHA_SEC_NONE
50  *      NL80211_CHAN_HT20      -> IEEE80211_HT_PARAM_CHA_SEC_NONE
51  *      NL80211_CHAN_HT40PLUS  -> IEEE80211_HT_PARAM_CHA_SEC_ABOVE
52  *      NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW
53  *      Others                 -> IEEE80211_HT_PARAM_CHA_SEC_NONE
54  */
55 u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
56 {
57         switch (chan_type) {
58         case NL80211_CHAN_NO_HT:
59         case NL80211_CHAN_HT20:
60                 return IEEE80211_HT_PARAM_CHA_SEC_NONE;
61         case NL80211_CHAN_HT40PLUS:
62                 return IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
63         case NL80211_CHAN_HT40MINUS:
64                 return IEEE80211_HT_PARAM_CHA_SEC_BELOW;
65         default:
66                 return IEEE80211_HT_PARAM_CHA_SEC_NONE;
67         }
68 }
69
70 /*
71  * This function checks whether WEP is set.
72  */
73 static int
74 mwifiex_is_alg_wep(u32 cipher)
75 {
76         switch (cipher) {
77         case WLAN_CIPHER_SUITE_WEP40:
78         case WLAN_CIPHER_SUITE_WEP104:
79                 return 1;
80         default:
81                 break;
82         }
83
84         return 0;
85 }
86
87 /*
88  * This function retrieves the private structure from kernel wiphy structure.
89  */
90 static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy)
91 {
92         return (void *) (*(unsigned long *) wiphy_priv(wiphy));
93 }
94
95 /*
96  * CFG802.11 operation handler to delete a network key.
97  */
98 static int
99 mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
100                          u8 key_index, bool pairwise, const u8 *mac_addr)
101 {
102         struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
103         const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
104         const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
105
106         if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index, peer_mac, 1)) {
107                 wiphy_err(wiphy, "deleting the crypto keys\n");
108                 return -EFAULT;
109         }
110
111         wiphy_dbg(wiphy, "info: crypto keys deleted\n");
112         return 0;
113 }
114
115 /*
116  * This function forms an skb for management frame.
117  */
118 static int
119 mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
120 {
121         u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
122         u16 pkt_len;
123         u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
124
125         pkt_len = len + ETH_ALEN;
126
127         skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN +
128                     MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
129         memcpy(skb_push(skb, sizeof(pkt_len)), &pkt_len, sizeof(pkt_len));
130
131         memcpy(skb_push(skb, sizeof(tx_control)),
132                &tx_control, sizeof(tx_control));
133
134         memcpy(skb_push(skb, sizeof(pkt_type)), &pkt_type, sizeof(pkt_type));
135
136         /* Add packet data and address4 */
137         memcpy(skb_put(skb, sizeof(struct ieee80211_hdr_3addr)), buf,
138                sizeof(struct ieee80211_hdr_3addr));
139         memcpy(skb_put(skb, ETH_ALEN), addr, ETH_ALEN);
140         memcpy(skb_put(skb, len - sizeof(struct ieee80211_hdr_3addr)),
141                buf + sizeof(struct ieee80211_hdr_3addr),
142                len - sizeof(struct ieee80211_hdr_3addr));
143
144         skb->priority = LOW_PRIO_TID;
145         __net_timestamp(skb);
146
147         return 0;
148 }
149
150 /*
151  * CFG802.11 operation handler to transmit a management frame.
152  */
153 static int
154 mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
155                          struct cfg80211_mgmt_tx_params *params, u64 *cookie)
156 {
157         const u8 *buf = params->buf;
158         size_t len = params->len;
159         struct sk_buff *skb;
160         u16 pkt_len;
161         const struct ieee80211_mgmt *mgmt;
162         struct mwifiex_txinfo *tx_info;
163         struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
164
165         if (!buf || !len) {
166                 wiphy_err(wiphy, "invalid buffer and length\n");
167                 return -EFAULT;
168         }
169
170         mgmt = (const struct ieee80211_mgmt *)buf;
171         if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA &&
172             ieee80211_is_probe_resp(mgmt->frame_control)) {
173                 /* Since we support offload probe resp, we need to skip probe
174                  * resp in AP or GO mode */
175                 wiphy_dbg(wiphy,
176                           "info: skip to send probe resp in AP or GO mode\n");
177                 return 0;
178         }
179
180         pkt_len = len + ETH_ALEN;
181         skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
182                             MWIFIEX_MGMT_FRAME_HEADER_SIZE +
183                             pkt_len + sizeof(pkt_len));
184
185         if (!skb) {
186                 wiphy_err(wiphy, "allocate skb failed for management frame\n");
187                 return -ENOMEM;
188         }
189
190         tx_info = MWIFIEX_SKB_TXCB(skb);
191         memset(tx_info, 0, sizeof(*tx_info));
192         tx_info->bss_num = priv->bss_num;
193         tx_info->bss_type = priv->bss_type;
194         tx_info->pkt_len = pkt_len;
195
196         mwifiex_form_mgmt_frame(skb, buf, len);
197         mwifiex_queue_tx_pkt(priv, skb);
198
199         *cookie = prandom_u32() | 1;
200         cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC);
201
202         wiphy_dbg(wiphy, "info: management frame transmitted\n");
203         return 0;
204 }
205
206 /*
207  * CFG802.11 operation handler to register a mgmt frame.
208  */
209 static void
210 mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
211                                      struct wireless_dev *wdev,
212                                      u16 frame_type, bool reg)
213 {
214         struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
215         u32 mask;
216
217         if (reg)
218                 mask = priv->mgmt_frame_mask | BIT(frame_type >> 4);
219         else
220                 mask = priv->mgmt_frame_mask & ~BIT(frame_type >> 4);
221
222         if (mask != priv->mgmt_frame_mask) {
223                 priv->mgmt_frame_mask = mask;
224                 mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
225                                  HostCmd_ACT_GEN_SET, 0,
226                                  &priv->mgmt_frame_mask, false);
227                 wiphy_dbg(wiphy, "info: mgmt frame registered\n");
228         }
229 }
230
231 /*
232  * CFG802.11 operation handler to remain on channel.
233  */
234 static int
235 mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
236                                    struct wireless_dev *wdev,
237                                    struct ieee80211_channel *chan,
238                                    unsigned int duration, u64 *cookie)
239 {
240         struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
241         int ret;
242
243         if (!chan || !cookie) {
244                 wiphy_err(wiphy, "Invalid parameter for ROC\n");
245                 return -EINVAL;
246         }
247
248         if (priv->roc_cfg.cookie) {
249                 wiphy_dbg(wiphy, "info: ongoing ROC, cookie = 0x%llx\n",
250                           priv->roc_cfg.cookie);
251                 return -EBUSY;
252         }
253
254         ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan,
255                                          duration);
256
257         if (!ret) {
258                 *cookie = prandom_u32() | 1;
259                 priv->roc_cfg.cookie = *cookie;
260                 priv->roc_cfg.chan = *chan;
261
262                 cfg80211_ready_on_channel(wdev, *cookie, chan,
263                                           duration, GFP_ATOMIC);
264
265                 wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie);
266         }
267
268         return ret;
269 }
270
271 /*
272  * CFG802.11 operation handler to cancel remain on channel.
273  */
274 static int
275 mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
276                                           struct wireless_dev *wdev, u64 cookie)
277 {
278         struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
279         int ret;
280
281         if (cookie != priv->roc_cfg.cookie)
282                 return -ENOENT;
283
284         ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
285                                          &priv->roc_cfg.chan, 0);
286
287         if (!ret) {
288                 cfg80211_remain_on_channel_expired(wdev, cookie,
289                                                    &priv->roc_cfg.chan,
290                                                    GFP_ATOMIC);
291
292                 memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
293
294                 wiphy_dbg(wiphy, "info: cancel ROC, cookie = 0x%llx\n", cookie);
295         }
296
297         return ret;
298 }
299
300 /*
301  * CFG802.11 operation handler to set Tx power.
302  */
303 static int
304 mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
305                               struct wireless_dev *wdev,
306                               enum nl80211_tx_power_setting type,
307                               int mbm)
308 {
309         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
310         struct mwifiex_private *priv;
311         struct mwifiex_power_cfg power_cfg;
312         int dbm = MBM_TO_DBM(mbm);
313
314         if (type == NL80211_TX_POWER_FIXED) {
315                 power_cfg.is_power_auto = 0;
316                 power_cfg.power_level = dbm;
317         } else {
318                 power_cfg.is_power_auto = 1;
319         }
320
321         priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
322
323         return mwifiex_set_tx_power(priv, &power_cfg);
324 }
325
326 /*
327  * CFG802.11 operation handler to set Power Save option.
328  *
329  * The timeout value, if provided, is currently ignored.
330  */
331 static int
332 mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
333                                 struct net_device *dev,
334                                 bool enabled, int timeout)
335 {
336         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
337         u32 ps_mode;
338
339         if (timeout)
340                 wiphy_dbg(wiphy,
341                           "info: ignore timeout value for IEEE Power Save\n");
342
343         ps_mode = enabled;
344
345         return mwifiex_drv_set_power(priv, &ps_mode);
346 }
347
348 /*
349  * CFG802.11 operation handler to set the default network key.
350  */
351 static int
352 mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
353                                  u8 key_index, bool unicast,
354                                  bool multicast)
355 {
356         struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
357
358         /* Return if WEP key not configured */
359         if (!priv->sec_info.wep_enabled)
360                 return 0;
361
362         if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
363                 priv->wep_key_curr_index = key_index;
364         } else if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index,
365                                       NULL, 0)) {
366                 wiphy_err(wiphy, "set default Tx key index\n");
367                 return -EFAULT;
368         }
369
370         return 0;
371 }
372
373 /*
374  * CFG802.11 operation handler to add a network key.
375  */
376 static int
377 mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
378                          u8 key_index, bool pairwise, const u8 *mac_addr,
379                          struct key_params *params)
380 {
381         struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
382         struct mwifiex_wep_key *wep_key;
383         const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
384         const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
385
386         if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
387             (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
388              params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
389                 if (params->key && params->key_len) {
390                         wep_key = &priv->wep_key[key_index];
391                         memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
392                         memcpy(wep_key->key_material, params->key,
393                                params->key_len);
394                         wep_key->key_index = key_index;
395                         wep_key->key_length = params->key_len;
396                         priv->sec_info.wep_enabled = 1;
397                 }
398                 return 0;
399         }
400
401         if (mwifiex_set_encode(priv, params, params->key, params->key_len,
402                                key_index, peer_mac, 0)) {
403                 wiphy_err(wiphy, "crypto keys added\n");
404                 return -EFAULT;
405         }
406
407         return 0;
408 }
409
410 /*
411  * This function sends domain information to the firmware.
412  *
413  * The following information are passed to the firmware -
414  *      - Country codes
415  *      - Sub bands (first channel, number of channels, maximum Tx power)
416  */
417 static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
418 {
419         u8 no_of_triplet = 0;
420         struct ieee80211_country_ie_triplet *t;
421         u8 no_of_parsed_chan = 0;
422         u8 first_chan = 0, next_chan = 0, max_pwr = 0;
423         u8 i, flag = 0;
424         enum ieee80211_band band;
425         struct ieee80211_supported_band *sband;
426         struct ieee80211_channel *ch;
427         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
428         struct mwifiex_private *priv;
429         struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
430
431         /* Set country code */
432         domain_info->country_code[0] = adapter->country_code[0];
433         domain_info->country_code[1] = adapter->country_code[1];
434         domain_info->country_code[2] = ' ';
435
436         band = mwifiex_band_to_radio_type(adapter->config_bands);
437         if (!wiphy->bands[band]) {
438                 wiphy_err(wiphy, "11D: setting domain info in FW\n");
439                 return -1;
440         }
441
442         sband = wiphy->bands[band];
443
444         for (i = 0; i < sband->n_channels ; i++) {
445                 ch = &sband->channels[i];
446                 if (ch->flags & IEEE80211_CHAN_DISABLED)
447                         continue;
448
449                 if (!flag) {
450                         flag = 1;
451                         first_chan = (u32) ch->hw_value;
452                         next_chan = first_chan;
453                         max_pwr = ch->max_power;
454                         no_of_parsed_chan = 1;
455                         continue;
456                 }
457
458                 if (ch->hw_value == next_chan + 1 &&
459                     ch->max_power == max_pwr) {
460                         next_chan++;
461                         no_of_parsed_chan++;
462                 } else {
463                         t = &domain_info->triplet[no_of_triplet];
464                         t->chans.first_channel = first_chan;
465                         t->chans.num_channels = no_of_parsed_chan;
466                         t->chans.max_power = max_pwr;
467                         no_of_triplet++;
468                         first_chan = (u32) ch->hw_value;
469                         next_chan = first_chan;
470                         max_pwr = ch->max_power;
471                         no_of_parsed_chan = 1;
472                 }
473         }
474
475         if (flag) {
476                 t = &domain_info->triplet[no_of_triplet];
477                 t->chans.first_channel = first_chan;
478                 t->chans.num_channels = no_of_parsed_chan;
479                 t->chans.max_power = max_pwr;
480                 no_of_triplet++;
481         }
482
483         domain_info->no_of_triplet = no_of_triplet;
484
485         priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
486
487         if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
488                              HostCmd_ACT_GEN_SET, 0, NULL, false)) {
489                 wiphy_err(wiphy, "11D: setting domain info in FW\n");
490                 return -1;
491         }
492
493         return 0;
494 }
495
496 /*
497  * CFG802.11 regulatory domain callback function.
498  *
499  * This function is called when the regulatory domain is changed due to the
500  * following reasons -
501  *      - Set by driver
502  *      - Set by system core
503  *      - Set by user
504  *      - Set bt Country IE
505  */
506 static void mwifiex_reg_notifier(struct wiphy *wiphy,
507                                  struct regulatory_request *request)
508 {
509         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
510         struct mwifiex_private *priv = mwifiex_get_priv(adapter,
511                                                         MWIFIEX_BSS_ROLE_ANY);
512
513         wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n",
514                   request->alpha2[0], request->alpha2[1]);
515
516         switch (request->initiator) {
517         case NL80211_REGDOM_SET_BY_DRIVER:
518         case NL80211_REGDOM_SET_BY_CORE:
519         case NL80211_REGDOM_SET_BY_USER:
520         case NL80211_REGDOM_SET_BY_COUNTRY_IE:
521                 break;
522         default:
523                 wiphy_err(wiphy, "unknown regdom initiator: %d\n",
524                           request->initiator);
525                 return;
526         }
527
528         /* Don't send world or same regdom info to firmware */
529         if (strncmp(request->alpha2, "00", 2) &&
530             strncmp(request->alpha2, adapter->country_code,
531                     sizeof(request->alpha2))) {
532                 memcpy(adapter->country_code, request->alpha2,
533                        sizeof(request->alpha2));
534                 mwifiex_send_domain_info_cmd_fw(wiphy);
535                 mwifiex_dnld_txpwr_table(priv);
536         }
537 }
538
539 /*
540  * This function sets the fragmentation threshold.
541  *
542  * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE
543  * and MWIFIEX_FRAG_MAX_VALUE.
544  */
545 static int
546 mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
547 {
548         if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
549             frag_thr > MWIFIEX_FRAG_MAX_VALUE)
550                 frag_thr = MWIFIEX_FRAG_MAX_VALUE;
551
552         return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
553                                 HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
554                                 &frag_thr, true);
555 }
556
557 /*
558  * This function sets the RTS threshold.
559
560  * The rts value must lie between MWIFIEX_RTS_MIN_VALUE
561  * and MWIFIEX_RTS_MAX_VALUE.
562  */
563 static int
564 mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
565 {
566         if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
567                 rts_thr = MWIFIEX_RTS_MAX_VALUE;
568
569         return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
570                                 HostCmd_ACT_GEN_SET, RTS_THRESH_I,
571                                 &rts_thr, true);
572 }
573
574 /*
575  * CFG802.11 operation handler to set wiphy parameters.
576  *
577  * This function can be used to set the RTS threshold and the
578  * Fragmentation threshold of the driver.
579  */
580 static int
581 mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
582 {
583         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
584         struct mwifiex_private *priv;
585         struct mwifiex_uap_bss_param *bss_cfg;
586         int ret, bss_started, i;
587
588         for (i = 0; i < adapter->priv_num; i++) {
589                 priv = adapter->priv[i];
590
591                 switch (priv->bss_role) {
592                 case MWIFIEX_BSS_ROLE_UAP:
593                         bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param),
594                                           GFP_KERNEL);
595                         if (!bss_cfg)
596                                 return -ENOMEM;
597
598                         mwifiex_set_sys_config_invalid_data(bss_cfg);
599
600                         if (changed & WIPHY_PARAM_RTS_THRESHOLD)
601                                 bss_cfg->rts_threshold = wiphy->rts_threshold;
602                         if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
603                                 bss_cfg->frag_threshold = wiphy->frag_threshold;
604                         if (changed & WIPHY_PARAM_RETRY_LONG)
605                                 bss_cfg->retry_limit = wiphy->retry_long;
606
607                         bss_started = priv->bss_started;
608
609                         ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
610                                                HostCmd_ACT_GEN_SET, 0,
611                                                NULL, true);
612                         if (ret) {
613                                 wiphy_err(wiphy, "Failed to stop the BSS\n");
614                                 kfree(bss_cfg);
615                                 return ret;
616                         }
617
618                         ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
619                                                HostCmd_ACT_GEN_SET,
620                                                UAP_BSS_PARAMS_I, bss_cfg,
621                                                false);
622
623                         kfree(bss_cfg);
624
625                         if (ret) {
626                                 wiphy_err(wiphy, "Failed to set bss config\n");
627                                 return ret;
628                         }
629
630                         if (!bss_started)
631                                 break;
632
633                         ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
634                                                HostCmd_ACT_GEN_SET, 0,
635                                                NULL, false);
636                         if (ret) {
637                                 wiphy_err(wiphy, "Failed to start BSS\n");
638                                 return ret;
639                         }
640
641                         break;
642                 case MWIFIEX_BSS_ROLE_STA:
643                         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
644                                 ret = mwifiex_set_rts(priv,
645                                                       wiphy->rts_threshold);
646                                 if (ret)
647                                         return ret;
648                         }
649                         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
650                                 ret = mwifiex_set_frag(priv,
651                                                        wiphy->frag_threshold);
652                                 if (ret)
653                                         return ret;
654                         }
655                         break;
656                 }
657         }
658
659         return 0;
660 }
661
662 static int
663 mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
664 {
665         u16 mode = P2P_MODE_DISABLE;
666
667         if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA)
668                 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA);
669
670         if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
671                              HostCmd_ACT_GEN_SET, 0, &mode, true))
672                 return -1;
673
674         return 0;
675 }
676
677 /*
678  * This function initializes the functionalities for P2P client.
679  * The P2P client initialization sequence is:
680  * disable -> device -> client
681  */
682 static int
683 mwifiex_cfg80211_init_p2p_client(struct mwifiex_private *priv)
684 {
685         u16 mode;
686
687         if (mwifiex_cfg80211_deinit_p2p(priv))
688                 return -1;
689
690         mode = P2P_MODE_DEVICE;
691         if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
692                              HostCmd_ACT_GEN_SET, 0, &mode, true))
693                 return -1;
694
695         mode = P2P_MODE_CLIENT;
696         if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
697                              HostCmd_ACT_GEN_SET, 0, &mode, true))
698                 return -1;
699
700         return 0;
701 }
702
703 /*
704  * This function initializes the functionalities for P2P GO.
705  * The P2P GO initialization sequence is:
706  * disable -> device -> GO
707  */
708 static int
709 mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
710 {
711         u16 mode;
712
713         if (mwifiex_cfg80211_deinit_p2p(priv))
714                 return -1;
715
716         mode = P2P_MODE_DEVICE;
717         if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
718                              HostCmd_ACT_GEN_SET, 0, &mode, true))
719                 return -1;
720
721         mode = P2P_MODE_GO;
722         if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
723                              HostCmd_ACT_GEN_SET, 0, &mode, true))
724                 return -1;
725
726         if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
727                 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_UAP);
728
729         return 0;
730 }
731
732 /*
733  * CFG802.11 operation handler to change interface type.
734  */
735 static int
736 mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
737                                      struct net_device *dev,
738                                      enum nl80211_iftype type, u32 *flags,
739                                      struct vif_params *params)
740 {
741         int ret;
742         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
743
744         switch (dev->ieee80211_ptr->iftype) {
745         case NL80211_IFTYPE_ADHOC:
746                 switch (type) {
747                 case NL80211_IFTYPE_STATION:
748                         break;
749                 case NL80211_IFTYPE_UNSPECIFIED:
750                         wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name);
751                 case NL80211_IFTYPE_ADHOC:      /* This shouldn't happen */
752                         return 0;
753                 case NL80211_IFTYPE_AP:
754                 default:
755                         wiphy_err(wiphy, "%s: changing to %d not supported\n",
756                                   dev->name, type);
757                         return -EOPNOTSUPP;
758                 }
759                 break;
760         case NL80211_IFTYPE_STATION:
761                 switch (type) {
762                 case NL80211_IFTYPE_ADHOC:
763                         break;
764                 case NL80211_IFTYPE_P2P_CLIENT:
765                         if (mwifiex_cfg80211_init_p2p_client(priv))
766                                 return -EFAULT;
767                         dev->ieee80211_ptr->iftype = type;
768                         return 0;
769                 case NL80211_IFTYPE_P2P_GO:
770                         if (mwifiex_cfg80211_init_p2p_go(priv))
771                                 return -EFAULT;
772                         dev->ieee80211_ptr->iftype = type;
773                         return 0;
774                 case NL80211_IFTYPE_UNSPECIFIED:
775                         wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
776                 case NL80211_IFTYPE_STATION:    /* This shouldn't happen */
777                         return 0;
778                 case NL80211_IFTYPE_AP:
779                 default:
780                         wiphy_err(wiphy, "%s: changing to %d not supported\n",
781                                   dev->name, type);
782                         return -EOPNOTSUPP;
783                 }
784                 break;
785         case NL80211_IFTYPE_AP:
786                 switch (type) {
787                 case NL80211_IFTYPE_UNSPECIFIED:
788                         wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name);
789                 case NL80211_IFTYPE_AP:         /* This shouldn't happen */
790                         return 0;
791                 case NL80211_IFTYPE_ADHOC:
792                 case NL80211_IFTYPE_STATION:
793                 default:
794                         wiphy_err(wiphy, "%s: changing to %d not supported\n",
795                                   dev->name, type);
796                         return -EOPNOTSUPP;
797                 }
798                 break;
799         case NL80211_IFTYPE_P2P_CLIENT:
800         case NL80211_IFTYPE_P2P_GO:
801                 switch (type) {
802                 case NL80211_IFTYPE_STATION:
803                         if (mwifiex_cfg80211_deinit_p2p(priv))
804                                 return -EFAULT;
805                         dev->ieee80211_ptr->iftype = type;
806                         return 0;
807                 default:
808                         return -EOPNOTSUPP;
809                 }
810                 break;
811         default:
812                 wiphy_err(wiphy, "%s: unknown iftype: %d\n",
813                           dev->name, dev->ieee80211_ptr->iftype);
814                 return -EOPNOTSUPP;
815         }
816
817         dev->ieee80211_ptr->iftype = type;
818         priv->bss_mode = type;
819         mwifiex_deauthenticate(priv, NULL);
820
821         priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
822
823         ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
824                                HostCmd_ACT_GEN_SET, 0, NULL, true);
825
826         return ret;
827 }
828
829 static void
830 mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
831                      struct rate_info *rate)
832 {
833         struct mwifiex_adapter *adapter = priv->adapter;
834
835         if (adapter->is_hw_11ac_capable) {
836                 /* bit[1-0]: 00=LG 01=HT 10=VHT */
837                 if (tx_htinfo & BIT(0)) {
838                         /* HT */
839                         rate->mcs = priv->tx_rate;
840                         rate->flags |= RATE_INFO_FLAGS_MCS;
841                 }
842                 if (tx_htinfo & BIT(1)) {
843                         /* VHT */
844                         rate->mcs = priv->tx_rate & 0x0F;
845                         rate->flags |= RATE_INFO_FLAGS_VHT_MCS;
846                 }
847
848                 if (tx_htinfo & (BIT(1) | BIT(0))) {
849                         /* HT or VHT */
850                         switch (tx_htinfo & (BIT(3) | BIT(2))) {
851                         case 0:
852                                 /* This will be 20MHz */
853                                 break;
854                         case (BIT(2)):
855                                 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
856                                 break;
857                         case (BIT(3)):
858                                 rate->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
859                                 break;
860                         case (BIT(3) | BIT(2)):
861                                 rate->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
862                                 break;
863                         }
864
865                         if (tx_htinfo & BIT(4))
866                                 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
867
868                         if ((priv->tx_rate >> 4) == 1)
869                                 rate->nss = 2;
870                         else
871                                 rate->nss = 1;
872                 }
873         } else {
874                 /*
875                  * Bit 0 in tx_htinfo indicates that current Tx rate
876                  * is 11n rate. Valid MCS index values for us are 0 to 15.
877                  */
878                 if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
879                         rate->mcs = priv->tx_rate;
880                         rate->flags |= RATE_INFO_FLAGS_MCS;
881                         if (tx_htinfo & BIT(1))
882                                 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
883                         if (tx_htinfo & BIT(2))
884                                 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
885                 }
886         }
887 }
888
889 /*
890  * This function dumps the station information on a buffer.
891  *
892  * The following information are shown -
893  *      - Total bytes transmitted
894  *      - Total bytes received
895  *      - Total packets transmitted
896  *      - Total packets received
897  *      - Signal quality level
898  *      - Transmission rate
899  */
900 static int
901 mwifiex_dump_station_info(struct mwifiex_private *priv,
902                           struct station_info *sinfo)
903 {
904         u32 rate;
905
906         sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES |
907                         STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS |
908                         STATION_INFO_TX_BITRATE |
909                         STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
910
911         /* Get signal information from the firmware */
912         if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
913                              HostCmd_ACT_GEN_GET, 0, NULL, true)) {
914                 dev_err(priv->adapter->dev, "failed to get signal information\n");
915                 return -EFAULT;
916         }
917
918         if (mwifiex_drv_get_data_rate(priv, &rate)) {
919                 dev_err(priv->adapter->dev, "getting data rate\n");
920                 return -EFAULT;
921         }
922
923         /* Get DTIM period information from firmware */
924         mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
925                          HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
926                          &priv->dtim_period, true);
927
928         mwifiex_parse_htinfo(priv, priv->tx_htinfo, &sinfo->txrate);
929
930         sinfo->signal_avg = priv->bcn_rssi_avg;
931         sinfo->rx_bytes = priv->stats.rx_bytes;
932         sinfo->tx_bytes = priv->stats.tx_bytes;
933         sinfo->rx_packets = priv->stats.rx_packets;
934         sinfo->tx_packets = priv->stats.tx_packets;
935         sinfo->signal = priv->bcn_rssi_avg;
936         /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
937         sinfo->txrate.legacy = rate * 5;
938
939         if (priv->bss_mode == NL80211_IFTYPE_STATION) {
940                 sinfo->filled |= STATION_INFO_BSS_PARAM;
941                 sinfo->bss_param.flags = 0;
942                 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
943                                                 WLAN_CAPABILITY_SHORT_PREAMBLE)
944                         sinfo->bss_param.flags |=
945                                         BSS_PARAM_FLAGS_SHORT_PREAMBLE;
946                 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
947                                                 WLAN_CAPABILITY_SHORT_SLOT_TIME)
948                         sinfo->bss_param.flags |=
949                                         BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
950                 sinfo->bss_param.dtim_period = priv->dtim_period;
951                 sinfo->bss_param.beacon_interval =
952                         priv->curr_bss_params.bss_descriptor.beacon_period;
953         }
954
955         return 0;
956 }
957
958 /*
959  * CFG802.11 operation handler to get station information.
960  *
961  * This function only works in connected mode, and dumps the
962  * requested station information, if available.
963  */
964 static int
965 mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
966                              const u8 *mac, struct station_info *sinfo)
967 {
968         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
969
970         if (!priv->media_connected)
971                 return -ENOENT;
972         if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
973                 return -ENOENT;
974
975         return mwifiex_dump_station_info(priv, sinfo);
976 }
977
978 /*
979  * CFG802.11 operation handler to dump station information.
980  */
981 static int
982 mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
983                               int idx, u8 *mac, struct station_info *sinfo)
984 {
985         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
986
987         if (!priv->media_connected || idx)
988                 return -ENOENT;
989
990         memcpy(mac, priv->cfg_bssid, ETH_ALEN);
991
992         return mwifiex_dump_station_info(priv, sinfo);
993 }
994
995 /* Supported rates to be advertised to the cfg80211 */
996 static struct ieee80211_rate mwifiex_rates[] = {
997         {.bitrate = 10, .hw_value = 2, },
998         {.bitrate = 20, .hw_value = 4, },
999         {.bitrate = 55, .hw_value = 11, },
1000         {.bitrate = 110, .hw_value = 22, },
1001         {.bitrate = 60, .hw_value = 12, },
1002         {.bitrate = 90, .hw_value = 18, },
1003         {.bitrate = 120, .hw_value = 24, },
1004         {.bitrate = 180, .hw_value = 36, },
1005         {.bitrate = 240, .hw_value = 48, },
1006         {.bitrate = 360, .hw_value = 72, },
1007         {.bitrate = 480, .hw_value = 96, },
1008         {.bitrate = 540, .hw_value = 108, },
1009 };
1010
1011 /* Channel definitions to be advertised to cfg80211 */
1012 static struct ieee80211_channel mwifiex_channels_2ghz[] = {
1013         {.center_freq = 2412, .hw_value = 1, },
1014         {.center_freq = 2417, .hw_value = 2, },
1015         {.center_freq = 2422, .hw_value = 3, },
1016         {.center_freq = 2427, .hw_value = 4, },
1017         {.center_freq = 2432, .hw_value = 5, },
1018         {.center_freq = 2437, .hw_value = 6, },
1019         {.center_freq = 2442, .hw_value = 7, },
1020         {.center_freq = 2447, .hw_value = 8, },
1021         {.center_freq = 2452, .hw_value = 9, },
1022         {.center_freq = 2457, .hw_value = 10, },
1023         {.center_freq = 2462, .hw_value = 11, },
1024         {.center_freq = 2467, .hw_value = 12, },
1025         {.center_freq = 2472, .hw_value = 13, },
1026         {.center_freq = 2484, .hw_value = 14, },
1027 };
1028
1029 static struct ieee80211_supported_band mwifiex_band_2ghz = {
1030         .channels = mwifiex_channels_2ghz,
1031         .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
1032         .bitrates = mwifiex_rates,
1033         .n_bitrates = ARRAY_SIZE(mwifiex_rates),
1034 };
1035
1036 static struct ieee80211_channel mwifiex_channels_5ghz[] = {
1037         {.center_freq = 5040, .hw_value = 8, },
1038         {.center_freq = 5060, .hw_value = 12, },
1039         {.center_freq = 5080, .hw_value = 16, },
1040         {.center_freq = 5170, .hw_value = 34, },
1041         {.center_freq = 5190, .hw_value = 38, },
1042         {.center_freq = 5210, .hw_value = 42, },
1043         {.center_freq = 5230, .hw_value = 46, },
1044         {.center_freq = 5180, .hw_value = 36, },
1045         {.center_freq = 5200, .hw_value = 40, },
1046         {.center_freq = 5220, .hw_value = 44, },
1047         {.center_freq = 5240, .hw_value = 48, },
1048         {.center_freq = 5260, .hw_value = 52, },
1049         {.center_freq = 5280, .hw_value = 56, },
1050         {.center_freq = 5300, .hw_value = 60, },
1051         {.center_freq = 5320, .hw_value = 64, },
1052         {.center_freq = 5500, .hw_value = 100, },
1053         {.center_freq = 5520, .hw_value = 104, },
1054         {.center_freq = 5540, .hw_value = 108, },
1055         {.center_freq = 5560, .hw_value = 112, },
1056         {.center_freq = 5580, .hw_value = 116, },
1057         {.center_freq = 5600, .hw_value = 120, },
1058         {.center_freq = 5620, .hw_value = 124, },
1059         {.center_freq = 5640, .hw_value = 128, },
1060         {.center_freq = 5660, .hw_value = 132, },
1061         {.center_freq = 5680, .hw_value = 136, },
1062         {.center_freq = 5700, .hw_value = 140, },
1063         {.center_freq = 5745, .hw_value = 149, },
1064         {.center_freq = 5765, .hw_value = 153, },
1065         {.center_freq = 5785, .hw_value = 157, },
1066         {.center_freq = 5805, .hw_value = 161, },
1067         {.center_freq = 5825, .hw_value = 165, },
1068 };
1069
1070 static struct ieee80211_supported_band mwifiex_band_5ghz = {
1071         .channels = mwifiex_channels_5ghz,
1072         .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
1073         .bitrates = mwifiex_rates + 4,
1074         .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4,
1075 };
1076
1077
1078 /* Supported crypto cipher suits to be advertised to cfg80211 */
1079 static const u32 mwifiex_cipher_suites[] = {
1080         WLAN_CIPHER_SUITE_WEP40,
1081         WLAN_CIPHER_SUITE_WEP104,
1082         WLAN_CIPHER_SUITE_TKIP,
1083         WLAN_CIPHER_SUITE_CCMP,
1084         WLAN_CIPHER_SUITE_AES_CMAC,
1085 };
1086
1087 /* Supported mgmt frame types to be advertised to cfg80211 */
1088 static const struct ieee80211_txrx_stypes
1089 mwifiex_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1090         [NL80211_IFTYPE_STATION] = {
1091                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1092                       BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1093                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1094                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1095         },
1096         [NL80211_IFTYPE_AP] = {
1097                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1098                       BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1099                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1100                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1101         },
1102         [NL80211_IFTYPE_P2P_CLIENT] = {
1103                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1104                       BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1105                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1106                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1107         },
1108         [NL80211_IFTYPE_P2P_GO] = {
1109                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1110                       BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1111                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1112                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
1113         },
1114 };
1115
1116 /*
1117  * CFG802.11 operation handler for setting bit rates.
1118  *
1119  * Function configures data rates to firmware using bitrate mask
1120  * provided by cfg80211.
1121  */
1122 static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
1123                                 struct net_device *dev,
1124                                 const u8 *peer,
1125                                 const struct cfg80211_bitrate_mask *mask)
1126 {
1127         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1128         u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
1129         enum ieee80211_band band;
1130         struct mwifiex_adapter *adapter = priv->adapter;
1131
1132         if (!priv->media_connected) {
1133                 dev_err(adapter->dev,
1134                         "Can not set Tx data rate in disconnected state\n");
1135                 return -EINVAL;
1136         }
1137
1138         band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
1139
1140         memset(bitmap_rates, 0, sizeof(bitmap_rates));
1141
1142         /* Fill HR/DSSS rates. */
1143         if (band == IEEE80211_BAND_2GHZ)
1144                 bitmap_rates[0] = mask->control[band].legacy & 0x000f;
1145
1146         /* Fill OFDM rates */
1147         if (band == IEEE80211_BAND_2GHZ)
1148                 bitmap_rates[1] = (mask->control[band].legacy & 0x0ff0) >> 4;
1149         else
1150                 bitmap_rates[1] = mask->control[band].legacy;
1151
1152         /* Fill HT MCS rates */
1153         bitmap_rates[2] = mask->control[band].ht_mcs[0];
1154         if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
1155                 bitmap_rates[2] |= mask->control[band].ht_mcs[1] << 8;
1156
1157        /* Fill VHT MCS rates */
1158         if (adapter->fw_api_ver == MWIFIEX_FW_V15) {
1159                 bitmap_rates[10] = mask->control[band].vht_mcs[0];
1160                 if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
1161                         bitmap_rates[11] = mask->control[band].vht_mcs[1];
1162         }
1163
1164         return mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
1165                                 HostCmd_ACT_GEN_SET, 0, bitmap_rates, true);
1166 }
1167
1168 /*
1169  * CFG802.11 operation handler for connection quality monitoring.
1170  *
1171  * This function subscribes/unsubscribes HIGH_RSSI and LOW_RSSI
1172  * events to FW.
1173  */
1174 static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
1175                                                 struct net_device *dev,
1176                                                 s32 rssi_thold, u32 rssi_hyst)
1177 {
1178         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1179         struct mwifiex_ds_misc_subsc_evt subsc_evt;
1180
1181         priv->cqm_rssi_thold = rssi_thold;
1182         priv->cqm_rssi_hyst = rssi_hyst;
1183
1184         memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
1185         subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
1186
1187         /* Subscribe/unsubscribe low and high rssi events */
1188         if (rssi_thold && rssi_hyst) {
1189                 subsc_evt.action = HostCmd_ACT_BITWISE_SET;
1190                 subsc_evt.bcn_l_rssi_cfg.abs_value = abs(rssi_thold);
1191                 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold);
1192                 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
1193                 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
1194                 return mwifiex_send_cmd(priv,
1195                                         HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
1196                                         0, 0, &subsc_evt, true);
1197         } else {
1198                 subsc_evt.action = HostCmd_ACT_BITWISE_CLR;
1199                 return mwifiex_send_cmd(priv,
1200                                         HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
1201                                         0, 0, &subsc_evt, true);
1202         }
1203
1204         return 0;
1205 }
1206
1207 /* cfg80211 operation handler for change_beacon.
1208  * Function retrieves and sets modified management IEs to FW.
1209  */
1210 static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
1211                                           struct net_device *dev,
1212                                           struct cfg80211_beacon_data *data)
1213 {
1214         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1215
1216         if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
1217                 wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__);
1218                 return -EINVAL;
1219         }
1220
1221         if (!priv->bss_started) {
1222                 wiphy_err(wiphy, "%s: bss not started\n", __func__);
1223                 return -EINVAL;
1224         }
1225
1226         if (mwifiex_set_mgmt_ies(priv, data)) {
1227                 wiphy_err(wiphy, "%s: setting mgmt ies failed\n", __func__);
1228                 return -EFAULT;
1229         }
1230
1231         return 0;
1232 }
1233
1234 /* cfg80211 operation handler for del_station.
1235  * Function deauthenticates station which value is provided in mac parameter.
1236  * If mac is NULL/broadcast, all stations in associated station list are
1237  * deauthenticated. If bss is not started or there are no stations in
1238  * associated stations list, no action is taken.
1239  */
1240 static int
1241 mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1242                              const u8 *mac)
1243 {
1244         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1245         struct mwifiex_sta_node *sta_node;
1246         unsigned long flags;
1247
1248         if (list_empty(&priv->sta_list) || !priv->bss_started)
1249                 return 0;
1250
1251         if (!mac || is_broadcast_ether_addr(mac)) {
1252                 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
1253                 list_for_each_entry(sta_node, &priv->sta_list, list) {
1254                         if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
1255                                              HostCmd_ACT_GEN_SET, 0,
1256                                              sta_node->mac_addr, true))
1257                                 return -1;
1258                         mwifiex_uap_del_sta_data(priv, sta_node);
1259                 }
1260         } else {
1261                 wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac);
1262                 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
1263                 sta_node = mwifiex_get_sta_entry(priv, mac);
1264                 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1265                 if (sta_node) {
1266                         if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
1267                                              HostCmd_ACT_GEN_SET, 0,
1268                                              sta_node->mac_addr, true))
1269                                 return -1;
1270                         mwifiex_uap_del_sta_data(priv, sta_node);
1271                 }
1272         }
1273
1274         return 0;
1275 }
1276
1277 static int
1278 mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
1279 {
1280         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
1281         struct mwifiex_private *priv = mwifiex_get_priv(adapter,
1282                                                         MWIFIEX_BSS_ROLE_ANY);
1283         struct mwifiex_ds_ant_cfg ant_cfg;
1284
1285         if (!tx_ant || !rx_ant)
1286                 return -EOPNOTSUPP;
1287
1288         if (adapter->hw_dev_mcs_support != HT_STREAM_2X2) {
1289                 /* Not a MIMO chip. User should provide specific antenna number
1290                  * for Tx/Rx path or enable all antennas for diversity
1291                  */
1292                 if (tx_ant != rx_ant)
1293                         return -EOPNOTSUPP;
1294
1295                 if ((tx_ant & (tx_ant - 1)) &&
1296                     (tx_ant != BIT(adapter->number_of_antenna) - 1))
1297                         return -EOPNOTSUPP;
1298
1299                 if ((tx_ant == BIT(adapter->number_of_antenna) - 1) &&
1300                     (priv->adapter->number_of_antenna > 1)) {
1301                         tx_ant = RF_ANTENNA_AUTO;
1302                         rx_ant = RF_ANTENNA_AUTO;
1303                 }
1304         } else {
1305                 struct ieee80211_sta_ht_cap *ht_info;
1306                 int rx_mcs_supp;
1307                 enum ieee80211_band band;
1308
1309                 if ((tx_ant == 0x1 && rx_ant == 0x1)) {
1310                         adapter->user_dev_mcs_support = HT_STREAM_1X1;
1311                         if (adapter->is_hw_11ac_capable)
1312                                 adapter->usr_dot_11ac_mcs_support =
1313                                                 MWIFIEX_11AC_MCS_MAP_1X1;
1314                 } else {
1315                         adapter->user_dev_mcs_support = HT_STREAM_2X2;
1316                         if (adapter->is_hw_11ac_capable)
1317                                 adapter->usr_dot_11ac_mcs_support =
1318                                                 MWIFIEX_11AC_MCS_MAP_2X2;
1319                 }
1320
1321                 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1322                         if (!adapter->wiphy->bands[band])
1323                                 continue;
1324
1325                         ht_info = &adapter->wiphy->bands[band]->ht_cap;
1326                         rx_mcs_supp =
1327                                 GET_RXMCSSUPP(adapter->user_dev_mcs_support);
1328                         memset(&ht_info->mcs, 0, adapter->number_of_antenna);
1329                         memset(&ht_info->mcs, 0xff, rx_mcs_supp);
1330                 }
1331         }
1332
1333         ant_cfg.tx_ant = tx_ant;
1334         ant_cfg.rx_ant = rx_ant;
1335
1336         return mwifiex_send_cmd(priv, HostCmd_CMD_RF_ANTENNA,
1337                                 HostCmd_ACT_GEN_SET, 0, &ant_cfg, true);
1338 }
1339
1340 /* cfg80211 operation handler for stop ap.
1341  * Function stops BSS running at uAP interface.
1342  */
1343 static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1344 {
1345         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1346
1347         if (mwifiex_del_mgmt_ies(priv))
1348                 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
1349
1350         priv->ap_11n_enabled = 0;
1351
1352         if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1353                              HostCmd_ACT_GEN_SET, 0, NULL, true)) {
1354                 wiphy_err(wiphy, "Failed to stop the BSS\n");
1355                 return -1;
1356         }
1357
1358         return 0;
1359 }
1360
1361 /* cfg80211 operation handler for start_ap.
1362  * Function sets beacon period, DTIM period, SSID and security into
1363  * AP config structure.
1364  * AP is configured with these settings and BSS is started.
1365  */
1366 static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1367                                      struct net_device *dev,
1368                                      struct cfg80211_ap_settings *params)
1369 {
1370         struct mwifiex_uap_bss_param *bss_cfg;
1371         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1372         u8 config_bands = 0;
1373
1374         if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
1375                 return -1;
1376         if (mwifiex_set_mgmt_ies(priv, &params->beacon))
1377                 return -1;
1378
1379         bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
1380         if (!bss_cfg)
1381                 return -ENOMEM;
1382
1383         mwifiex_set_sys_config_invalid_data(bss_cfg);
1384
1385         if (params->beacon_interval)
1386                 bss_cfg->beacon_period = params->beacon_interval;
1387         if (params->dtim_period)
1388                 bss_cfg->dtim_period = params->dtim_period;
1389
1390         if (params->ssid && params->ssid_len) {
1391                 memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len);
1392                 bss_cfg->ssid.ssid_len = params->ssid_len;
1393         }
1394
1395         switch (params->hidden_ssid) {
1396         case NL80211_HIDDEN_SSID_NOT_IN_USE:
1397                 bss_cfg->bcast_ssid_ctl = 1;
1398                 break;
1399         case NL80211_HIDDEN_SSID_ZERO_LEN:
1400                 bss_cfg->bcast_ssid_ctl = 0;
1401                 break;
1402         case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
1403                 /* firmware doesn't support this type of hidden SSID */
1404         default:
1405                 kfree(bss_cfg);
1406                 return -EINVAL;
1407         }
1408
1409         bss_cfg->channel = ieee80211_frequency_to_channel(
1410                                 params->chandef.chan->center_freq);
1411
1412         /* Set appropriate bands */
1413         if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1414                 bss_cfg->band_cfg = BAND_CONFIG_BG;
1415                 config_bands = BAND_B | BAND_G;
1416
1417                 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1418                         config_bands |= BAND_GN;
1419         } else {
1420                 bss_cfg->band_cfg = BAND_CONFIG_A;
1421                 config_bands = BAND_A;
1422
1423                 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1424                         config_bands |= BAND_AN;
1425
1426                 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1427                         config_bands |= BAND_AAC;
1428         }
1429
1430         if (!((config_bands | priv->adapter->fw_bands) &
1431               ~priv->adapter->fw_bands))
1432                 priv->adapter->config_bands = config_bands;
1433
1434         mwifiex_set_uap_rates(bss_cfg, params);
1435         mwifiex_send_domain_info_cmd_fw(wiphy);
1436
1437         if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
1438                 kfree(bss_cfg);
1439                 wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
1440                 return -1;
1441         }
1442
1443         mwifiex_set_ht_params(priv, bss_cfg, params);
1444
1445         if (priv->adapter->is_hw_11ac_capable) {
1446                 mwifiex_set_vht_params(priv, bss_cfg, params);
1447                 mwifiex_set_vht_width(priv, params->chandef.width,
1448                                       priv->ap_11ac_enabled);
1449         }
1450
1451         if (priv->ap_11ac_enabled)
1452                 mwifiex_set_11ac_ba_params(priv);
1453         else
1454                 mwifiex_set_ba_params(priv);
1455
1456         mwifiex_set_wmm_params(priv, bss_cfg, params);
1457
1458         if (params->inactivity_timeout > 0) {
1459                 /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */
1460                 bss_cfg->sta_ao_timer = 10 * params->inactivity_timeout;
1461                 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout;
1462         }
1463
1464         if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1465                              HostCmd_ACT_GEN_SET, 0, NULL, true)) {
1466                 wiphy_err(wiphy, "Failed to stop the BSS\n");
1467                 kfree(bss_cfg);
1468                 return -1;
1469         }
1470
1471         if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
1472                              HostCmd_ACT_GEN_SET,
1473                              UAP_BSS_PARAMS_I, bss_cfg, false)) {
1474                 wiphy_err(wiphy, "Failed to set the SSID\n");
1475                 kfree(bss_cfg);
1476                 return -1;
1477         }
1478
1479         kfree(bss_cfg);
1480
1481         if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
1482                              HostCmd_ACT_GEN_SET, 0, NULL, false)) {
1483                 wiphy_err(wiphy, "Failed to start the BSS\n");
1484                 return -1;
1485         }
1486
1487         if (priv->sec_info.wep_enabled)
1488                 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
1489         else
1490                 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1491
1492         if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1493                              HostCmd_ACT_GEN_SET, 0,
1494                              &priv->curr_pkt_filter, true))
1495                 return -1;
1496
1497         return 0;
1498 }
1499
1500 /*
1501  * CFG802.11 operation handler for disconnection request.
1502  *
1503  * This function does not work when there is already a disconnection
1504  * procedure going on.
1505  */
1506 static int
1507 mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1508                             u16 reason_code)
1509 {
1510         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1511
1512         if (mwifiex_deauthenticate(priv, NULL))
1513                 return -EFAULT;
1514
1515         wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
1516                 " reason code %d\n", priv->cfg_bssid, reason_code);
1517
1518         memset(priv->cfg_bssid, 0, ETH_ALEN);
1519         priv->hs2_enabled = false;
1520
1521         return 0;
1522 }
1523
1524 /*
1525  * This function informs the CFG802.11 subsystem of a new IBSS.
1526  *
1527  * The following information are sent to the CFG802.11 subsystem
1528  * to register the new IBSS. If we do not register the new IBSS,
1529  * a kernel panic will result.
1530  *      - SSID
1531  *      - SSID length
1532  *      - BSSID
1533  *      - Channel
1534  */
1535 static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
1536 {
1537         struct ieee80211_channel *chan;
1538         struct mwifiex_bss_info bss_info;
1539         struct cfg80211_bss *bss;
1540         int ie_len;
1541         u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
1542         enum ieee80211_band band;
1543
1544         if (mwifiex_get_bss_info(priv, &bss_info))
1545                 return -1;
1546
1547         ie_buf[0] = WLAN_EID_SSID;
1548         ie_buf[1] = bss_info.ssid.ssid_len;
1549
1550         memcpy(&ie_buf[sizeof(struct ieee_types_header)],
1551                &bss_info.ssid.ssid, bss_info.ssid.ssid_len);
1552         ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
1553
1554         band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
1555         chan = __ieee80211_get_channel(priv->wdev->wiphy,
1556                         ieee80211_channel_to_frequency(bss_info.bss_chan,
1557                                                        band));
1558
1559         bss = cfg80211_inform_bss(priv->wdev->wiphy, chan,
1560                                   CFG80211_BSS_FTYPE_UNKNOWN,
1561                                   bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
1562                                   0, ie_buf, ie_len, 0, GFP_KERNEL);
1563         cfg80211_put_bss(priv->wdev->wiphy, bss);
1564         memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
1565
1566         return 0;
1567 }
1568
1569 /*
1570  * This function connects with a BSS.
1571  *
1572  * This function handles both Infra and Ad-Hoc modes. It also performs
1573  * validity checking on the provided parameters, disconnects from the
1574  * current BSS (if any), sets up the association/scan parameters,
1575  * including security settings, and performs specific SSID scan before
1576  * trying to connect.
1577  *
1578  * For Infra mode, the function returns failure if the specified SSID
1579  * is not found in scan table. However, for Ad-Hoc mode, it can create
1580  * the IBSS if it does not exist. On successful completion in either case,
1581  * the function notifies the CFG802.11 subsystem of the new BSS connection.
1582  */
1583 static int
1584 mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
1585                        const u8 *ssid, const u8 *bssid, int mode,
1586                        struct ieee80211_channel *channel,
1587                        struct cfg80211_connect_params *sme, bool privacy)
1588 {
1589         struct cfg80211_ssid req_ssid;
1590         int ret, auth_type = 0;
1591         struct cfg80211_bss *bss = NULL;
1592         u8 is_scanning_required = 0;
1593
1594         memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
1595
1596         req_ssid.ssid_len = ssid_len;
1597         if (ssid_len > IEEE80211_MAX_SSID_LEN) {
1598                 dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
1599                 return -EINVAL;
1600         }
1601
1602         memcpy(req_ssid.ssid, ssid, ssid_len);
1603         if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
1604                 dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
1605                 return -EINVAL;
1606         }
1607
1608         /* As this is new association, clear locally stored
1609          * keys and security related flags */
1610         priv->sec_info.wpa_enabled = false;
1611         priv->sec_info.wpa2_enabled = false;
1612         priv->wep_key_curr_index = 0;
1613         priv->sec_info.encryption_mode = 0;
1614         priv->sec_info.is_authtype_auto = 0;
1615         ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
1616
1617         if (mode == NL80211_IFTYPE_ADHOC) {
1618                 /* "privacy" is set only for ad-hoc mode */
1619                 if (privacy) {
1620                         /*
1621                          * Keep WLAN_CIPHER_SUITE_WEP104 for now so that
1622                          * the firmware can find a matching network from the
1623                          * scan. The cfg80211 does not give us the encryption
1624                          * mode at this stage so just setting it to WEP here.
1625                          */
1626                         priv->sec_info.encryption_mode =
1627                                         WLAN_CIPHER_SUITE_WEP104;
1628                         priv->sec_info.authentication_mode =
1629                                         NL80211_AUTHTYPE_OPEN_SYSTEM;
1630                 }
1631
1632                 goto done;
1633         }
1634
1635         /* Now handle infra mode. "sme" is valid for infra mode only */
1636         if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
1637                 auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1638                 priv->sec_info.is_authtype_auto = 1;
1639         } else {
1640                 auth_type = sme->auth_type;
1641         }
1642
1643         if (sme->crypto.n_ciphers_pairwise) {
1644                 priv->sec_info.encryption_mode =
1645                                                 sme->crypto.ciphers_pairwise[0];
1646                 priv->sec_info.authentication_mode = auth_type;
1647         }
1648
1649         if (sme->crypto.cipher_group) {
1650                 priv->sec_info.encryption_mode = sme->crypto.cipher_group;
1651                 priv->sec_info.authentication_mode = auth_type;
1652         }
1653         if (sme->ie)
1654                 ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
1655
1656         if (sme->key) {
1657                 if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) {
1658                         dev_dbg(priv->adapter->dev,
1659                                 "info: setting wep encryption"
1660                                 " with key len %d\n", sme->key_len);
1661                         priv->wep_key_curr_index = sme->key_idx;
1662                         ret = mwifiex_set_encode(priv, NULL, sme->key,
1663                                                  sme->key_len, sme->key_idx,
1664                                                  NULL, 0);
1665                 }
1666         }
1667 done:
1668         /*
1669          * Scan entries are valid for some time (15 sec). So we can save one
1670          * active scan time if we just try cfg80211_get_bss first. If it fails
1671          * then request scan and cfg80211_get_bss() again for final output.
1672          */
1673         while (1) {
1674                 if (is_scanning_required) {
1675                         /* Do specific SSID scanning */
1676                         if (mwifiex_request_scan(priv, &req_ssid)) {
1677                                 dev_err(priv->adapter->dev, "scan error\n");
1678                                 return -EFAULT;
1679                         }
1680                 }
1681
1682                 /* Find the BSS we want using available scan results */
1683                 if (mode == NL80211_IFTYPE_ADHOC)
1684                         bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1685                                                bssid, ssid, ssid_len,
1686                                                WLAN_CAPABILITY_IBSS,
1687                                                WLAN_CAPABILITY_IBSS);
1688                 else
1689                         bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1690                                                bssid, ssid, ssid_len,
1691                                                WLAN_CAPABILITY_ESS,
1692                                                WLAN_CAPABILITY_ESS);
1693
1694                 if (!bss) {
1695                         if (is_scanning_required) {
1696                                 dev_warn(priv->adapter->dev,
1697                                          "assoc: requested bss not found in scan results\n");
1698                                 break;
1699                         }
1700                         is_scanning_required = 1;
1701                 } else {
1702                         dev_dbg(priv->adapter->dev,
1703                                 "info: trying to associate to '%s' bssid %pM\n",
1704                                 (char *) req_ssid.ssid, bss->bssid);
1705                         memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
1706                         break;
1707                 }
1708         }
1709
1710         ret = mwifiex_bss_start(priv, bss, &req_ssid);
1711         if (ret)
1712                 return ret;
1713
1714         if (mode == NL80211_IFTYPE_ADHOC) {
1715                 /* Inform the BSS information to kernel, otherwise
1716                  * kernel will give a panic after successful assoc */
1717                 if (mwifiex_cfg80211_inform_ibss_bss(priv))
1718                         return -EFAULT;
1719         }
1720
1721         return ret;
1722 }
1723
1724 /*
1725  * CFG802.11 operation handler for association request.
1726  *
1727  * This function does not work when the current mode is set to Ad-Hoc, or
1728  * when there is already an association procedure going on. The given BSS
1729  * information is used to associate.
1730  */
1731 static int
1732 mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1733                          struct cfg80211_connect_params *sme)
1734 {
1735         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1736         int ret;
1737
1738         if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
1739                 wiphy_err(wiphy,
1740                           "%s: reject infra assoc request in non-STA role\n",
1741                           dev->name);
1742                 return -EINVAL;
1743         }
1744
1745         if (priv->wdev && priv->wdev->current_bss) {
1746                 wiphy_warn(wiphy, "%s: already connected\n", dev->name);
1747                 return -EALREADY;
1748         }
1749
1750         wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1751                   (char *) sme->ssid, sme->bssid);
1752
1753         ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
1754                                      priv->bss_mode, sme->channel, sme, 0);
1755         if (!ret) {
1756                 cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
1757                                         NULL, 0, WLAN_STATUS_SUCCESS,
1758                                         GFP_KERNEL);
1759                 dev_dbg(priv->adapter->dev,
1760                         "info: associated to bssid %pM successfully\n",
1761                         priv->cfg_bssid);
1762         } else {
1763                 dev_dbg(priv->adapter->dev,
1764                         "info: association to bssid %pM failed\n",
1765                         priv->cfg_bssid);
1766                 memset(priv->cfg_bssid, 0, ETH_ALEN);
1767
1768                 if (ret > 0)
1769                         cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
1770                                                 NULL, 0, NULL, 0, ret,
1771                                                 GFP_KERNEL);
1772                 else
1773                         cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
1774                                                 NULL, 0, NULL, 0,
1775                                                 WLAN_STATUS_UNSPECIFIED_FAILURE,
1776                                                 GFP_KERNEL);
1777         }
1778
1779         return 0;
1780 }
1781
1782 /*
1783  * This function sets following parameters for ibss network.
1784  *  -  channel
1785  *  -  start band
1786  *  -  11n flag
1787  *  -  secondary channel offset
1788  */
1789 static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1790                                    struct cfg80211_ibss_params *params)
1791 {
1792         struct wiphy *wiphy = priv->wdev->wiphy;
1793         struct mwifiex_adapter *adapter = priv->adapter;
1794         int index = 0, i;
1795         u8 config_bands = 0;
1796
1797         if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1798                 if (!params->basic_rates) {
1799                         config_bands = BAND_B | BAND_G;
1800                 } else {
1801                         for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) {
1802                                 /*
1803                                  * Rates below 6 Mbps in the table are CCK
1804                                  * rates; 802.11b and from 6 they are OFDM;
1805                                  * 802.11G
1806                                  */
1807                                 if (mwifiex_rates[i].bitrate == 60) {
1808                                         index = 1 << i;
1809                                         break;
1810                                 }
1811                         }
1812
1813                         if (params->basic_rates < index) {
1814                                 config_bands = BAND_B;
1815                         } else {
1816                                 config_bands = BAND_G;
1817                                 if (params->basic_rates % index)
1818                                         config_bands |= BAND_B;
1819                         }
1820                 }
1821
1822                 if (cfg80211_get_chandef_type(&params->chandef) !=
1823                                                 NL80211_CHAN_NO_HT)
1824                         config_bands |= BAND_G | BAND_GN;
1825         } else {
1826                 if (cfg80211_get_chandef_type(&params->chandef) ==
1827                                                 NL80211_CHAN_NO_HT)
1828                         config_bands = BAND_A;
1829                 else
1830                         config_bands = BAND_AN | BAND_A;
1831         }
1832
1833         if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) {
1834                 adapter->config_bands = config_bands;
1835                 adapter->adhoc_start_band = config_bands;
1836
1837                 if ((config_bands & BAND_GN) || (config_bands & BAND_AN))
1838                         adapter->adhoc_11n_enabled = true;
1839                 else
1840                         adapter->adhoc_11n_enabled = false;
1841         }
1842
1843         adapter->sec_chan_offset =
1844                 mwifiex_chan_type_to_sec_chan_offset(
1845                         cfg80211_get_chandef_type(&params->chandef));
1846         priv->adhoc_channel = ieee80211_frequency_to_channel(
1847                                 params->chandef.chan->center_freq);
1848
1849         wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n",
1850                   config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
1851
1852         return 0;
1853 }
1854
1855 /*
1856  * CFG802.11 operation handler to join an IBSS.
1857  *
1858  * This function does not work in any mode other than Ad-Hoc, or if
1859  * a join operation is already in progress.
1860  */
1861 static int
1862 mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1863                            struct cfg80211_ibss_params *params)
1864 {
1865         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1866         int ret = 0;
1867
1868         if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
1869                 wiphy_err(wiphy, "request to join ibss received "
1870                                 "when station is not in ibss mode\n");
1871                 goto done;
1872         }
1873
1874         wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
1875                   (char *) params->ssid, params->bssid);
1876
1877         mwifiex_set_ibss_params(priv, params);
1878
1879         ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1880                                      params->bssid, priv->bss_mode,
1881                                      params->chandef.chan, NULL,
1882                                      params->privacy);
1883 done:
1884         if (!ret) {
1885                 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
1886                                      params->chandef.chan, GFP_KERNEL);
1887                 dev_dbg(priv->adapter->dev,
1888                         "info: joined/created adhoc network with bssid"
1889                         " %pM successfully\n", priv->cfg_bssid);
1890         } else {
1891                 dev_dbg(priv->adapter->dev,
1892                         "info: failed creating/joining adhoc network\n");
1893         }
1894
1895         return ret;
1896 }
1897
1898 /*
1899  * CFG802.11 operation handler to leave an IBSS.
1900  *
1901  * This function does not work if a leave operation is
1902  * already in progress.
1903  */
1904 static int
1905 mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1906 {
1907         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1908
1909         wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
1910                   priv->cfg_bssid);
1911         if (mwifiex_deauthenticate(priv, NULL))
1912                 return -EFAULT;
1913
1914         memset(priv->cfg_bssid, 0, ETH_ALEN);
1915
1916         return 0;
1917 }
1918
1919 /*
1920  * CFG802.11 operation handler for scan request.
1921  *
1922  * This function issues a scan request to the firmware based upon
1923  * the user specified scan configuration. On successfull completion,
1924  * it also informs the results.
1925  */
1926 static int
1927 mwifiex_cfg80211_scan(struct wiphy *wiphy,
1928                       struct cfg80211_scan_request *request)
1929 {
1930         struct net_device *dev = request->wdev->netdev;
1931         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1932         int i, offset, ret;
1933         struct ieee80211_channel *chan;
1934         struct ieee_types_header *ie;
1935         struct mwifiex_user_scan_cfg *user_scan_cfg;
1936
1937         wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1938
1939         /* Block scan request if scan operation or scan cleanup when interface
1940          * is disabled is in process
1941          */
1942         if (priv->scan_request || priv->scan_aborting) {
1943                 dev_err(priv->adapter->dev, "cmd: Scan already in process..\n");
1944                 return -EBUSY;
1945         }
1946
1947         user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
1948         if (!user_scan_cfg)
1949                 return -ENOMEM;
1950
1951         priv->scan_request = request;
1952
1953         user_scan_cfg->num_ssids = request->n_ssids;
1954         user_scan_cfg->ssid_list = request->ssids;
1955
1956         if (request->ie && request->ie_len) {
1957                 offset = 0;
1958                 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
1959                         if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR)
1960                                 continue;
1961                         priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN;
1962                         ie = (struct ieee_types_header *)(request->ie + offset);
1963                         memcpy(&priv->vs_ie[i].ie, ie, sizeof(*ie) + ie->len);
1964                         offset += sizeof(*ie) + ie->len;
1965
1966                         if (offset >= request->ie_len)
1967                                 break;
1968                 }
1969         }
1970
1971         for (i = 0; i < min_t(u32, request->n_channels,
1972                               MWIFIEX_USER_SCAN_CHAN_MAX); i++) {
1973                 chan = request->channels[i];
1974                 user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1975                 user_scan_cfg->chan_list[i].radio_type = chan->band;
1976
1977                 if ((chan->flags & IEEE80211_CHAN_NO_IR) || !request->n_ssids)
1978                         user_scan_cfg->chan_list[i].scan_type =
1979                                                 MWIFIEX_SCAN_TYPE_PASSIVE;
1980                 else
1981                         user_scan_cfg->chan_list[i].scan_type =
1982                                                 MWIFIEX_SCAN_TYPE_ACTIVE;
1983
1984                 user_scan_cfg->chan_list[i].scan_time = 0;
1985         }
1986
1987         if (priv->adapter->scan_chan_gap_enabled &&
1988             mwifiex_is_any_intf_active(priv))
1989                 user_scan_cfg->scan_chan_gap =
1990                                               priv->adapter->scan_chan_gap_time;
1991
1992         ret = mwifiex_scan_networks(priv, user_scan_cfg);
1993         kfree(user_scan_cfg);
1994         if (ret) {
1995                 dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
1996                 priv->scan_aborting = false;
1997                 priv->scan_request = NULL;
1998                 return ret;
1999         }
2000
2001         if (request->ie && request->ie_len) {
2002                 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
2003                         if (priv->vs_ie[i].mask == MWIFIEX_VSIE_MASK_SCAN) {
2004                                 priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_CLEAR;
2005                                 memset(&priv->vs_ie[i].ie, 0,
2006                                        MWIFIEX_MAX_VSIE_LEN);
2007                         }
2008                 }
2009         }
2010         return 0;
2011 }
2012
2013 static void mwifiex_setup_vht_caps(struct ieee80211_sta_vht_cap *vht_info,
2014                                    struct mwifiex_private *priv)
2015 {
2016         struct mwifiex_adapter *adapter = priv->adapter;
2017
2018         vht_info->vht_supported = true;
2019
2020         vht_info->cap = adapter->hw_dot_11ac_dev_cap;
2021         /* Update MCS support for VHT */
2022         vht_info->vht_mcs.rx_mcs_map = cpu_to_le16(
2023                                 adapter->hw_dot_11ac_mcs_support & 0xFFFF);
2024         vht_info->vht_mcs.rx_highest = 0;
2025         vht_info->vht_mcs.tx_mcs_map = cpu_to_le16(
2026                                 adapter->hw_dot_11ac_mcs_support >> 16);
2027         vht_info->vht_mcs.tx_highest = 0;
2028 }
2029
2030 /*
2031  * This function sets up the CFG802.11 specific HT capability fields
2032  * with default values.
2033  *
2034  * The following default values are set -
2035  *      - HT Supported = True
2036  *      - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K
2037  *      - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE
2038  *      - HT Capabilities supported by firmware
2039  *      - MCS information, Rx mask = 0xff
2040  *      - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01)
2041  */
2042 static void
2043 mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2044                       struct mwifiex_private *priv)
2045 {
2046         int rx_mcs_supp;
2047         struct ieee80211_mcs_info mcs_set;
2048         u8 *mcs = (u8 *)&mcs_set;
2049         struct mwifiex_adapter *adapter = priv->adapter;
2050
2051         ht_info->ht_supported = true;
2052         ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
2053         ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2054
2055         memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
2056
2057         /* Fill HT capability information */
2058         if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
2059                 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
2060         else
2061                 ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
2062
2063         if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap))
2064                 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
2065         else
2066                 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20;
2067
2068         if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap))
2069                 ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
2070         else
2071                 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40;
2072
2073         if (adapter->user_dev_mcs_support == HT_STREAM_2X2)
2074                 ht_info->cap |= 3 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
2075         else
2076                 ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
2077
2078         if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap))
2079                 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
2080         else
2081                 ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC;
2082
2083         if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap))
2084                 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
2085         else
2086                 ht_info->cap &= ~IEEE80211_HT_CAP_GRN_FLD;
2087
2088         if (ISENABLED_40MHZ_INTOLERANT(adapter->hw_dot_11n_dev_cap))
2089                 ht_info->cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
2090         else
2091                 ht_info->cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT;
2092
2093         if (ISSUPP_RXLDPC(adapter->hw_dot_11n_dev_cap))
2094                 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
2095         else
2096                 ht_info->cap &= ~IEEE80211_HT_CAP_LDPC_CODING;
2097
2098         ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
2099         ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
2100
2101         rx_mcs_supp = GET_RXMCSSUPP(adapter->user_dev_mcs_support);
2102         /* Set MCS for 1x1/2x2 */
2103         memset(mcs, 0xff, rx_mcs_supp);
2104         /* Clear all the other values */
2105         memset(&mcs[rx_mcs_supp], 0,
2106                sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
2107         if (priv->bss_mode == NL80211_IFTYPE_STATION ||
2108             ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
2109                 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
2110                 SETHT_MCS32(mcs_set.rx_mask);
2111
2112         memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info));
2113
2114         ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2115 }
2116
2117 /*
2118  *  create a new virtual interface with the given name
2119  */
2120 struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2121                                               const char *name,
2122                                               enum nl80211_iftype type,
2123                                               u32 *flags,
2124                                               struct vif_params *params)
2125 {
2126         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2127         struct mwifiex_private *priv;
2128         struct net_device *dev;
2129         void *mdev_priv;
2130         struct wireless_dev *wdev;
2131
2132         if (!adapter)
2133                 return ERR_PTR(-EFAULT);
2134
2135         switch (type) {
2136         case NL80211_IFTYPE_UNSPECIFIED:
2137         case NL80211_IFTYPE_STATION:
2138         case NL80211_IFTYPE_ADHOC:
2139                 priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
2140                 if (priv->bss_mode) {
2141                         wiphy_err(wiphy,
2142                                   "cannot create multiple sta/adhoc ifaces\n");
2143                         return ERR_PTR(-EINVAL);
2144                 }
2145
2146                 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2147                 if (!wdev)
2148                         return ERR_PTR(-ENOMEM);
2149
2150                 wdev->wiphy = wiphy;
2151                 priv->wdev = wdev;
2152                 wdev->iftype = NL80211_IFTYPE_STATION;
2153
2154                 if (type == NL80211_IFTYPE_UNSPECIFIED)
2155                         priv->bss_mode = NL80211_IFTYPE_STATION;
2156                 else
2157                         priv->bss_mode = type;
2158
2159                 priv->bss_type = MWIFIEX_BSS_TYPE_STA;
2160                 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
2161                 priv->bss_priority = 0;
2162                 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
2163                 priv->bss_num = 0;
2164
2165                 break;
2166         case NL80211_IFTYPE_AP:
2167                 priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP];
2168
2169                 if (priv->bss_mode) {
2170                         wiphy_err(wiphy, "Can't create multiple AP interfaces");
2171                         return ERR_PTR(-EINVAL);
2172                 }
2173
2174                 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2175                 if (!wdev)
2176                         return ERR_PTR(-ENOMEM);
2177
2178                 priv->wdev = wdev;
2179                 wdev->wiphy = wiphy;
2180                 wdev->iftype = NL80211_IFTYPE_AP;
2181
2182                 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
2183                 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
2184                 priv->bss_priority = 0;
2185                 priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
2186                 priv->bss_started = 0;
2187                 priv->bss_num = 0;
2188                 priv->bss_mode = type;
2189
2190                 break;
2191         case NL80211_IFTYPE_P2P_CLIENT:
2192                 priv = adapter->priv[MWIFIEX_BSS_TYPE_P2P];
2193
2194                 if (priv->bss_mode) {
2195                         wiphy_err(wiphy, "Can't create multiple P2P ifaces");
2196                         return ERR_PTR(-EINVAL);
2197                 }
2198
2199                 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2200                 if (!wdev)
2201                         return ERR_PTR(-ENOMEM);
2202
2203                 priv->wdev = wdev;
2204                 wdev->wiphy = wiphy;
2205
2206                 /* At start-up, wpa_supplicant tries to change the interface
2207                  * to NL80211_IFTYPE_STATION if it is not managed mode.
2208                  */
2209                 wdev->iftype = NL80211_IFTYPE_P2P_CLIENT;
2210                 priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT;
2211
2212                 /* Setting bss_type to P2P tells firmware that this interface
2213                  * is receiving P2P peers found during find phase and doing
2214                  * action frame handshake.
2215                  */
2216                 priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
2217
2218                 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
2219                 priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
2220                 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
2221                 priv->bss_started = 0;
2222                 priv->bss_num = 0;
2223
2224                 if (mwifiex_cfg80211_init_p2p_client(priv)) {
2225                         wdev = ERR_PTR(-EFAULT);
2226                         goto done;
2227                 }
2228
2229                 break;
2230         default:
2231                 wiphy_err(wiphy, "type not supported\n");
2232                 return ERR_PTR(-EINVAL);
2233         }
2234
2235         dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name,
2236                                NET_NAME_UNKNOWN, ether_setup,
2237                                IEEE80211_NUM_ACS, 1);
2238         if (!dev) {
2239                 wiphy_err(wiphy, "no memory available for netdevice\n");
2240                 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2241                 wdev = ERR_PTR(-ENOMEM);
2242                 goto done;
2243         }
2244
2245         mwifiex_init_priv_params(priv, dev);
2246         priv->netdev = dev;
2247
2248         mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
2249         if (adapter->is_hw_11ac_capable)
2250                 mwifiex_setup_vht_caps(
2251                         &wiphy->bands[IEEE80211_BAND_2GHZ]->vht_cap, priv);
2252
2253         if (adapter->config_bands & BAND_A)
2254                 mwifiex_setup_ht_caps(
2255                         &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
2256
2257         if ((adapter->config_bands & BAND_A) && adapter->is_hw_11ac_capable)
2258                 mwifiex_setup_vht_caps(
2259                         &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv);
2260
2261         dev_net_set(dev, wiphy_net(wiphy));
2262         dev->ieee80211_ptr = priv->wdev;
2263         dev->ieee80211_ptr->iftype = priv->bss_mode;
2264         memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
2265         SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
2266
2267         dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
2268         dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
2269         dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
2270         dev->ethtool_ops = &mwifiex_ethtool_ops;
2271
2272         mdev_priv = netdev_priv(dev);
2273         *((unsigned long *) mdev_priv) = (unsigned long) priv;
2274
2275         SET_NETDEV_DEV(dev, adapter->dev);
2276
2277         /* Register network device */
2278         if (register_netdevice(dev)) {
2279                 wiphy_err(wiphy, "cannot register virtual network device\n");
2280                 free_netdev(dev);
2281                 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2282                 priv->netdev = NULL;
2283                 wdev = ERR_PTR(-EFAULT);
2284                 goto done;
2285         }
2286
2287         sema_init(&priv->async_sem, 1);
2288
2289         dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
2290
2291 #ifdef CONFIG_DEBUG_FS
2292         mwifiex_dev_debugfs_init(priv);
2293 #endif
2294
2295 done:
2296         if (IS_ERR(wdev)) {
2297                 kfree(priv->wdev);
2298                 priv->wdev = NULL;
2299         }
2300
2301         return wdev;
2302 }
2303 EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
2304
2305 /*
2306  * del_virtual_intf: remove the virtual interface determined by dev
2307  */
2308 int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2309 {
2310         struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
2311
2312 #ifdef CONFIG_DEBUG_FS
2313         mwifiex_dev_debugfs_remove(priv);
2314 #endif
2315
2316         mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
2317
2318         if (netif_carrier_ok(priv->netdev))
2319                 netif_carrier_off(priv->netdev);
2320
2321         if (wdev->netdev->reg_state == NETREG_REGISTERED)
2322                 unregister_netdevice(wdev->netdev);
2323
2324         /* Clear the priv in adapter */
2325         priv->netdev->ieee80211_ptr = NULL;
2326         priv->netdev = NULL;
2327         kfree(wdev);
2328         priv->wdev = NULL;
2329
2330         priv->media_connected = false;
2331
2332         priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2333
2334         return 0;
2335 }
2336 EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
2337
2338 static bool
2339 mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
2340                              u8 max_byte_seq)
2341 {
2342         int j, k, valid_byte_cnt = 0;
2343         bool dont_care_byte = false;
2344
2345         for (j = 0; j < DIV_ROUND_UP(pat->pattern_len, 8); j++) {
2346                 for (k = 0; k < 8; k++) {
2347                         if (pat->mask[j] & 1 << k) {
2348                                 memcpy(byte_seq + valid_byte_cnt,
2349                                        &pat->pattern[j * 8 + k], 1);
2350                                 valid_byte_cnt++;
2351                                 if (dont_care_byte)
2352                                         return false;
2353                         } else {
2354                                 if (valid_byte_cnt)
2355                                         dont_care_byte = true;
2356                         }
2357
2358                         if (valid_byte_cnt > max_byte_seq)
2359                                 return false;
2360                 }
2361         }
2362
2363         byte_seq[max_byte_seq] = valid_byte_cnt;
2364
2365         return true;
2366 }
2367
2368 #ifdef CONFIG_PM
2369 static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2370                                     struct cfg80211_wowlan *wowlan)
2371 {
2372         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2373         struct mwifiex_ds_mef_cfg mef_cfg;
2374         struct mwifiex_mef_entry *mef_entry;
2375         int i, filt_num = 0, ret;
2376         bool first_pat = true;
2377         u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
2378         const u8 ipv4_mc_mac[] = {0x33, 0x33};
2379         const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
2380         struct mwifiex_private *priv =
2381                         mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
2382
2383         if (!wowlan) {
2384                 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2385                 return 0;
2386         }
2387
2388         if (!priv->media_connected) {
2389                 dev_warn(adapter->dev,
2390                          "Can not configure WOWLAN in disconnected state\n");
2391                 return 0;
2392         }
2393
2394         mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL);
2395         if (!mef_entry)
2396                 return -ENOMEM;
2397
2398         memset(&mef_cfg, 0, sizeof(mef_cfg));
2399         mef_cfg.num_entries = 1;
2400         mef_cfg.mef_entry = mef_entry;
2401         mef_entry->mode = MEF_MODE_HOST_SLEEP;
2402         mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST;
2403
2404         for (i = 0; i < wowlan->n_patterns; i++) {
2405                 memset(byte_seq, 0, sizeof(byte_seq));
2406                 if (!mwifiex_is_pattern_supported(&wowlan->patterns[i],
2407                                                   byte_seq,
2408                                                   MWIFIEX_MEF_MAX_BYTESEQ)) {
2409                         wiphy_err(wiphy, "Pattern not supported\n");
2410                         kfree(mef_entry);
2411                         return -EOPNOTSUPP;
2412                 }
2413
2414                 if (!wowlan->patterns[i].pkt_offset) {
2415                         if (!(byte_seq[0] & 0x01) &&
2416                             (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 1)) {
2417                                 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST;
2418                                 continue;
2419                         } else if (is_broadcast_ether_addr(byte_seq)) {
2420                                 mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST;
2421                                 continue;
2422                         } else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) &&
2423                                     (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 2)) ||
2424                                    (!memcmp(byte_seq, ipv6_mc_mac, 3) &&
2425                                     (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 3))) {
2426                                 mef_cfg.criteria |= MWIFIEX_CRITERIA_MULTICAST;
2427                                 continue;
2428                         }
2429                 }
2430
2431                 mef_entry->filter[filt_num].repeat = 1;
2432                 mef_entry->filter[filt_num].offset =
2433                                                 wowlan->patterns[i].pkt_offset;
2434                 memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq,
2435                        sizeof(byte_seq));
2436                 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2437
2438                 if (first_pat)
2439                         first_pat = false;
2440                 else
2441                         mef_entry->filter[filt_num].filt_action = TYPE_AND;
2442
2443                 filt_num++;
2444         }
2445
2446         if (wowlan->magic_pkt) {
2447                 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST;
2448                 mef_entry->filter[filt_num].repeat = 16;
2449                 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2450                        ETH_ALEN);
2451                 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2452                                                                 ETH_ALEN;
2453                 mef_entry->filter[filt_num].offset = 28;
2454                 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2455                 if (filt_num)
2456                         mef_entry->filter[filt_num].filt_action = TYPE_OR;
2457
2458                 filt_num++;
2459                 mef_entry->filter[filt_num].repeat = 16;
2460                 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2461                        ETH_ALEN);
2462                 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2463                                                                 ETH_ALEN;
2464                 mef_entry->filter[filt_num].offset = 56;
2465                 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2466                 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2467         }
2468
2469         if (!mef_cfg.criteria)
2470                 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
2471                                    MWIFIEX_CRITERIA_UNICAST |
2472                                    MWIFIEX_CRITERIA_MULTICAST;
2473
2474         ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
2475                                HostCmd_ACT_GEN_SET, 0, &mef_cfg, true);
2476
2477         kfree(mef_entry);
2478         return ret;
2479 }
2480
2481 static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
2482 {
2483         return 0;
2484 }
2485
2486 static void mwifiex_cfg80211_set_wakeup(struct wiphy *wiphy,
2487                                        bool enabled)
2488 {
2489         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2490
2491         device_set_wakeup_enable(adapter->dev, enabled);
2492 }
2493 #endif
2494
2495 static int mwifiex_get_coalesce_pkt_type(u8 *byte_seq)
2496 {
2497         const u8 ipv4_mc_mac[] = {0x33, 0x33};
2498         const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
2499         const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff};
2500
2501         if ((byte_seq[0] & 0x01) &&
2502             (byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 1))
2503                 return PACKET_TYPE_UNICAST;
2504         else if (!memcmp(byte_seq, bc_mac, 4))
2505                 return PACKET_TYPE_BROADCAST;
2506         else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) &&
2507                   byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 2) ||
2508                  (!memcmp(byte_seq, ipv6_mc_mac, 3) &&
2509                   byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 3))
2510                 return PACKET_TYPE_MULTICAST;
2511
2512         return 0;
2513 }
2514
2515 static int
2516 mwifiex_fill_coalesce_rule_info(struct mwifiex_private *priv,
2517                                 struct cfg80211_coalesce_rules *crule,
2518                                 struct mwifiex_coalesce_rule *mrule)
2519 {
2520         u8 byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ + 1];
2521         struct filt_field_param *param;
2522         int i;
2523
2524         mrule->max_coalescing_delay = crule->delay;
2525
2526         param = mrule->params;
2527
2528         for (i = 0; i < crule->n_patterns; i++) {
2529                 memset(byte_seq, 0, sizeof(byte_seq));
2530                 if (!mwifiex_is_pattern_supported(&crule->patterns[i],
2531                                                   byte_seq,
2532                                                 MWIFIEX_COALESCE_MAX_BYTESEQ)) {
2533                         dev_err(priv->adapter->dev, "Pattern not supported\n");
2534                         return -EOPNOTSUPP;
2535                 }
2536
2537                 if (!crule->patterns[i].pkt_offset) {
2538                         u8 pkt_type;
2539
2540                         pkt_type = mwifiex_get_coalesce_pkt_type(byte_seq);
2541                         if (pkt_type && mrule->pkt_type) {
2542                                 dev_err(priv->adapter->dev,
2543                                         "Multiple packet types not allowed\n");
2544                                 return -EOPNOTSUPP;
2545                         } else if (pkt_type) {
2546                                 mrule->pkt_type = pkt_type;
2547                                 continue;
2548                         }
2549                 }
2550
2551                 if (crule->condition == NL80211_COALESCE_CONDITION_MATCH)
2552                         param->operation = RECV_FILTER_MATCH_TYPE_EQ;
2553                 else
2554                         param->operation = RECV_FILTER_MATCH_TYPE_NE;
2555
2556                 param->operand_len = byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ];
2557                 memcpy(param->operand_byte_stream, byte_seq,
2558                        param->operand_len);
2559                 param->offset = crule->patterns[i].pkt_offset;
2560                 param++;
2561
2562                 mrule->num_of_fields++;
2563         }
2564
2565         if (!mrule->pkt_type) {
2566                 dev_err(priv->adapter->dev,
2567                         "Packet type can not be determined\n");
2568                 return -EOPNOTSUPP;
2569         }
2570
2571         return 0;
2572 }
2573
2574 static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
2575                                          struct cfg80211_coalesce *coalesce)
2576 {
2577         struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2578         int i, ret;
2579         struct mwifiex_ds_coalesce_cfg coalesce_cfg;
2580         struct mwifiex_private *priv =
2581                         mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
2582
2583         memset(&coalesce_cfg, 0, sizeof(coalesce_cfg));
2584         if (!coalesce) {
2585                 dev_dbg(adapter->dev,
2586                         "Disable coalesce and reset all previous rules\n");
2587                 return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
2588                                         HostCmd_ACT_GEN_SET, 0,
2589                                         &coalesce_cfg, true);
2590         }
2591
2592         coalesce_cfg.num_of_rules = coalesce->n_rules;
2593         for (i = 0; i < coalesce->n_rules; i++) {
2594                 ret = mwifiex_fill_coalesce_rule_info(priv, &coalesce->rules[i],
2595                                                       &coalesce_cfg.rule[i]);
2596                 if (ret) {
2597                         dev_err(priv->adapter->dev,
2598                                 "Recheck the patterns provided for rule %d\n",
2599                                 i + 1);
2600                         return ret;
2601                 }
2602         }
2603
2604         return mwifiex_send_cmd(priv, HostCmd_CMD_COALESCE_CFG,
2605                                 HostCmd_ACT_GEN_SET, 0, &coalesce_cfg, true);
2606 }
2607
2608 /* cfg80211 ops handler for tdls_mgmt.
2609  * Function prepares TDLS action frame packets and forwards them to FW
2610  */
2611 static int
2612 mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
2613                            const u8 *peer, u8 action_code, u8 dialog_token,
2614                            u16 status_code, u32 peer_capability,
2615                            bool initiator, const u8 *extra_ies,
2616                            size_t extra_ies_len)
2617 {
2618         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2619         int ret;
2620
2621         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
2622                 return -ENOTSUPP;
2623
2624         /* make sure we are in station mode and connected */
2625         if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
2626                 return -ENOTSUPP;
2627
2628         switch (action_code) {
2629         case WLAN_TDLS_SETUP_REQUEST:
2630                 dev_dbg(priv->adapter->dev,
2631                         "Send TDLS Setup Request to %pM status_code=%d\n", peer,
2632                          status_code);
2633                 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2634                                                    dialog_token, status_code,
2635                                                    extra_ies, extra_ies_len);
2636                 break;
2637         case WLAN_TDLS_SETUP_RESPONSE:
2638                 dev_dbg(priv->adapter->dev,
2639                         "Send TDLS Setup Response to %pM status_code=%d\n",
2640                         peer, status_code);
2641                 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2642                                                    dialog_token, status_code,
2643                                                    extra_ies, extra_ies_len);
2644                 break;
2645         case WLAN_TDLS_SETUP_CONFIRM:
2646                 dev_dbg(priv->adapter->dev,
2647                         "Send TDLS Confirm to %pM status_code=%d\n", peer,
2648                         status_code);
2649                 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2650                                                    dialog_token, status_code,
2651                                                    extra_ies, extra_ies_len);
2652                 break;
2653         case WLAN_TDLS_TEARDOWN:
2654                 dev_dbg(priv->adapter->dev, "Send TDLS Tear down to %pM\n",
2655                         peer);
2656                 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2657                                                    dialog_token, status_code,
2658                                                    extra_ies, extra_ies_len);
2659                 break;
2660         case WLAN_TDLS_DISCOVERY_REQUEST:
2661                 dev_dbg(priv->adapter->dev,
2662                         "Send TDLS Discovery Request to %pM\n", peer);
2663                 ret = mwifiex_send_tdls_data_frame(priv, peer, action_code,
2664                                                    dialog_token, status_code,
2665                                                    extra_ies, extra_ies_len);
2666                 break;
2667         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
2668                 dev_dbg(priv->adapter->dev,
2669                         "Send TDLS Discovery Response to %pM\n", peer);
2670                 ret = mwifiex_send_tdls_action_frame(priv, peer, action_code,
2671                                                    dialog_token, status_code,
2672                                                    extra_ies, extra_ies_len);
2673                 break;
2674         default:
2675                 dev_warn(priv->adapter->dev,
2676                          "Unknown TDLS mgmt/action frame %pM\n", peer);
2677                 ret = -EINVAL;
2678                 break;
2679         }
2680
2681         return ret;
2682 }
2683
2684 static int
2685 mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
2686                            const u8 *peer, enum nl80211_tdls_operation action)
2687 {
2688         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2689
2690         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
2691             !(wiphy->flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
2692                 return -ENOTSUPP;
2693
2694         /* make sure we are in station mode and connected */
2695         if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
2696                 return -ENOTSUPP;
2697
2698         dev_dbg(priv->adapter->dev,
2699                 "TDLS peer=%pM, oper=%d\n", peer, action);
2700
2701         switch (action) {
2702         case NL80211_TDLS_ENABLE_LINK:
2703                 action = MWIFIEX_TDLS_ENABLE_LINK;
2704                 break;
2705         case NL80211_TDLS_DISABLE_LINK:
2706                 action = MWIFIEX_TDLS_DISABLE_LINK;
2707                 break;
2708         case NL80211_TDLS_TEARDOWN:
2709                 /* shouldn't happen!*/
2710                 dev_warn(priv->adapter->dev,
2711                          "tdls_oper: teardown from driver not supported\n");
2712                 return -EINVAL;
2713         case NL80211_TDLS_SETUP:
2714                 /* shouldn't happen!*/
2715                 dev_warn(priv->adapter->dev,
2716                          "tdls_oper: setup from driver not supported\n");
2717                 return -EINVAL;
2718         case NL80211_TDLS_DISCOVERY_REQ:
2719                 /* shouldn't happen!*/
2720                 dev_warn(priv->adapter->dev,
2721                          "tdls_oper: discovery from driver not supported\n");
2722                 return -EINVAL;
2723         default:
2724                 dev_err(priv->adapter->dev,
2725                         "tdls_oper: operation not supported\n");
2726                 return -ENOTSUPP;
2727         }
2728
2729         return mwifiex_tdls_oper(priv, peer, action);
2730 }
2731
2732 static int
2733 mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
2734                              const u8 *mac, struct station_parameters *params)
2735 {
2736         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2737
2738         if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2739                 return -ENOTSUPP;
2740
2741         /* make sure we are in station mode and connected */
2742         if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
2743                 return -ENOTSUPP;
2744
2745         return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK);
2746 }
2747
2748 static int
2749 mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
2750                                 const u8 *mac,
2751                                 struct station_parameters *params)
2752 {
2753         int ret;
2754         struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2755
2756         /* we support change_station handler only for TDLS peers*/
2757         if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
2758                 return -ENOTSUPP;
2759
2760         /* make sure we are in station mode and connected */
2761         if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
2762                 return -ENOTSUPP;
2763
2764         priv->sta_params = params;
2765
2766         ret = mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CONFIG_LINK);
2767         priv->sta_params = NULL;
2768
2769         return ret;
2770 }
2771
2772 /* station cfg80211 operations */
2773 static struct cfg80211_ops mwifiex_cfg80211_ops = {
2774         .add_virtual_intf = mwifiex_add_virtual_intf,
2775         .del_virtual_intf = mwifiex_del_virtual_intf,
2776         .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
2777         .scan = mwifiex_cfg80211_scan,
2778         .connect = mwifiex_cfg80211_connect,
2779         .disconnect = mwifiex_cfg80211_disconnect,
2780         .get_station = mwifiex_cfg80211_get_station,
2781         .dump_station = mwifiex_cfg80211_dump_station,
2782         .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
2783         .join_ibss = mwifiex_cfg80211_join_ibss,
2784         .leave_ibss = mwifiex_cfg80211_leave_ibss,
2785         .add_key = mwifiex_cfg80211_add_key,
2786         .del_key = mwifiex_cfg80211_del_key,
2787         .mgmt_tx = mwifiex_cfg80211_mgmt_tx,
2788         .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
2789         .remain_on_channel = mwifiex_cfg80211_remain_on_channel,
2790         .cancel_remain_on_channel = mwifiex_cfg80211_cancel_remain_on_channel,
2791         .set_default_key = mwifiex_cfg80211_set_default_key,
2792         .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
2793         .set_tx_power = mwifiex_cfg80211_set_tx_power,
2794         .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
2795         .start_ap = mwifiex_cfg80211_start_ap,
2796         .stop_ap = mwifiex_cfg80211_stop_ap,
2797         .change_beacon = mwifiex_cfg80211_change_beacon,
2798         .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
2799         .set_antenna = mwifiex_cfg80211_set_antenna,
2800         .del_station = mwifiex_cfg80211_del_station,
2801 #ifdef CONFIG_PM
2802         .suspend = mwifiex_cfg80211_suspend,
2803         .resume = mwifiex_cfg80211_resume,
2804         .set_wakeup = mwifiex_cfg80211_set_wakeup,
2805 #endif
2806         .set_coalesce = mwifiex_cfg80211_set_coalesce,
2807         .tdls_mgmt = mwifiex_cfg80211_tdls_mgmt,
2808         .tdls_oper = mwifiex_cfg80211_tdls_oper,
2809         .add_station = mwifiex_cfg80211_add_station,
2810         .change_station = mwifiex_cfg80211_change_station,
2811 };
2812
2813 #ifdef CONFIG_PM
2814 static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
2815         .flags = WIPHY_WOWLAN_MAGIC_PKT,
2816         .n_patterns = MWIFIEX_MEF_MAX_FILTERS,
2817         .pattern_min_len = 1,
2818         .pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
2819         .max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
2820 };
2821 #endif
2822
2823 static bool mwifiex_is_valid_alpha2(const char *alpha2)
2824 {
2825         if (!alpha2 || strlen(alpha2) != 2)
2826                 return false;
2827
2828         if (isalpha(alpha2[0]) && isalpha(alpha2[1]))
2829                 return true;
2830
2831         return false;
2832 }
2833
2834 static const struct wiphy_coalesce_support mwifiex_coalesce_support = {
2835         .n_rules = MWIFIEX_COALESCE_MAX_RULES,
2836         .max_delay = MWIFIEX_MAX_COALESCING_DELAY,
2837         .n_patterns = MWIFIEX_COALESCE_MAX_FILTERS,
2838         .pattern_min_len = 1,
2839         .pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
2840         .max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
2841 };
2842
2843 /*
2844  * This function registers the device with CFG802.11 subsystem.
2845  *
2846  * The function creates the wireless device/wiphy, populates it with
2847  * default parameters and handler function pointers, and finally
2848  * registers the device.
2849  */
2850
2851 int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2852 {
2853         int ret;
2854         void *wdev_priv;
2855         struct wiphy *wiphy;
2856         struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
2857         u8 *country_code;
2858         u32 thr, retry;
2859
2860         /* create a new wiphy for use with cfg80211 */
2861         wiphy = wiphy_new(&mwifiex_cfg80211_ops,
2862                           sizeof(struct mwifiex_adapter *));
2863         if (!wiphy) {
2864                 dev_err(adapter->dev, "%s: creating new wiphy\n", __func__);
2865                 return -ENOMEM;
2866         }
2867         wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
2868         wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
2869         wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
2870         wiphy->max_remain_on_channel_duration = 5000;
2871         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2872                                  BIT(NL80211_IFTYPE_ADHOC) |
2873                                  BIT(NL80211_IFTYPE_P2P_CLIENT) |
2874                                  BIT(NL80211_IFTYPE_P2P_GO) |
2875                                  BIT(NL80211_IFTYPE_AP);
2876
2877         wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
2878         if (adapter->config_bands & BAND_A)
2879                 wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
2880         else
2881                 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
2882
2883         wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta;
2884         wiphy->n_iface_combinations = 1;
2885
2886         /* Initialize cipher suits */
2887         wiphy->cipher_suites = mwifiex_cipher_suites;
2888         wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
2889
2890         memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
2891         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2892         wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
2893                         WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2894                         WIPHY_FLAG_AP_UAPSD |
2895                         WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2896
2897         if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
2898                 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2899                                 WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
2900
2901 #ifdef CONFIG_PM
2902         wiphy->wowlan = &mwifiex_wowlan_support;
2903 #endif
2904
2905         wiphy->coalesce = &mwifiex_coalesce_support;
2906
2907         wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
2908                                     NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
2909                                     NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
2910
2911         wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1;
2912         wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1;
2913
2914         wiphy->features |= NL80211_FEATURE_HT_IBSS |
2915                            NL80211_FEATURE_INACTIVITY_TIMER |
2916                            NL80211_FEATURE_NEED_OBSS_SCAN;
2917
2918         /* Reserve space for mwifiex specific private data for BSS */
2919         wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
2920
2921         wiphy->reg_notifier = mwifiex_reg_notifier;
2922
2923         /* Set struct mwifiex_adapter pointer in wiphy_priv */
2924         wdev_priv = wiphy_priv(wiphy);
2925         *(unsigned long *)wdev_priv = (unsigned long)adapter;
2926
2927         set_wiphy_dev(wiphy, priv->adapter->dev);
2928
2929         ret = wiphy_register(wiphy);
2930         if (ret < 0) {
2931                 dev_err(adapter->dev,
2932                         "%s: wiphy_register failed: %d\n", __func__, ret);
2933                 wiphy_free(wiphy);
2934                 return ret;
2935         }
2936
2937         if (reg_alpha2 && mwifiex_is_valid_alpha2(reg_alpha2)) {
2938                 wiphy_info(wiphy, "driver hint alpha2: %2.2s\n", reg_alpha2);
2939                 regulatory_hint(wiphy, reg_alpha2);
2940         } else {
2941                 country_code = mwifiex_11d_code_2_region(adapter->region_code);
2942                 if (country_code)
2943                         wiphy_info(wiphy, "ignoring F/W country code %2.2s\n",
2944                                    country_code);
2945         }
2946
2947         mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2948                          HostCmd_ACT_GEN_GET, FRAG_THRESH_I, &thr, true);
2949         wiphy->frag_threshold = thr;
2950         mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2951                          HostCmd_ACT_GEN_GET, RTS_THRESH_I, &thr, true);
2952         wiphy->rts_threshold = thr;
2953         mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2954                          HostCmd_ACT_GEN_GET, SHORT_RETRY_LIM_I, &retry, true);
2955         wiphy->retry_short = (u8) retry;
2956         mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
2957                          HostCmd_ACT_GEN_GET, LONG_RETRY_LIM_I, &retry, true);
2958         wiphy->retry_long = (u8) retry;
2959
2960         adapter->wiphy = wiphy;
2961         return ret;
2962 }