root/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cfg_scan_result
  2. cfg_connect_result
  3. wilc_get_wl_to_vif
  4. set_channel
  5. scan
  6. connect
  7. disconnect
  8. wilc_wfi_cfg_copy_wep_info
  9. wilc_wfi_cfg_allocate_wpa_entry
  10. wilc_wfi_cfg_copy_wpa_info
  11. add_key
  12. del_key
  13. get_key
  14. set_default_key
  15. get_station
  16. change_bss
  17. wilc_get_interface
  18. set_wiphy_params
  19. set_pmksa
  20. del_pmksa
  21. flush_pmksa
  22. wilc_wfi_cfg_parse_ch_attr
  23. wilc_wfi_cfg_parse_rx_action
  24. wilc_wfi_cfg_parse_tx_action
  25. wilc_wfi_cfg_parse_rx_vendor_spec
  26. wilc_wfi_p2p_rx
  27. wilc_wfi_mgmt_tx_complete
  28. wilc_wfi_remain_on_channel_expired
  29. remain_on_channel
  30. cancel_remain_on_channel
  31. wilc_wfi_cfg_tx_vendor_spec
  32. mgmt_tx
  33. mgmt_tx_cancel_wait
  34. wilc_mgmt_frame_register
  35. set_cqm_rssi_config
  36. dump_station
  37. set_power_mgmt
  38. change_virtual_intf
  39. start_ap
  40. change_beacon
  41. stop_ap
  42. add_station
  43. del_station
  44. change_station
  45. wilc_get_vif_from_type
  46. add_virtual_intf
  47. del_virtual_intf
  48. wilc_suspend
  49. wilc_resume
  50. wilc_set_wakeup
  51. set_tx_power
  52. get_tx_power
  53. wlan_init_locks
  54. wilc_cfg80211_init
  55. wilc_create_wiphy
  56. wilc_init_host_int
  57. wilc_deinit_host_int

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
   4  * All rights reserved.
   5  */
   6 
   7 #include "wilc_wfi_cfgoperations.h"
   8 
   9 #define FRAME_TYPE_ID                   0
  10 #define ACTION_CAT_ID                   24
  11 #define ACTION_SUBTYPE_ID               25
  12 #define P2P_PUB_ACTION_SUBTYPE          30
  13 
  14 #define ACTION_FRAME                    0xd0
  15 #define GO_INTENT_ATTR_ID               0x04
  16 #define CHANLIST_ATTR_ID                0x0b
  17 #define OPERCHAN_ATTR_ID                0x11
  18 #define PUB_ACTION_ATTR_ID              0x04
  19 #define P2PELEM_ATTR_ID                 0xdd
  20 
  21 #define GO_NEG_REQ                      0x00
  22 #define GO_NEG_RSP                      0x01
  23 #define GO_NEG_CONF                     0x02
  24 #define P2P_INV_REQ                     0x03
  25 #define P2P_INV_RSP                     0x04
  26 #define PUBLIC_ACT_VENDORSPEC           0x09
  27 #define GAS_INITIAL_REQ                 0x0a
  28 #define GAS_INITIAL_RSP                 0x0b
  29 
  30 #define WILC_INVALID_CHANNEL            0
  31 
  32 static const struct ieee80211_txrx_stypes
  33         wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
  34         [NL80211_IFTYPE_STATION] = {
  35                 .tx = 0xffff,
  36                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  37                         BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  38         },
  39         [NL80211_IFTYPE_AP] = {
  40                 .tx = 0xffff,
  41                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  42                         BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  43                         BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  44                         BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  45                         BIT(IEEE80211_STYPE_AUTH >> 4) |
  46                         BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  47                         BIT(IEEE80211_STYPE_ACTION >> 4)
  48         },
  49         [NL80211_IFTYPE_P2P_CLIENT] = {
  50                 .tx = 0xffff,
  51                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  52                         BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  53                         BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  54                         BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  55                         BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  56                         BIT(IEEE80211_STYPE_AUTH >> 4) |
  57                         BIT(IEEE80211_STYPE_DEAUTH >> 4)
  58         }
  59 };
  60 
  61 static const struct wiphy_wowlan_support wowlan_support = {
  62         .flags = WIPHY_WOWLAN_ANY
  63 };
  64 
  65 struct wilc_p2p_mgmt_data {
  66         int size;
  67         u8 *buff;
  68 };
  69 
  70 static const u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
  71 static const u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
  72 
  73 static void cfg_scan_result(enum scan_event scan_event,
  74                             struct wilc_rcvd_net_info *info, void *user_void)
  75 {
  76         struct wilc_priv *priv = user_void;
  77 
  78         if (!priv->cfg_scanning)
  79                 return;
  80 
  81         if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
  82                 s32 freq;
  83                 struct ieee80211_channel *channel;
  84                 struct cfg80211_bss *bss;
  85                 struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
  86 
  87                 if (!wiphy || !info)
  88                         return;
  89 
  90                 freq = ieee80211_channel_to_frequency((s32)info->ch,
  91                                                       NL80211_BAND_2GHZ);
  92                 channel = ieee80211_get_channel(wiphy, freq);
  93                 if (!channel)
  94                         return;
  95 
  96                 bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
  97                                                 info->frame_len,
  98                                                 (s32)info->rssi * 100,
  99                                                 GFP_KERNEL);
 100                 if (!bss)
 101                         cfg80211_put_bss(wiphy, bss);
 102         } else if (scan_event == SCAN_EVENT_DONE) {
 103                 mutex_lock(&priv->scan_req_lock);
 104 
 105                 if (priv->scan_req) {
 106                         struct cfg80211_scan_info info = {
 107                                 .aborted = false,
 108                         };
 109 
 110                         cfg80211_scan_done(priv->scan_req, &info);
 111                         priv->cfg_scanning = false;
 112                         priv->scan_req = NULL;
 113                 }
 114                 mutex_unlock(&priv->scan_req_lock);
 115         } else if (scan_event == SCAN_EVENT_ABORTED) {
 116                 mutex_lock(&priv->scan_req_lock);
 117 
 118                 if (priv->scan_req) {
 119                         struct cfg80211_scan_info info = {
 120                                 .aborted = false,
 121                         };
 122 
 123                         cfg80211_scan_done(priv->scan_req, &info);
 124                         priv->cfg_scanning = false;
 125                         priv->scan_req = NULL;
 126                 }
 127                 mutex_unlock(&priv->scan_req_lock);
 128         }
 129 }
 130 
 131 static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
 132                                void *priv_data)
 133 {
 134         struct wilc_priv *priv = priv_data;
 135         struct net_device *dev = priv->dev;
 136         struct wilc_vif *vif = netdev_priv(dev);
 137         struct wilc *wl = vif->wilc;
 138         struct host_if_drv *wfi_drv = priv->hif_drv;
 139         struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
 140 
 141         vif->connecting = false;
 142 
 143         if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
 144                 u16 connect_status = conn_info->status;
 145 
 146                 if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
 147                     connect_status == WLAN_STATUS_SUCCESS) {
 148                         connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
 149                         wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
 150 
 151                         if (vif->iftype != WILC_CLIENT_MODE)
 152                                 wl->sta_ch = WILC_INVALID_CHANNEL;
 153 
 154                         netdev_err(dev, "Unspecified failure\n");
 155                 }
 156 
 157                 if (connect_status == WLAN_STATUS_SUCCESS)
 158                         memcpy(priv->associated_bss, conn_info->bssid,
 159                                ETH_ALEN);
 160 
 161                 cfg80211_connect_result(dev, conn_info->bssid,
 162                                         conn_info->req_ies,
 163                                         conn_info->req_ies_len,
 164                                         conn_info->resp_ies,
 165                                         conn_info->resp_ies_len, connect_status,
 166                                         GFP_KERNEL);
 167         } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
 168                 u16 reason = 0;
 169 
 170                 priv->p2p.local_random = 0x01;
 171                 priv->p2p.recv_random = 0x00;
 172                 priv->p2p.is_wilc_ie = false;
 173                 eth_zero_addr(priv->associated_bss);
 174                 wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
 175 
 176                 if (vif->iftype != WILC_CLIENT_MODE) {
 177                         wl->sta_ch = WILC_INVALID_CHANNEL;
 178                 } else {
 179                         if (wfi_drv->ifc_up)
 180                                 reason = 3;
 181                         else
 182                                 reason = 1;
 183                 }
 184 
 185                 cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
 186         }
 187 }
 188 
 189 static struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
 190 {
 191         int i;
 192 
 193         for (i = 0; i < wl->vif_num; i++)
 194                 if (wl->vif[i])
 195                         return wl->vif[i];
 196 
 197         return ERR_PTR(-EINVAL);
 198 }
 199 
 200 static int set_channel(struct wiphy *wiphy,
 201                        struct cfg80211_chan_def *chandef)
 202 {
 203         struct wilc *wl = wiphy_priv(wiphy);
 204         struct wilc_vif *vif;
 205         u32 channelnum;
 206         int result;
 207 
 208         mutex_lock(&wl->vif_mutex);
 209         vif = wilc_get_wl_to_vif(wl);
 210         if (IS_ERR(vif)) {
 211                 mutex_unlock(&wl->vif_mutex);
 212                 return PTR_ERR(vif);
 213         }
 214 
 215         channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
 216 
 217         wl->op_ch = channelnum;
 218         result = wilc_set_mac_chnl_num(vif, channelnum);
 219         if (result)
 220                 netdev_err(vif->ndev, "Error in setting channel\n");
 221 
 222         mutex_unlock(&wl->vif_mutex);
 223         return result;
 224 }
 225 
 226 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 227 {
 228         struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
 229         struct wilc_priv *priv = &vif->priv;
 230         u32 i;
 231         int ret = 0;
 232         u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
 233         u8 scan_type;
 234 
 235         if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
 236                 netdev_err(vif->ndev, "Requested scanned channels over\n");
 237                 return -EINVAL;
 238         }
 239 
 240         priv->scan_req = request;
 241         priv->cfg_scanning = true;
 242         for (i = 0; i < request->n_channels; i++) {
 243                 u16 freq = request->channels[i]->center_freq;
 244 
 245                 scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
 246         }
 247 
 248         if (request->n_ssids)
 249                 scan_type = WILC_FW_ACTIVE_SCAN;
 250         else
 251                 scan_type = WILC_FW_PASSIVE_SCAN;
 252 
 253         ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
 254                         request->n_channels, cfg_scan_result, (void *)priv,
 255                         request);
 256 
 257         if (ret) {
 258                 priv->scan_req = NULL;
 259                 priv->cfg_scanning = false;
 260         }
 261 
 262         return ret;
 263 }
 264 
 265 static int connect(struct wiphy *wiphy, struct net_device *dev,
 266                    struct cfg80211_connect_params *sme)
 267 {
 268         struct wilc_vif *vif = netdev_priv(dev);
 269         struct wilc_priv *priv = &vif->priv;
 270         struct host_if_drv *wfi_drv = priv->hif_drv;
 271         int ret;
 272         u32 i;
 273         u8 security = WILC_FW_SEC_NO;
 274         enum authtype auth_type = WILC_FW_AUTH_ANY;
 275         u32 cipher_group;
 276         struct cfg80211_bss *bss;
 277         void *join_params;
 278         u8 ch;
 279 
 280         vif->connecting = true;
 281 
 282         memset(priv->wep_key, 0, sizeof(priv->wep_key));
 283         memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
 284 
 285         cipher_group = sme->crypto.cipher_group;
 286         if (cipher_group != 0) {
 287                 if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
 288                         security = WILC_FW_SEC_WEP;
 289 
 290                         priv->wep_key_len[sme->key_idx] = sme->key_len;
 291                         memcpy(priv->wep_key[sme->key_idx], sme->key,
 292                                sme->key_len);
 293 
 294                         wilc_set_wep_default_keyid(vif, sme->key_idx);
 295                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
 296                                                  sme->key_idx);
 297                 } else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
 298                         security = WILC_FW_SEC_WEP_EXTENDED;
 299 
 300                         priv->wep_key_len[sme->key_idx] = sme->key_len;
 301                         memcpy(priv->wep_key[sme->key_idx], sme->key,
 302                                sme->key_len);
 303 
 304                         wilc_set_wep_default_keyid(vif, sme->key_idx);
 305                         wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
 306                                                  sme->key_idx);
 307                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
 308                         if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
 309                                 security = WILC_FW_SEC_WPA2_TKIP;
 310                         else
 311                                 security = WILC_FW_SEC_WPA2_AES;
 312                 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
 313                         if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
 314                                 security = WILC_FW_SEC_WPA_TKIP;
 315                         else
 316                                 security = WILC_FW_SEC_WPA_AES;
 317                 } else {
 318                         ret = -ENOTSUPP;
 319                         netdev_err(dev, "%s: Unsupported cipher\n",
 320                                    __func__);
 321                         goto out_error;
 322                 }
 323         }
 324 
 325         if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
 326             (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
 327                 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
 328                         u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
 329 
 330                         if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
 331                                 security |= WILC_FW_TKIP;
 332                         else
 333                                 security |= WILC_FW_AES;
 334                 }
 335         }
 336 
 337         switch (sme->auth_type) {
 338         case NL80211_AUTHTYPE_OPEN_SYSTEM:
 339                 auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
 340                 break;
 341 
 342         case NL80211_AUTHTYPE_SHARED_KEY:
 343                 auth_type = WILC_FW_AUTH_SHARED_KEY;
 344                 break;
 345 
 346         default:
 347                 break;
 348         }
 349 
 350         if (sme->crypto.n_akm_suites) {
 351                 if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
 352                         auth_type = WILC_FW_AUTH_IEEE8021;
 353         }
 354 
 355         if (wfi_drv->usr_scan_req.scan_result) {
 356                 netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
 357                 ret = -EBUSY;
 358                 goto out_error;
 359         }
 360 
 361         bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
 362                                sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
 363                                IEEE80211_PRIVACY(sme->privacy));
 364         if (!bss) {
 365                 ret = -EINVAL;
 366                 goto out_error;
 367         }
 368 
 369         if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
 370                 ret = -EALREADY;
 371                 goto out_put_bss;
 372         }
 373 
 374         join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
 375         if (!join_params) {
 376                 netdev_err(dev, "%s: failed to construct join param\n",
 377                            __func__);
 378                 ret = -EINVAL;
 379                 goto out_put_bss;
 380         }
 381 
 382         ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
 383         vif->wilc->op_ch = ch;
 384         if (vif->iftype != WILC_CLIENT_MODE)
 385                 vif->wilc->sta_ch = ch;
 386 
 387         wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);
 388 
 389         wfi_drv->conn_info.security = security;
 390         wfi_drv->conn_info.auth_type = auth_type;
 391         wfi_drv->conn_info.ch = ch;
 392         wfi_drv->conn_info.conn_result = cfg_connect_result;
 393         wfi_drv->conn_info.arg = priv;
 394         wfi_drv->conn_info.param = join_params;
 395 
 396         ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
 397         if (ret) {
 398                 netdev_err(dev, "wilc_set_join_req(): Error\n");
 399                 ret = -ENOENT;
 400                 if (vif->iftype != WILC_CLIENT_MODE)
 401                         vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
 402                 wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
 403                 wfi_drv->conn_info.conn_result = NULL;
 404                 kfree(join_params);
 405                 goto out_put_bss;
 406         }
 407         kfree(join_params);
 408         cfg80211_put_bss(wiphy, bss);
 409         return 0;
 410 
 411 out_put_bss:
 412         cfg80211_put_bss(wiphy, bss);
 413 
 414 out_error:
 415         vif->connecting = false;
 416         return ret;
 417 }
 418 
 419 static int disconnect(struct wiphy *wiphy, struct net_device *dev,
 420                       u16 reason_code)
 421 {
 422         struct wilc_vif *vif = netdev_priv(dev);
 423         struct wilc_priv *priv = &vif->priv;
 424         struct wilc *wilc = vif->wilc;
 425         int ret;
 426 
 427         vif->connecting = false;
 428 
 429         if (!wilc)
 430                 return -EIO;
 431 
 432         if (wilc->close) {
 433                 /* already disconnected done */
 434                 cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
 435                 return 0;
 436         }
 437 
 438         if (vif->iftype != WILC_CLIENT_MODE)
 439                 wilc->sta_ch = WILC_INVALID_CHANNEL;
 440         wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
 441 
 442         priv->p2p.local_random = 0x01;
 443         priv->p2p.recv_random = 0x00;
 444         priv->p2p.is_wilc_ie = false;
 445         priv->hif_drv->p2p_timeout = 0;
 446 
 447         ret = wilc_disconnect(vif);
 448         if (ret != 0) {
 449                 netdev_err(priv->dev, "Error in disconnecting\n");
 450                 ret = -EINVAL;
 451         }
 452 
 453         return ret;
 454 }
 455 
 456 static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
 457                                               u8 key_index,
 458                                               struct key_params *params)
 459 {
 460         priv->wep_key_len[key_index] = params->key_len;
 461         memcpy(priv->wep_key[key_index], params->key, params->key_len);
 462 }
 463 
 464 static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
 465 {
 466         if (!priv->wilc_gtk[idx]) {
 467                 priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
 468                                               GFP_KERNEL);
 469                 if (!priv->wilc_gtk[idx])
 470                         return -ENOMEM;
 471         }
 472 
 473         if (!priv->wilc_ptk[idx]) {
 474                 priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
 475                                               GFP_KERNEL);
 476                 if (!priv->wilc_ptk[idx])
 477                         return -ENOMEM;
 478         }
 479 
 480         return 0;
 481 }
 482 
 483 static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
 484                                       struct key_params *params)
 485 {
 486         kfree(key_info->key);
 487 
 488         key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
 489         if (!key_info->key)
 490                 return -ENOMEM;
 491 
 492         kfree(key_info->seq);
 493 
 494         if (params->seq_len > 0) {
 495                 key_info->seq = kmemdup(params->seq, params->seq_len,
 496                                         GFP_KERNEL);
 497                 if (!key_info->seq)
 498                         return -ENOMEM;
 499         }
 500 
 501         key_info->cipher = params->cipher;
 502         key_info->key_len = params->key_len;
 503         key_info->seq_len = params->seq_len;
 504 
 505         return 0;
 506 }
 507 
 508 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 509                    bool pairwise, const u8 *mac_addr, struct key_params *params)
 510 
 511 {
 512         int ret = 0, keylen = params->key_len;
 513         const u8 *rx_mic = NULL;
 514         const u8 *tx_mic = NULL;
 515         u8 mode = WILC_FW_SEC_NO;
 516         u8 op_mode;
 517         struct wilc_vif *vif = netdev_priv(netdev);
 518         struct wilc_priv *priv = &vif->priv;
 519 
 520         switch (params->cipher) {
 521         case WLAN_CIPHER_SUITE_WEP40:
 522         case WLAN_CIPHER_SUITE_WEP104:
 523                 if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
 524                         wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
 525 
 526                         if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
 527                                 mode = WILC_FW_SEC_WEP;
 528                         else
 529                                 mode = WILC_FW_SEC_WEP_EXTENDED;
 530 
 531                         ret = wilc_add_wep_key_bss_ap(vif, params->key,
 532                                                       params->key_len,
 533                                                       key_index, mode,
 534                                                       WILC_FW_AUTH_OPEN_SYSTEM);
 535                         break;
 536                 }
 537                 if (memcmp(params->key, priv->wep_key[key_index],
 538                            params->key_len)) {
 539                         wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
 540 
 541                         ret = wilc_add_wep_key_bss_sta(vif, params->key,
 542                                                        params->key_len,
 543                                                        key_index);
 544                 }
 545 
 546                 break;
 547 
 548         case WLAN_CIPHER_SUITE_TKIP:
 549         case WLAN_CIPHER_SUITE_CCMP:
 550                 if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
 551                     priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
 552                         struct wilc_wfi_key *key;
 553 
 554                         ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
 555                         if (ret)
 556                                 return -ENOMEM;
 557 
 558                         if (params->key_len > 16 &&
 559                             params->cipher == WLAN_CIPHER_SUITE_TKIP) {
 560                                 tx_mic = params->key + 24;
 561                                 rx_mic = params->key + 16;
 562                                 keylen = params->key_len - 16;
 563                         }
 564 
 565                         if (!pairwise) {
 566                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
 567                                         mode = WILC_FW_SEC_WPA_TKIP;
 568                                 else
 569                                         mode = WILC_FW_SEC_WPA2_AES;
 570 
 571                                 priv->wilc_groupkey = mode;
 572 
 573                                 key = priv->wilc_gtk[key_index];
 574                         } else {
 575                                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
 576                                         mode = WILC_FW_SEC_WPA_TKIP;
 577                                 else
 578                                         mode = priv->wilc_groupkey | WILC_FW_AES;
 579 
 580                                 key = priv->wilc_ptk[key_index];
 581                         }
 582                         ret = wilc_wfi_cfg_copy_wpa_info(key, params);
 583                         if (ret)
 584                                 return -ENOMEM;
 585 
 586                         op_mode = WILC_AP_MODE;
 587                 } else {
 588                         if (params->key_len > 16 &&
 589                             params->cipher == WLAN_CIPHER_SUITE_TKIP) {
 590                                 rx_mic = params->key + 24;
 591                                 tx_mic = params->key + 16;
 592                                 keylen = params->key_len - 16;
 593                         }
 594 
 595                         op_mode = WILC_STATION_MODE;
 596                 }
 597 
 598                 if (!pairwise)
 599                         ret = wilc_add_rx_gtk(vif, params->key, keylen,
 600                                               key_index, params->seq_len,
 601                                               params->seq, rx_mic, tx_mic,
 602                                               op_mode, mode);
 603                 else
 604                         ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
 605                                            rx_mic, tx_mic, op_mode, mode,
 606                                            key_index);
 607 
 608                 break;
 609 
 610         default:
 611                 netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
 612                 ret = -ENOTSUPP;
 613         }
 614 
 615         return ret;
 616 }
 617 
 618 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
 619                    u8 key_index,
 620                    bool pairwise,
 621                    const u8 *mac_addr)
 622 {
 623         struct wilc *wl = wiphy_priv(wiphy);
 624         struct wilc_vif *vif = netdev_priv(netdev);
 625         struct wilc_priv *priv = &vif->priv;
 626 
 627         if (netdev == wl->vif[0]->ndev) {
 628                 if (priv->wilc_gtk[key_index]) {
 629                         kfree(priv->wilc_gtk[key_index]->key);
 630                         priv->wilc_gtk[key_index]->key = NULL;
 631                         kfree(priv->wilc_gtk[key_index]->seq);
 632                         priv->wilc_gtk[key_index]->seq = NULL;
 633 
 634                         kfree(priv->wilc_gtk[key_index]);
 635                         priv->wilc_gtk[key_index] = NULL;
 636                 }
 637 
 638                 if (priv->wilc_ptk[key_index]) {
 639                         kfree(priv->wilc_ptk[key_index]->key);
 640                         priv->wilc_ptk[key_index]->key = NULL;
 641                         kfree(priv->wilc_ptk[key_index]->seq);
 642                         priv->wilc_ptk[key_index]->seq = NULL;
 643                         kfree(priv->wilc_ptk[key_index]);
 644                         priv->wilc_ptk[key_index] = NULL;
 645                 }
 646         }
 647 
 648         if (key_index <= 3 && priv->wep_key_len[key_index]) {
 649                 memset(priv->wep_key[key_index], 0,
 650                        priv->wep_key_len[key_index]);
 651                 priv->wep_key_len[key_index] = 0;
 652                 wilc_remove_wep_key(vif, key_index);
 653         }
 654 
 655         return 0;
 656 }
 657 
 658 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 659                    bool pairwise, const u8 *mac_addr, void *cookie,
 660                    void (*callback)(void *cookie, struct key_params *))
 661 {
 662         struct wilc_vif *vif = netdev_priv(netdev);
 663         struct wilc_priv *priv = &vif->priv;
 664         struct  key_params key_params;
 665 
 666         if (!pairwise) {
 667                 key_params.key = priv->wilc_gtk[key_index]->key;
 668                 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
 669                 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
 670                 key_params.seq = priv->wilc_gtk[key_index]->seq;
 671                 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
 672         } else {
 673                 key_params.key = priv->wilc_ptk[key_index]->key;
 674                 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
 675                 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
 676                 key_params.seq = priv->wilc_ptk[key_index]->seq;
 677                 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
 678         }
 679 
 680         callback(cookie, &key_params);
 681 
 682         return 0;
 683 }
 684 
 685 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
 686                            u8 key_index, bool unicast, bool multicast)
 687 {
 688         struct wilc_vif *vif = netdev_priv(netdev);
 689 
 690         wilc_set_wep_default_keyid(vif, key_index);
 691 
 692         return 0;
 693 }
 694 
 695 static int get_station(struct wiphy *wiphy, struct net_device *dev,
 696                        const u8 *mac, struct station_info *sinfo)
 697 {
 698         struct wilc_vif *vif = netdev_priv(dev);
 699         struct wilc_priv *priv = &vif->priv;
 700         u32 i = 0;
 701         u32 associatedsta = ~0;
 702         u32 inactive_time = 0;
 703 
 704         if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
 705                 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
 706                         if (!(memcmp(mac,
 707                                      priv->assoc_stainfo.sta_associated_bss[i],
 708                                      ETH_ALEN))) {
 709                                 associatedsta = i;
 710                                 break;
 711                         }
 712                 }
 713 
 714                 if (associatedsta == ~0) {
 715                         netdev_err(dev, "sta required is not associated\n");
 716                         return -ENOENT;
 717                 }
 718 
 719                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
 720 
 721                 wilc_get_inactive_time(vif, mac, &inactive_time);
 722                 sinfo->inactive_time = 1000 * inactive_time;
 723         } else if (vif->iftype == WILC_STATION_MODE) {
 724                 struct rf_info stats;
 725 
 726                 wilc_get_statistics(vif, &stats);
 727 
 728                 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
 729                                  BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
 730                                  BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
 731                                  BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
 732                                  BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
 733 
 734                 sinfo->signal = stats.rssi;
 735                 sinfo->rx_packets = stats.rx_cnt;
 736                 sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
 737                 sinfo->tx_failed = stats.tx_fail_cnt;
 738                 sinfo->txrate.legacy = stats.link_speed * 10;
 739 
 740                 if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
 741                     stats.link_speed != DEFAULT_LINK_SPEED)
 742                         wilc_enable_tcp_ack_filter(vif, true);
 743                 else if (stats.link_speed != DEFAULT_LINK_SPEED)
 744                         wilc_enable_tcp_ack_filter(vif, false);
 745         }
 746         return 0;
 747 }
 748 
 749 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
 750                       struct bss_parameters *params)
 751 {
 752         return 0;
 753 }
 754 
 755 struct wilc_vif *wilc_get_interface(struct wilc *wl)
 756 {
 757         int i;
 758         struct wilc_vif *vif = NULL;
 759 
 760         mutex_lock(&wl->vif_mutex);
 761         for (i = 0; i < wl->vif_num; i++) {
 762                 if (wl->vif[i]) {
 763                         vif = wl->vif[i];
 764                         break;
 765                 }
 766         }
 767         mutex_unlock(&wl->vif_mutex);
 768         return vif;
 769 }
 770 
 771 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
 772 {
 773         int ret;
 774         struct cfg_param_attr cfg_param_val;
 775         struct wilc *wl = wiphy_priv(wiphy);
 776         struct wilc_vif *vif;
 777         struct wilc_priv *priv;
 778 
 779         vif = wilc_get_interface(wl);
 780         if (!vif)
 781                 return -EINVAL;
 782 
 783         priv = &vif->priv;
 784         cfg_param_val.flag = 0;
 785 
 786         if (changed & WIPHY_PARAM_RETRY_SHORT) {
 787                 netdev_dbg(vif->ndev,
 788                            "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
 789                            wiphy->retry_short);
 790                 cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
 791                 cfg_param_val.short_retry_limit = wiphy->retry_short;
 792         }
 793         if (changed & WIPHY_PARAM_RETRY_LONG) {
 794                 netdev_dbg(vif->ndev,
 795                            "Setting WIPHY_PARAM_RETRY_LONG %d\n",
 796                            wiphy->retry_long);
 797                 cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
 798                 cfg_param_val.long_retry_limit = wiphy->retry_long;
 799         }
 800         if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
 801                 if (wiphy->frag_threshold > 255 &&
 802                     wiphy->frag_threshold < 7937) {
 803                         netdev_dbg(vif->ndev,
 804                                    "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
 805                                    wiphy->frag_threshold);
 806                         cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
 807                         cfg_param_val.frag_threshold = wiphy->frag_threshold;
 808                 } else {
 809                         netdev_err(vif->ndev,
 810                                    "Fragmentation threshold out of range\n");
 811                         return -EINVAL;
 812                 }
 813         }
 814 
 815         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
 816                 if (wiphy->rts_threshold > 255) {
 817                         netdev_dbg(vif->ndev,
 818                                    "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
 819                                    wiphy->rts_threshold);
 820                         cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
 821                         cfg_param_val.rts_threshold = wiphy->rts_threshold;
 822                 } else {
 823                         netdev_err(vif->ndev, "RTS threshold out of range\n");
 824                         return -EINVAL;
 825                 }
 826         }
 827 
 828         ret = wilc_hif_set_cfg(vif, &cfg_param_val);
 829         if (ret)
 830                 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
 831 
 832         return ret;
 833 }
 834 
 835 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 836                      struct cfg80211_pmksa *pmksa)
 837 {
 838         struct wilc_vif *vif = netdev_priv(netdev);
 839         struct wilc_priv *priv = &vif->priv;
 840         u32 i;
 841         int ret = 0;
 842         u8 flag = 0;
 843 
 844         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
 845                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
 846                             ETH_ALEN)) {
 847                         flag = PMKID_FOUND;
 848                         break;
 849                 }
 850         }
 851         if (i < WILC_MAX_NUM_PMKIDS) {
 852                 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
 853                        ETH_ALEN);
 854                 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
 855                        WLAN_PMKID_LEN);
 856                 if (!(flag == PMKID_FOUND))
 857                         priv->pmkid_list.numpmkid++;
 858         } else {
 859                 netdev_err(netdev, "Invalid PMKID index\n");
 860                 ret = -EINVAL;
 861         }
 862 
 863         if (!ret)
 864                 ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
 865 
 866         return ret;
 867 }
 868 
 869 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 870                      struct cfg80211_pmksa *pmksa)
 871 {
 872         u32 i;
 873         int ret = 0;
 874         struct wilc_vif *vif = netdev_priv(netdev);
 875         struct wilc_priv *priv = &vif->priv;
 876 
 877         for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
 878                 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
 879                             ETH_ALEN)) {
 880                         memset(&priv->pmkid_list.pmkidlist[i], 0,
 881                                sizeof(struct wilc_pmkid));
 882                         break;
 883                 }
 884         }
 885 
 886         if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
 887                 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
 888                         memcpy(priv->pmkid_list.pmkidlist[i].bssid,
 889                                priv->pmkid_list.pmkidlist[i + 1].bssid,
 890                                ETH_ALEN);
 891                         memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
 892                                priv->pmkid_list.pmkidlist[i + 1].pmkid,
 893                                WLAN_PMKID_LEN);
 894                 }
 895                 priv->pmkid_list.numpmkid--;
 896         } else {
 897                 ret = -EINVAL;
 898         }
 899 
 900         return ret;
 901 }
 902 
 903 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 904 {
 905         struct wilc_vif *vif = netdev_priv(netdev);
 906 
 907         memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
 908 
 909         return 0;
 910 }
 911 
 912 static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx,
 913                                               u8 op_ch_attr_idx, u8 sta_ch)
 914 {
 915         int i = 0;
 916         int j = 0;
 917 
 918         if (ch_list_attr_idx) {
 919                 u8 limit = ch_list_attr_idx + 3 + buf[ch_list_attr_idx + 1];
 920 
 921                 for (i = ch_list_attr_idx + 3; i < limit; i++) {
 922                         if (buf[i] == 0x51) {
 923                                 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
 924                                         buf[j] = sta_ch;
 925                                 break;
 926                         }
 927                 }
 928         }
 929 
 930         if (op_ch_attr_idx) {
 931                 buf[op_ch_attr_idx + 6] = 0x51;
 932                 buf[op_ch_attr_idx + 7] = sta_ch;
 933         }
 934 }
 935 
 936 static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len, u8 sta_ch)
 937 {
 938         u32 index = 0;
 939         u8 op_channel_attr_index = 0;
 940         u8 channel_list_attr_index = 0;
 941 
 942         while (index < len) {
 943                 if (buf[index] == GO_INTENT_ATTR_ID)
 944                         buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);
 945 
 946                 if (buf[index] ==  CHANLIST_ATTR_ID)
 947                         channel_list_attr_index = index;
 948                 else if (buf[index] ==  OPERCHAN_ATTR_ID)
 949                         op_channel_attr_index = index;
 950                 index += buf[index + 1] + 3;
 951         }
 952         if (sta_ch != WILC_INVALID_CHANNEL)
 953                 wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
 954                                            op_channel_attr_index, sta_ch);
 955 }
 956 
 957 static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch,
 958                                          u8 iftype, u8 sta_ch)
 959 {
 960         u32 index = 0;
 961         u8 op_channel_attr_index = 0;
 962         u8 channel_list_attr_index = 0;
 963 
 964         while (index < len) {
 965                 if (buf[index] == GO_INTENT_ATTR_ID) {
 966                         buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);
 967 
 968                         break;
 969                 }
 970 
 971                 if (buf[index] ==  CHANLIST_ATTR_ID)
 972                         channel_list_attr_index = index;
 973                 else if (buf[index] ==  OPERCHAN_ATTR_ID)
 974                         op_channel_attr_index = index;
 975                 index += buf[index + 1] + 3;
 976         }
 977         if (sta_ch != WILC_INVALID_CHANNEL && oper_ch)
 978                 wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
 979                                            op_channel_attr_index, sta_ch);
 980 }
 981 
 982 static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff,
 983                                               u32 size)
 984 {
 985         int i;
 986         u8 subtype;
 987         struct wilc_vif *vif = netdev_priv(priv->dev);
 988 
 989         subtype = buff[P2P_PUB_ACTION_SUBTYPE];
 990         if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
 991             !priv->p2p.is_wilc_ie) {
 992                 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
 993                         if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
 994                                 priv->p2p.recv_random = buff[i + 6];
 995                                 priv->p2p.is_wilc_ie = true;
 996                                 break;
 997                         }
 998                 }
 999         }
1000 
1001         if (priv->p2p.local_random <= priv->p2p.recv_random) {
1002                 netdev_dbg(vif->ndev,
1003                            "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n",
1004                            priv->p2p.local_random, priv->p2p.recv_random);
1005                 return;
1006         }
1007 
1008         if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
1009             subtype == P2P_INV_REQ || subtype == P2P_INV_RSP) {
1010                 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1011                         if (buff[i] == P2PELEM_ATTR_ID &&
1012                             !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1013                                 wilc_wfi_cfg_parse_rx_action(&buff[i + 6],
1014                                                              size - (i + 6),
1015                                                              vif->wilc->sta_ch);
1016                                 break;
1017                         }
1018                 }
1019         }
1020 }
1021 
1022 void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
1023 {
1024         struct wilc *wl = vif->wilc;
1025         struct wilc_priv *priv = &vif->priv;
1026         struct host_if_drv *wfi_drv = priv->hif_drv;
1027         u32 header, pkt_offset;
1028         s32 freq;
1029         __le16 fc;
1030 
1031         header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
1032         pkt_offset = GET_PKT_OFFSET(header);
1033 
1034         if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1035                 bool ack = false;
1036 
1037                 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP ||
1038                     pkt_offset & IS_MGMT_STATUS_SUCCES)
1039                         ack = true;
1040 
1041                 cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
1042                                         size, ack, GFP_KERNEL);
1043                 return;
1044         }
1045 
1046         freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1047 
1048         fc = ((struct ieee80211_hdr *)buff)->frame_control;
1049         if (!ieee80211_is_action(fc)) {
1050                 cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1051                 return;
1052         }
1053 
1054         if (priv->cfg_scanning &&
1055             time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
1056                 netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
1057                 return;
1058         }
1059         if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1060                 u8 subtype = buff[P2P_PUB_ACTION_SUBTYPE];
1061 
1062                 switch (buff[ACTION_SUBTYPE_ID]) {
1063                 case GAS_INITIAL_REQ:
1064                 case GAS_INITIAL_RSP:
1065                         break;
1066 
1067                 case PUBLIC_ACT_VENDORSPEC:
1068                         if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4))
1069                                 wilc_wfi_cfg_parse_rx_vendor_spec(priv, buff,
1070                                                                   size);
1071 
1072                         if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
1073                             priv->p2p.is_wilc_ie)
1074                                 size -= 7;
1075 
1076                         break;
1077 
1078                 default:
1079                         netdev_dbg(vif->ndev,
1080                                    "%s: Not handled action frame type:%x\n",
1081                                    __func__, buff[ACTION_SUBTYPE_ID]);
1082                         break;
1083                 }
1084         }
1085 
1086         cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1087 }
1088 
1089 static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
1090 {
1091         struct wilc_p2p_mgmt_data *pv_data = priv;
1092 
1093         kfree(pv_data->buff);
1094         kfree(pv_data);
1095 }
1096 
1097 static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
1098 {
1099         struct wilc_vif *vif = data;
1100         struct wilc_priv *priv = &vif->priv;
1101         struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
1102 
1103         if (cookie != params->listen_cookie)
1104                 return;
1105 
1106         priv->p2p_listen_state = false;
1107 
1108         cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
1109                                            params->listen_ch, GFP_KERNEL);
1110 }
1111 
1112 static int remain_on_channel(struct wiphy *wiphy,
1113                              struct wireless_dev *wdev,
1114                              struct ieee80211_channel *chan,
1115                              unsigned int duration, u64 *cookie)
1116 {
1117         int ret = 0;
1118         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1119         struct wilc_priv *priv = &vif->priv;
1120         u64 id;
1121 
1122         if (wdev->iftype == NL80211_IFTYPE_AP) {
1123                 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1124                 return ret;
1125         }
1126 
1127         id = ++priv->inc_roc_cookie;
1128         if (id == 0)
1129                 id = ++priv->inc_roc_cookie;
1130 
1131         ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
1132                                      wilc_wfi_remain_on_channel_expired,
1133                                      (void *)vif);
1134         if (ret)
1135                 return ret;
1136 
1137         vif->wilc->op_ch = chan->hw_value;
1138 
1139         priv->remain_on_ch_params.listen_ch = chan;
1140         priv->remain_on_ch_params.listen_cookie = id;
1141         *cookie = id;
1142         priv->p2p_listen_state = true;
1143         priv->remain_on_ch_params.listen_duration = duration;
1144 
1145         cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
1146         mod_timer(&vif->hif_drv->remain_on_ch_timer,
1147                   jiffies + msecs_to_jiffies(duration));
1148 
1149         return ret;
1150 }
1151 
1152 static int cancel_remain_on_channel(struct wiphy *wiphy,
1153                                     struct wireless_dev *wdev,
1154                                     u64 cookie)
1155 {
1156         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1157         struct wilc_priv *priv = &vif->priv;
1158 
1159         if (cookie != priv->remain_on_ch_params.listen_cookie)
1160                 return -ENOENT;
1161 
1162         return wilc_listen_state_expired(vif, cookie);
1163 }
1164 
1165 static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv,
1166                                         struct wilc_p2p_mgmt_data *mgmt_tx,
1167                                         struct cfg80211_mgmt_tx_params *params,
1168                                         u8 iftype, u32 buf_len)
1169 {
1170         const u8 *buf = params->buf;
1171         size_t len = params->len;
1172         u32 i;
1173         u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE];
1174         struct wilc_vif *vif = netdev_priv(priv->dev);
1175 
1176         if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) {
1177                 if (priv->p2p.local_random == 1 &&
1178                     priv->p2p.recv_random < priv->p2p.local_random) {
1179                         get_random_bytes(&priv->p2p.local_random, 1);
1180                         priv->p2p.local_random++;
1181                 }
1182         }
1183 
1184         if (priv->p2p.local_random <= priv->p2p.recv_random ||
1185             !(subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
1186               subtype == P2P_INV_REQ || subtype == P2P_INV_RSP))
1187                 return;
1188 
1189         for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1190                 if (buf[i] == P2PELEM_ATTR_ID &&
1191                     !memcmp(p2p_oui, &buf[i + 2], 4)) {
1192                         bool oper_ch = false;
1193                         u8 *tx_buff = &mgmt_tx->buff[i + 6];
1194 
1195                         if (subtype == P2P_INV_REQ || subtype == P2P_INV_RSP)
1196                                 oper_ch = true;
1197 
1198                         wilc_wfi_cfg_parse_tx_action(tx_buff, len - (i + 6),
1199                                                      oper_ch, iftype,
1200                                                      vif->wilc->sta_ch);
1201 
1202                         break;
1203                 }
1204         }
1205 
1206         if (subtype != P2P_INV_REQ && subtype != P2P_INV_RSP) {
1207                 int vendor_spec_len = sizeof(p2p_vendor_spec);
1208 
1209                 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec,
1210                        vendor_spec_len);
1211                 mgmt_tx->buff[len + vendor_spec_len] = priv->p2p.local_random;
1212                 mgmt_tx->size = buf_len;
1213         }
1214 }
1215 
1216 static int mgmt_tx(struct wiphy *wiphy,
1217                    struct wireless_dev *wdev,
1218                    struct cfg80211_mgmt_tx_params *params,
1219                    u64 *cookie)
1220 {
1221         struct ieee80211_channel *chan = params->chan;
1222         unsigned int wait = params->wait;
1223         const u8 *buf = params->buf;
1224         size_t len = params->len;
1225         const struct ieee80211_mgmt *mgmt;
1226         struct wilc_p2p_mgmt_data *mgmt_tx;
1227         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1228         struct wilc_priv *priv = &vif->priv;
1229         struct host_if_drv *wfi_drv = priv->hif_drv;
1230         u32 buf_len = len + sizeof(p2p_vendor_spec) +
1231                         sizeof(priv->p2p.local_random);
1232         int ret = 0;
1233 
1234         *cookie = prandom_u32();
1235         priv->tx_cookie = *cookie;
1236         mgmt = (const struct ieee80211_mgmt *)buf;
1237 
1238         if (!ieee80211_is_mgmt(mgmt->frame_control))
1239                 goto out;
1240 
1241         mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
1242         if (!mgmt_tx) {
1243                 ret = -ENOMEM;
1244                 goto out;
1245         }
1246 
1247         mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1248         if (!mgmt_tx->buff) {
1249                 ret = -ENOMEM;
1250                 kfree(mgmt_tx);
1251                 goto out;
1252         }
1253 
1254         memcpy(mgmt_tx->buff, buf, len);
1255         mgmt_tx->size = len;
1256 
1257         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1258                 wilc_set_mac_chnl_num(vif, chan->hw_value);
1259                 vif->wilc->op_ch = chan->hw_value;
1260                 goto out_txq_add_pkt;
1261         }
1262 
1263         if (!ieee80211_is_action(mgmt->frame_control))
1264                 goto out_txq_add_pkt;
1265 
1266         if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1267                 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1268                     buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1269                         wilc_set_mac_chnl_num(vif, chan->hw_value);
1270                         vif->wilc->op_ch = chan->hw_value;
1271                 }
1272                 switch (buf[ACTION_SUBTYPE_ID]) {
1273                 case GAS_INITIAL_REQ:
1274                 case GAS_INITIAL_RSP:
1275                         break;
1276 
1277                 case PUBLIC_ACT_VENDORSPEC:
1278                         if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4))
1279                                 wilc_wfi_cfg_tx_vendor_spec(priv, mgmt_tx,
1280                                                             params, vif->iftype,
1281                                                             buf_len);
1282                         else
1283                                 netdev_dbg(vif->ndev,
1284                                            "Not a P2P public action frame\n");
1285 
1286                         break;
1287 
1288                 default:
1289                         netdev_dbg(vif->ndev,
1290                                    "%s: Not handled action frame type:%x\n",
1291                                    __func__, buf[ACTION_SUBTYPE_ID]);
1292                         break;
1293                 }
1294         }
1295 
1296         wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1297 
1298 out_txq_add_pkt:
1299 
1300         wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1301                                    mgmt_tx->buff, mgmt_tx->size,
1302                                    wilc_wfi_mgmt_tx_complete);
1303 
1304 out:
1305 
1306         return ret;
1307 }
1308 
1309 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1310                                struct wireless_dev *wdev,
1311                                u64 cookie)
1312 {
1313         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1314         struct wilc_priv *priv = &vif->priv;
1315         struct host_if_drv *wfi_drv = priv->hif_drv;
1316 
1317         wfi_drv->p2p_timeout = jiffies;
1318 
1319         if (!priv->p2p_listen_state) {
1320                 struct wilc_wfi_p2p_listen_params *params;
1321 
1322                 params = &priv->remain_on_ch_params;
1323 
1324                 cfg80211_remain_on_channel_expired(wdev,
1325                                                    params->listen_cookie,
1326                                                    params->listen_ch,
1327                                                    GFP_KERNEL);
1328         }
1329 
1330         return 0;
1331 }
1332 
1333 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1334                               u16 frame_type, bool reg)
1335 {
1336         struct wilc *wl = wiphy_priv(wiphy);
1337         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1338 
1339         if (!frame_type)
1340                 return;
1341 
1342         switch (frame_type) {
1343         case IEEE80211_STYPE_PROBE_REQ:
1344                 vif->frame_reg[0].type = frame_type;
1345                 vif->frame_reg[0].reg = reg;
1346                 break;
1347 
1348         case IEEE80211_STYPE_ACTION:
1349                 vif->frame_reg[1].type = frame_type;
1350                 vif->frame_reg[1].reg = reg;
1351                 break;
1352 
1353         default:
1354                 break;
1355         }
1356 
1357         if (!wl->initialized)
1358                 return;
1359         wilc_frame_register(vif, frame_type, reg);
1360 }
1361 
1362 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1363                                s32 rssi_thold, u32 rssi_hyst)
1364 {
1365         return 0;
1366 }
1367 
1368 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1369                         int idx, u8 *mac, struct station_info *sinfo)
1370 {
1371         struct wilc_vif *vif = netdev_priv(dev);
1372         int ret;
1373 
1374         if (idx != 0)
1375                 return -ENOENT;
1376 
1377         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1378 
1379         ret = wilc_get_rssi(vif, &sinfo->signal);
1380         if (ret)
1381                 return ret;
1382 
1383         memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
1384         return 0;
1385 }
1386 
1387 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1388                           bool enabled, int timeout)
1389 {
1390         struct wilc_vif *vif = netdev_priv(dev);
1391         struct wilc_priv *priv = &vif->priv;
1392 
1393         if (!priv->hif_drv)
1394                 return -EIO;
1395 
1396         wilc_set_power_mgmt(vif, enabled, timeout);
1397 
1398         return 0;
1399 }
1400 
1401 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1402                                enum nl80211_iftype type,
1403                                struct vif_params *params)
1404 {
1405         struct wilc *wl = wiphy_priv(wiphy);
1406         struct wilc_vif *vif = netdev_priv(dev);
1407         struct wilc_priv *priv = &vif->priv;
1408 
1409         priv->p2p.local_random = 0x01;
1410         priv->p2p.recv_random = 0x00;
1411         priv->p2p.is_wilc_ie = false;
1412 
1413         switch (type) {
1414         case NL80211_IFTYPE_STATION:
1415                 vif->connecting = false;
1416                 dev->ieee80211_ptr->iftype = type;
1417                 priv->wdev.iftype = type;
1418                 vif->monitor_flag = 0;
1419                 if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
1420                         wilc_wfi_deinit_mon_interface(wl, true);
1421                 vif->iftype = WILC_STATION_MODE;
1422 
1423                 if (wl->initialized)
1424                         wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1425                                                 WILC_STATION_MODE, vif->idx);
1426 
1427                 memset(priv->assoc_stainfo.sta_associated_bss, 0,
1428                        WILC_MAX_NUM_STA * ETH_ALEN);
1429                 break;
1430 
1431         case NL80211_IFTYPE_P2P_CLIENT:
1432                 vif->connecting = false;
1433                 dev->ieee80211_ptr->iftype = type;
1434                 priv->wdev.iftype = type;
1435                 vif->monitor_flag = 0;
1436                 vif->iftype = WILC_CLIENT_MODE;
1437 
1438                 if (wl->initialized)
1439                         wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1440                                                 WILC_STATION_MODE, vif->idx);
1441                 break;
1442 
1443         case NL80211_IFTYPE_AP:
1444                 dev->ieee80211_ptr->iftype = type;
1445                 priv->wdev.iftype = type;
1446                 vif->iftype = WILC_AP_MODE;
1447 
1448                 if (wl->initialized)
1449                         wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1450                                                 WILC_AP_MODE, vif->idx);
1451                 break;
1452 
1453         case NL80211_IFTYPE_P2P_GO:
1454                 dev->ieee80211_ptr->iftype = type;
1455                 priv->wdev.iftype = type;
1456                 vif->iftype = WILC_GO_MODE;
1457 
1458                 if (wl->initialized)
1459                         wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1460                                                 WILC_AP_MODE, vif->idx);
1461                 break;
1462 
1463         default:
1464                 netdev_err(dev, "Unknown interface type= %d\n", type);
1465                 return -EINVAL;
1466         }
1467 
1468         return 0;
1469 }
1470 
1471 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1472                     struct cfg80211_ap_settings *settings)
1473 {
1474         struct wilc_vif *vif = netdev_priv(dev);
1475         int ret;
1476 
1477         ret = set_channel(wiphy, &settings->chandef);
1478         if (ret != 0)
1479                 netdev_err(dev, "Error in setting channel\n");
1480 
1481         wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
1482 
1483         return wilc_add_beacon(vif, settings->beacon_interval,
1484                                    settings->dtim_period, &settings->beacon);
1485 }
1486 
1487 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1488                          struct cfg80211_beacon_data *beacon)
1489 {
1490         struct wilc_vif *vif = netdev_priv(dev);
1491 
1492         return wilc_add_beacon(vif, 0, 0, beacon);
1493 }
1494 
1495 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1496 {
1497         int ret;
1498         struct wilc_vif *vif = netdev_priv(dev);
1499 
1500         wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
1501 
1502         ret = wilc_del_beacon(vif);
1503 
1504         if (ret)
1505                 netdev_err(dev, "Host delete beacon fail\n");
1506 
1507         return ret;
1508 }
1509 
1510 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1511                        const u8 *mac, struct station_parameters *params)
1512 {
1513         int ret = 0;
1514         struct wilc_vif *vif = netdev_priv(dev);
1515         struct wilc_priv *priv = &vif->priv;
1516 
1517         if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1518                 memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
1519                        ETH_ALEN);
1520 
1521                 ret = wilc_add_station(vif, mac, params);
1522                 if (ret)
1523                         netdev_err(dev, "Host add station fail\n");
1524         }
1525 
1526         return ret;
1527 }
1528 
1529 static int del_station(struct wiphy *wiphy, struct net_device *dev,
1530                        struct station_del_parameters *params)
1531 {
1532         const u8 *mac = params->mac;
1533         int ret = 0;
1534         struct wilc_vif *vif = netdev_priv(dev);
1535         struct wilc_priv *priv = &vif->priv;
1536         struct sta_info *info;
1537 
1538         if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
1539                 return ret;
1540 
1541         info = &priv->assoc_stainfo;
1542 
1543         if (!mac)
1544                 ret = wilc_del_allstation(vif, info->sta_associated_bss);
1545 
1546         ret = wilc_del_station(vif, mac);
1547         if (ret)
1548                 netdev_err(dev, "Host delete station fail\n");
1549         return ret;
1550 }
1551 
1552 static int change_station(struct wiphy *wiphy, struct net_device *dev,
1553                           const u8 *mac, struct station_parameters *params)
1554 {
1555         int ret = 0;
1556         struct wilc_vif *vif = netdev_priv(dev);
1557 
1558         if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1559                 ret = wilc_edit_station(vif, mac, params);
1560                 if (ret)
1561                         netdev_err(dev, "Host edit station fail\n");
1562         }
1563         return ret;
1564 }
1565 
1566 static int wilc_get_vif_from_type(struct wilc *wl, int type)
1567 {
1568         int i;
1569 
1570         mutex_lock(&wl->vif_mutex);
1571         for (i = 0; i < wl->vif_num; i++) {
1572                 if (wl->vif[i]->iftype == type) {
1573                         mutex_unlock(&wl->vif_mutex);
1574                         return i;
1575                 }
1576         }
1577         mutex_unlock(&wl->vif_mutex);
1578 
1579         return -EINVAL;
1580 }
1581 
1582 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
1583                                              const char *name,
1584                                              unsigned char name_assign_type,
1585                                              enum nl80211_iftype type,
1586                                              struct vif_params *params)
1587 {
1588         struct wilc *wl = wiphy_priv(wiphy);
1589         struct wilc_vif *vif;
1590         struct wireless_dev *wdev;
1591         int iftype;
1592         int ret;
1593 
1594         if (type == NL80211_IFTYPE_MONITOR) {
1595                 struct net_device *ndev;
1596                 int ap_index = wilc_get_vif_from_type(wl, WILC_AP_MODE);
1597 
1598                 if (ap_index < 0) {
1599                         ap_index = wilc_get_vif_from_type(wl, WILC_GO_MODE);
1600                         if (ap_index < 0)
1601                                 goto validate_interface;
1602                 }
1603 
1604                 vif  = wl->vif[ap_index];
1605                 if (vif->monitor_flag)
1606                         goto validate_interface;
1607 
1608                 ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
1609                 if (ndev)
1610                         vif->monitor_flag = 1;
1611                 else
1612                         return ERR_PTR(-EINVAL);
1613 
1614                 wdev = &vif->priv.wdev;
1615                 return wdev;
1616         }
1617 
1618 validate_interface:
1619         mutex_lock(&wl->vif_mutex);
1620         if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
1621                 pr_err("Reached maximum number of interface\n");
1622                 ret = -EINVAL;
1623                 goto out_err;
1624         }
1625 
1626         switch (type) {
1627         case NL80211_IFTYPE_STATION:
1628                 iftype = WILC_STATION_MODE;
1629                 break;
1630         case NL80211_IFTYPE_AP:
1631                 iftype = WILC_AP_MODE;
1632                 break;
1633         default:
1634                 ret = -EOPNOTSUPP;
1635                 goto out_err;
1636         }
1637 
1638         vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
1639         if (IS_ERR(vif)) {
1640                 ret = PTR_ERR(vif);
1641                 goto out_err;
1642         }
1643 
1644         mutex_unlock(&wl->vif_mutex);
1645 
1646         return &vif->priv.wdev;
1647 
1648 out_err:
1649         mutex_unlock(&wl->vif_mutex);
1650         return ERR_PTR(ret);
1651 }
1652 
1653 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
1654 {
1655         struct wilc *wl = wiphy_priv(wiphy);
1656         struct wilc_vif *vif;
1657         int i;
1658 
1659         if (wdev->iftype == NL80211_IFTYPE_AP ||
1660             wdev->iftype == NL80211_IFTYPE_P2P_GO)
1661                 wilc_wfi_deinit_mon_interface(wl, true);
1662         vif = netdev_priv(wdev->netdev);
1663         cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
1664         unregister_netdevice(vif->ndev);
1665         vif->monitor_flag = 0;
1666 
1667         mutex_lock(&wl->vif_mutex);
1668         wilc_set_operation_mode(vif, 0, 0, 0);
1669         for (i = vif->idx; i < wl->vif_num; i++) {
1670                 if ((i + 1) >= wl->vif_num) {
1671                         wl->vif[i] = NULL;
1672                 } else {
1673                         vif = wl->vif[i + 1];
1674                         vif->idx = i;
1675                         wl->vif[i] = vif;
1676                         wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1677                                                 vif->iftype, vif->idx);
1678                 }
1679         }
1680         wl->vif_num--;
1681         mutex_unlock(&wl->vif_mutex);
1682 
1683         return 0;
1684 }
1685 
1686 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
1687 {
1688         struct wilc *wl = wiphy_priv(wiphy);
1689 
1690         if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
1691                 wl->suspend_event = true;
1692         else
1693                 wl->suspend_event = false;
1694 
1695         return 0;
1696 }
1697 
1698 static int wilc_resume(struct wiphy *wiphy)
1699 {
1700         return 0;
1701 }
1702 
1703 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
1704 {
1705         struct wilc *wl = wiphy_priv(wiphy);
1706         struct wilc_vif *vif;
1707 
1708         mutex_lock(&wl->vif_mutex);
1709         vif = wilc_get_wl_to_vif(wl);
1710         if (IS_ERR(vif)) {
1711                 mutex_unlock(&wl->vif_mutex);
1712                 return;
1713         }
1714 
1715         netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
1716         mutex_unlock(&wl->vif_mutex);
1717 }
1718 
1719 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1720                         enum nl80211_tx_power_setting type, int mbm)
1721 {
1722         int ret;
1723         s32 tx_power = MBM_TO_DBM(mbm);
1724         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1725 
1726         if (tx_power < 0)
1727                 tx_power = 0;
1728         else if (tx_power > 18)
1729                 tx_power = 18;
1730         ret = wilc_set_tx_power(vif, tx_power);
1731         if (ret)
1732                 netdev_err(vif->ndev, "Failed to set tx power\n");
1733 
1734         return ret;
1735 }
1736 
1737 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1738                         int *dbm)
1739 {
1740         int ret;
1741         struct wilc_vif *vif = netdev_priv(wdev->netdev);
1742         struct wilc *wl = vif->wilc;
1743 
1744         /* If firmware is not started, return. */
1745         if (!wl->initialized)
1746                 return -EIO;
1747 
1748         ret = wilc_get_tx_power(vif, (u8 *)dbm);
1749         if (ret)
1750                 netdev_err(vif->ndev, "Failed to get tx power\n");
1751 
1752         return ret;
1753 }
1754 
1755 static const struct cfg80211_ops wilc_cfg80211_ops = {
1756         .set_monitor_channel = set_channel,
1757         .scan = scan,
1758         .connect = connect,
1759         .disconnect = disconnect,
1760         .add_key = add_key,
1761         .del_key = del_key,
1762         .get_key = get_key,
1763         .set_default_key = set_default_key,
1764         .add_virtual_intf = add_virtual_intf,
1765         .del_virtual_intf = del_virtual_intf,
1766         .change_virtual_intf = change_virtual_intf,
1767 
1768         .start_ap = start_ap,
1769         .change_beacon = change_beacon,
1770         .stop_ap = stop_ap,
1771         .add_station = add_station,
1772         .del_station = del_station,
1773         .change_station = change_station,
1774         .get_station = get_station,
1775         .dump_station = dump_station,
1776         .change_bss = change_bss,
1777         .set_wiphy_params = set_wiphy_params,
1778 
1779         .set_pmksa = set_pmksa,
1780         .del_pmksa = del_pmksa,
1781         .flush_pmksa = flush_pmksa,
1782         .remain_on_channel = remain_on_channel,
1783         .cancel_remain_on_channel = cancel_remain_on_channel,
1784         .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
1785         .mgmt_tx = mgmt_tx,
1786         .mgmt_frame_register = wilc_mgmt_frame_register,
1787         .set_power_mgmt = set_power_mgmt,
1788         .set_cqm_rssi_config = set_cqm_rssi_config,
1789 
1790         .suspend = wilc_suspend,
1791         .resume = wilc_resume,
1792         .set_wakeup = wilc_set_wakeup,
1793         .set_tx_power = set_tx_power,
1794         .get_tx_power = get_tx_power,
1795 
1796 };
1797 
1798 static void wlan_init_locks(struct wilc *wl)
1799 {
1800         mutex_init(&wl->hif_cs);
1801         mutex_init(&wl->rxq_cs);
1802         mutex_init(&wl->cfg_cmd_lock);
1803         mutex_init(&wl->vif_mutex);
1804 
1805         spin_lock_init(&wl->txq_spinlock);
1806         mutex_init(&wl->txq_add_to_head_cs);
1807 
1808         init_completion(&wl->txq_event);
1809         init_completion(&wl->cfg_event);
1810         init_completion(&wl->sync_event);
1811         init_completion(&wl->txq_thread_started);
1812 }
1813 
1814 int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
1815                        const struct wilc_hif_func *ops)
1816 {
1817         struct wilc *wl;
1818         struct wilc_vif *vif;
1819         int ret;
1820 
1821         wl = wilc_create_wiphy(dev);
1822         if (!wl)
1823                 return -EINVAL;
1824 
1825         ret = wilc_wlan_cfg_init(wl);
1826         if (ret)
1827                 goto free_wl;
1828 
1829         *wilc = wl;
1830         wl->io_type = io_type;
1831         wl->hif_func = ops;
1832         wl->chip_ps_state = WILC_CHIP_WAKEDUP;
1833         INIT_LIST_HEAD(&wl->txq_head.list);
1834         INIT_LIST_HEAD(&wl->rxq_head.list);
1835 
1836         wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
1837         if (!wl->hif_workqueue) {
1838                 ret = -ENOMEM;
1839                 goto free_cfg;
1840         }
1841         vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
1842                                    NL80211_IFTYPE_STATION, false);
1843         if (IS_ERR(vif)) {
1844                 ret = PTR_ERR(vif);
1845                 goto free_hq;
1846         }
1847 
1848         wlan_init_locks(wl);
1849 
1850         return 0;
1851 
1852 free_hq:
1853         destroy_workqueue(wl->hif_workqueue);
1854 
1855 free_cfg:
1856         wilc_wlan_cfg_deinit(wl);
1857 
1858 free_wl:
1859         wiphy_unregister(wl->wiphy);
1860         wiphy_free(wl->wiphy);
1861         return ret;
1862 }
1863 EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
1864 
1865 struct wilc *wilc_create_wiphy(struct device *dev)
1866 {
1867         struct wiphy *wiphy;
1868         struct wilc *wl;
1869         int ret;
1870 
1871         wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
1872         if (!wiphy)
1873                 return NULL;
1874 
1875         wl = wiphy_priv(wiphy);
1876 
1877         memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
1878         memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
1879         wl->band.bitrates = wl->bitrates;
1880         wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
1881         wl->band.channels = wl->channels;
1882         wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
1883 
1884         wl->band.ht_cap.ht_supported = 1;
1885         wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
1886         wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
1887         wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1888         wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1889 
1890         wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
1891 
1892         wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
1893 #ifdef CONFIG_PM
1894         wiphy->wowlan = &wowlan_support;
1895 #endif
1896         wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
1897         wiphy->max_scan_ie_len = 1000;
1898         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1899         memcpy(wl->cipher_suites, wilc_cipher_suites,
1900                sizeof(wilc_cipher_suites));
1901         wiphy->cipher_suites = wl->cipher_suites;
1902         wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
1903         wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
1904 
1905         wiphy->max_remain_on_channel_duration = 500;
1906         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1907                                 BIT(NL80211_IFTYPE_AP) |
1908                                 BIT(NL80211_IFTYPE_MONITOR) |
1909                                 BIT(NL80211_IFTYPE_P2P_GO) |
1910                                 BIT(NL80211_IFTYPE_P2P_CLIENT);
1911         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1912 
1913         set_wiphy_dev(wiphy, dev);
1914         wl->wiphy = wiphy;
1915         ret = wiphy_register(wiphy);
1916         if (ret) {
1917                 wiphy_free(wiphy);
1918                 return NULL;
1919         }
1920         return wl;
1921 }
1922 
1923 int wilc_init_host_int(struct net_device *net)
1924 {
1925         int ret;
1926         struct wilc_vif *vif = netdev_priv(net);
1927         struct wilc_priv *priv = &vif->priv;
1928 
1929         priv->p2p_listen_state = false;
1930 
1931         mutex_init(&priv->scan_req_lock);
1932         ret = wilc_init(net, &priv->hif_drv);
1933         if (ret)
1934                 netdev_err(net, "Error while initializing hostinterface\n");
1935 
1936         return ret;
1937 }
1938 
1939 void wilc_deinit_host_int(struct net_device *net)
1940 {
1941         int ret;
1942         struct wilc_vif *vif = netdev_priv(net);
1943         struct wilc_priv *priv = &vif->priv;
1944 
1945         priv->p2p_listen_state = false;
1946 
1947         flush_workqueue(vif->wilc->hif_workqueue);
1948         mutex_destroy(&priv->scan_req_lock);
1949         ret = wilc_deinit(vif);
1950 
1951         if (ret)
1952                 netdev_err(net, "Error while deinitializing host interface\n");
1953 }
1954 

/* [<][>][^][v][top][bottom][index][help] */