15e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 25e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Marvell Wireless LAN device driver: functions for station ioctl 35e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 45e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Copyright (C) 2011, Marvell International Ltd. 55e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 65e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This software file (the "File") is distributed by Marvell International 75e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Ltd. under the terms of the GNU General Public License Version 2, June 1991 85e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * (the "License"). You may use, redistribute and/or modify this File in 95e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * accordance with the terms and conditions of the License, a copy of which 105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * is available by writing to the Free Software Foundation, Inc., 115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the 125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * ARE EXPRESSLY DISCLAIMED. The License provides additional details about 175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * this warranty disclaimer. 185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "decl.h" 215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "ioctl.h" 225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "util.h" 235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "fw.h" 245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "main.h" 255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "wmm.h" 265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "11n.h" 275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "cfg80211.h" 285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Copies the multicast address list from device to driver. 315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function does not validate the destination memory for 335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * size, and the calling function must ensure enough memory is 345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * available. 355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 36600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, 37600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar struct net_device *dev) 385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao int i = 0; 405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct netdev_hw_addr *ha; 415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao netdev_for_each_mc_addr(ha, dev) 435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(&mlist->mac_list[i++], ha->addr, ETH_ALEN); 445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return i; 465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Wait queue completion handler. 505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 51600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar * This function waits on a cmd wait queue. It also cancels the pending 52600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar * request after waking up, in case of errors. 535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 54600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) 555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bool cancel_flag = false; 57b7097eb75fa11c302dcdec83f1dbfa874e0af0d1Amitkumar Karwar int status; 58b015dbc0f95eef34819515bd403a62569bca23dfAmitkumar Karwar struct cmd_ctrl_node *cmd_queued; 595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 60b015dbc0f95eef34819515bd403a62569bca23dfAmitkumar Karwar if (!adapter->cmd_queued) 61b015dbc0f95eef34819515bd403a62569bca23dfAmitkumar Karwar return 0; 62b015dbc0f95eef34819515bd403a62569bca23dfAmitkumar Karwar 63b015dbc0f95eef34819515bd403a62569bca23dfAmitkumar Karwar cmd_queued = adapter->cmd_queued; 64efaaa8b8414e0ab4ba09aaaf79ab92a34b75797bAmitkumar Karwar adapter->cmd_queued = NULL; 65b015dbc0f95eef34819515bd403a62569bca23dfAmitkumar Karwar 66600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar dev_dbg(adapter->dev, "cmd pending\n"); 67600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar atomic_inc(&adapter->cmd_pending); 685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 69600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar /* Status pending, wake up main process */ 70600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar queue_work(adapter->workqueue, &adapter->main_work); 715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 72600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar /* Wait for completion */ 73600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar wait_event_interruptible(adapter->cmd_wait_q.wait, 74500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar *(cmd_queued->condition)); 75efaaa8b8414e0ab4ba09aaaf79ab92a34b75797bAmitkumar Karwar if (!*(cmd_queued->condition)) 76600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar cancel_flag = true; 775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 78600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if (cancel_flag) { 79600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar mwifiex_cancel_pending_ioctl(adapter); 80600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar dev_dbg(adapter->dev, "cmd cancel\n"); 815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 82b7097eb75fa11c302dcdec83f1dbfa874e0af0d1Amitkumar Karwar 83b7097eb75fa11c302dcdec83f1dbfa874e0af0d1Amitkumar Karwar status = adapter->cmd_wait_q.status; 84600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar adapter->cmd_wait_q.status = 0; 855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return status; 875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it to set the multicast list. 925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function can be used to enable promiscuous mode, or enable all 945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * multicast packets, or to enable selective multicast. 955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 96600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_request_set_multicast_list(struct mwifiex_private *priv, 97600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar struct mwifiex_multicast_list *mcast_list) 985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao int ret = 0; 1005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 old_pkt_filter; 1015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao old_pkt_filter = priv->curr_pkt_filter; 1035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { 1055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); 1065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; 1075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->curr_pkt_filter &= 1085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; 1095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 1105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Multicast */ 1115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; 1125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) { 1135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, 1145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "info: Enabling All Multicast!\n"); 1155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->curr_pkt_filter |= 1165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; 1175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 1185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->curr_pkt_filter &= 1195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; 1205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (mcast_list->num_multicast_addr) { 1215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, 1225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "info: Set multicast list=%d\n", 1235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao mcast_list->num_multicast_addr); 1245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Set multicast addresses to firmware */ 1255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (old_pkt_filter == priv->curr_pkt_filter) { 1265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Send request to firmware */ 127600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_async(priv, 1285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao HostCmd_CMD_MAC_MULTICAST_ADR, 129600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, 130600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar mcast_list); 1315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 1325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Send request to firmware */ 133600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_async(priv, 1345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao HostCmd_CMD_MAC_MULTICAST_ADR, 135600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, 1365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao mcast_list); 1375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 1385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 1395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 1405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 1415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, 1425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", 1435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao old_pkt_filter, priv->curr_pkt_filter); 1445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (old_pkt_filter != priv->curr_pkt_filter) { 145600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, 146600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 147600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar 0, &priv->curr_pkt_filter); 1485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 1495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 1515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 1525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 1547c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar * This function fills bss descriptor structure using provided 1557c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar * information. 1567c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar */ 1577c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwarint mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, 1587c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar u8 *bssid, s32 rssi, u8 *ie_buf, 1597c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar size_t ie_len, u16 beacon_period, 1605116f3cef206e7fcd6023ba8595a6321f33c2044Amitkumar Karwar u16 cap_info_bitmap, u8 band, 1617c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar struct mwifiex_bssdescriptor *bss_desc) 1627c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar{ 1637c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar int ret; 1647c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 1657c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar memcpy(bss_desc->mac_address, bssid, ETH_ALEN); 1667c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->rssi = rssi; 1677c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->beacon_buf = ie_buf; 1687c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->beacon_buf_size = ie_len; 1697c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->beacon_period = beacon_period; 1707c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->cap_info_bitmap = cap_info_bitmap; 1715116f3cef206e7fcd6023ba8595a6321f33c2044Amitkumar Karwar bss_desc->bss_band = band; 1727c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { 1737c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); 1747c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; 1757c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar } else { 1767c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL; 1777c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar } 1787c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_IBSS) 1797c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->bss_mode = NL80211_IFTYPE_ADHOC; 1807c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar else 1817c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc->bss_mode = NL80211_IFTYPE_STATION; 1827c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 1837c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc, 1847c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ie_buf, ie_len); 1857c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 1867c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar return ret; 1877c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar} 1887c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 1897c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar/* 1905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * In Ad-Hoc mode, the IBSS is created if not found in scan list. 1915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * In both Ad-Hoc and infra mode, an deauthentication is performed 1925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * first. 1935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 1947c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwarint mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, 195b9be5f39bdabb25708a9de294c2cae7bdd8dfb17Amitkumar Karwar struct cfg80211_ssid *req_ssid) 1965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 197270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 1985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_adapter *adapter = priv->adapter; 1997c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar struct mwifiex_bssdescriptor *bss_desc = NULL; 2007c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar u8 *beacon_ie = NULL; 2015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 2025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->scan_block = false; 2037c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 2047c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (bss) { 2057c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar /* Allocate and fill new bss descriptor */ 2067c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), 2077c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar GFP_KERNEL); 2087c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (!bss_desc) { 2097c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar dev_err(priv->adapter->dev, " failed to alloc bss_desc\n"); 2107c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar return -ENOMEM; 2117c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar } 2125982b47aa410e6aef55a5b0087269f5c9c172110Yogesh Ashok Powar 2135982b47aa410e6aef55a5b0087269f5c9c172110Yogesh Ashok Powar beacon_ie = kmemdup(bss->information_elements, 2145982b47aa410e6aef55a5b0087269f5c9c172110Yogesh Ashok Powar bss->len_beacon_ies, GFP_KERNEL); 2157c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (!beacon_ie) { 216aef0ba54ecb961ae559106540f37ab734b64410dDan Carpenter kfree(bss_desc); 2175982b47aa410e6aef55a5b0087269f5c9c172110Yogesh Ashok Powar dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); 2187c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar return -ENOMEM; 2197c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar } 2205982b47aa410e6aef55a5b0087269f5c9c172110Yogesh Ashok Powar 2217c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal, 2227c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar beacon_ie, bss->len_beacon_ies, 2237c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss->beacon_interval, 2245116f3cef206e7fcd6023ba8595a6321f33c2044Amitkumar Karwar bss->capability, 2255116f3cef206e7fcd6023ba8595a6321f33c2044Amitkumar Karwar *(u8 *)bss->priv, bss_desc); 2267c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (ret) 2277c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar goto done; 2287c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar } 2295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 230eecd8250e492ffc4e7b72953cda9c2f3ba0e6cccBing Zhao if (priv->bss_mode == NL80211_IFTYPE_STATION) { 2315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Infra mode */ 232600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_deauthenticate(priv, NULL); 2335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ret) 2347c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar goto done; 2357c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 2367c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_check_network_compatibility(priv, bss_desc); 2377c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (ret) 2387c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar goto done; 2395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 2407c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar dev_dbg(adapter->dev, "info: SSID found in scan list ... " 2417c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar "associating...\n"); 2427c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 2437c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (!netif_queue_stopped(priv->netdev)) 244bbea3bc432dc5c08d09ca5c80afdd82515470688Avinash Patil mwifiex_stop_net_dev_queue(priv->netdev, adapter); 245b7097eb75fa11c302dcdec83f1dbfa874e0af0d1Amitkumar Karwar if (netif_carrier_ok(priv->netdev)) 246b7097eb75fa11c302dcdec83f1dbfa874e0af0d1Amitkumar Karwar netif_carrier_off(priv->netdev); 2475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 2485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Clear any past association response stored for 2495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * application retrieval */ 2505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->assoc_rsp_size = 0; 2517c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_associate(priv, bss_desc); 252a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar 253a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar /* If auth type is auto and association fails using open mode, 254a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar * try to connect using shared mode */ 255a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar if (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG && 256a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar priv->sec_info.is_authtype_auto && 257a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar priv->sec_info.wep_enabled) { 258a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar priv->sec_info.authentication_mode = 259a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar NL80211_AUTHTYPE_SHARED_KEY; 260a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar ret = mwifiex_associate(priv, bss_desc); 261a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar } 262a0f6d6caef4033aa9c3e2ea2ceae256c4347a419Amitkumar Karwar 2637c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (bss) 2647c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar cfg80211_put_bss(bss); 2655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 2665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Adhoc mode */ 2675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* If the requested SSID matches current SSID, return */ 2687c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (bss_desc && bss_desc->ssid.ssid_len && 269500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. 270500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar ssid, &bss_desc->ssid))) { 2717c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar kfree(bss_desc); 2727c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar kfree(beacon_ie); 2735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 2747c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar } 2755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 2765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Exit Adhoc mode first */ 2775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); 278600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_deauthenticate(priv, NULL); 2795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ret) 2807c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar goto done; 2815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 2825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->adhoc_is_link_sensed = false; 2835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 2847c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_check_network_compatibility(priv, bss_desc); 2857c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 2867c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (!netif_queue_stopped(priv->netdev)) 287bbea3bc432dc5c08d09ca5c80afdd82515470688Avinash Patil mwifiex_stop_net_dev_queue(priv->netdev, adapter); 288b7097eb75fa11c302dcdec83f1dbfa874e0af0d1Amitkumar Karwar if (netif_carrier_ok(priv->netdev)) 289b7097eb75fa11c302dcdec83f1dbfa874e0af0d1Amitkumar Karwar netif_carrier_off(priv->netdev); 2907c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 2917c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (!ret) { 2925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(adapter->dev, "info: network found in scan" 2935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao " list. Joining...\n"); 2947c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_adhoc_join(priv, bss_desc); 2957c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (bss) 2967c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar cfg80211_put_bss(bss); 297636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar } else { 2985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(adapter->dev, "info: Network not found in " 2995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "the list, creating adhoc with ssid = %s\n", 3007c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar req_ssid->ssid); 3017c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_adhoc_start(priv, req_ssid); 3025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 3035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 3045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 3057c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwardone: 3067c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar kfree(bss_desc); 3077c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar kfree(beacon_ie); 3085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 3095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 3105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 3115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 3125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set host sleep configuration. 3135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 3145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 3155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it. 3165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 317711825a06bb288e04f8236d77c4e12eba9a1c478Amitkumar Karwarstatic int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, 318711825a06bb288e04f8236d77c4e12eba9a1c478Amitkumar Karwar int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) 319600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar 3205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 3215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_adapter *adapter = priv->adapter; 3225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao int status = 0; 3235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u32 prev_cond = 0; 3245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 325600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if (!hs_cfg) 326600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar return -ENOMEM; 327600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar 3285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao switch (action) { 3295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case HostCmd_ACT_GEN_SET: 3305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (adapter->pps_uapsd_mode) { 3315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(adapter->dev, "info: Host Sleep IOCTL" 3325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao " is blocked in UAPSD/PPS mode\n"); 3335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao status = -1; 3345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 3355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 3365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (hs_cfg->is_invoke_hostcmd) { 3375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) { 3385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!adapter->is_hs_configured) 3395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Already cancelled */ 3405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 3415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Save previous condition */ 3425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao prev_cond = le32_to_cpu(adapter->hs_cfg 3435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao .conditions); 3445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.conditions = 3455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cpu_to_le32(hs_cfg->conditions); 3465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else if (hs_cfg->conditions) { 3475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.conditions = 3485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cpu_to_le32(hs_cfg->conditions); 3495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; 3505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (hs_cfg->gap) 3515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.gap = (u8)hs_cfg->gap; 352500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar } else if (adapter->hs_cfg.conditions 353500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { 3545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Return failure if no parameters for HS 3555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao enable */ 3565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao status = -1; 3575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 3585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 359600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if (cmd_type == MWIFIEX_SYNC_CMD) 360600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_send_cmd_sync(priv, 361600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_CMD_802_11_HS_CFG_ENH, 362600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, 363600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar &adapter->hs_cfg); 364600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar else 365600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_send_cmd_async(priv, 366600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_CMD_802_11_HS_CFG_ENH, 367600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, 368600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar &adapter->hs_cfg); 3695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) 3705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Restore previous condition */ 3715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.conditions = 3725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cpu_to_le32(prev_cond); 3735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 3745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.conditions = 375500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar cpu_to_le32(hs_cfg->conditions); 3765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; 3775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_cfg.gap = (u8)hs_cfg->gap; 3785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 3795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 3805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case HostCmd_ACT_GEN_GET: 3815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao hs_cfg->conditions = le32_to_cpu(adapter->hs_cfg.conditions); 3825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao hs_cfg->gpio = adapter->hs_cfg.gpio; 3835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao hs_cfg->gap = adapter->hs_cfg.gap; 3845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 3855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao default: 3865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao status = -1; 3875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 3885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 3895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 3905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return status; 3915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 3925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 3935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 3945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to cancel the existing Host Sleep configuration. 3955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 3965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 3975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 3985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 399600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type) 4005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 4015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_hs_cfg hscfg; 4025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao hscfg.conditions = HOST_SLEEP_CFG_CANCEL; 4045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao hscfg.is_invoke_hostcmd = true; 4055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 406636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, 407636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar cmd_type, &hscfg); 4085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 4095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing ZhaoEXPORT_SYMBOL_GPL(mwifiex_cancel_hs); 4105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 4125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to cancel the existing Host Sleep configuration. 4135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 4145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 4155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 4165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 4175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint mwifiex_enable_hs(struct mwifiex_adapter *adapter) 4185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 4195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_hs_cfg hscfg; 4205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (adapter->hs_activated) { 4225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(adapter->dev, "cmd: HS Already actived\n"); 4235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return true; 4245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 4255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->hs_activate_wait_q_woken = false; 4275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 428b093863edd20b64fa444b770a8701ddcbe9faea1Amitkumar Karwar memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); 4295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao hscfg.is_invoke_hostcmd = true; 4305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, 432500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar MWIFIEX_BSS_ROLE_STA), 433600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, 434600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar &hscfg)) { 4355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(adapter->dev, "IOCTL request HS enable failed\n"); 4365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return false; 4375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 4385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao wait_event_interruptible(adapter->hs_activate_wait_q, 440500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar adapter->hs_activate_wait_q_woken); 4415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return true; 4435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 4445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing ZhaoEXPORT_SYMBOL_GPL(mwifiex_enable_hs); 4455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 4475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to get BSS information. 4485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 4495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function collates the information from different driver structures 4505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * to send to the user. 4515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 4525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint mwifiex_get_bss_info(struct mwifiex_private *priv, 4535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_bss_info *info) 4545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 4555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_adapter *adapter = priv->adapter; 4565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_bssdescriptor *bss_desc; 4575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!info) 4595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 4605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bss_desc = &priv->curr_bss_params.bss_descriptor; 4625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->bss_mode = priv->bss_mode; 4645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 465b9be5f39bdabb25708a9de294c2cae7bdd8dfb17Amitkumar Karwar memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid)); 4665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); 4685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->bss_chan = bss_desc->channel; 4705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->region_code = adapter->region_code; 4725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->media_connected = priv->media_connected; 4745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->max_power_level = priv->max_tx_power_level; 4765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->min_power_level = priv->min_tx_power_level; 4775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->adhoc_state = priv->adhoc_state; 4795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->bcn_nf_last = priv->bcn_nf_last; 4815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4825eb02e44adc92a71bae3ff60acb1eea5ada14e93Amitkumar Karwar if (priv->sec_info.wep_enabled) 4835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->wep_status = true; 4845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else 4855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->wep_status = false; 4865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->is_hs_configured = adapter->is_hs_configured; 4885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao info->is_deep_sleep = adapter->is_deep_sleep; 4895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 4915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 4925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 4935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 494a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar * The function disables auto deep sleep mode. 495a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar */ 496a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwarint mwifiex_disable_auto_ds(struct mwifiex_private *priv) 497a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar{ 498a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar struct mwifiex_ds_auto_ds auto_ds; 499a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar 500a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar auto_ds.auto_ds = DEEP_SLEEP_OFF; 501a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar 502a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 503a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds); 504a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar} 505a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar KarwarEXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds); 506a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar 507a0490936007bacf5bf6f4fb27788550c89c2c70dAmitkumar Karwar/* 5085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set/get active channel. 5095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 5105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function performs validity checking on channel/frequency 5115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * compatibility and returns failure if not valid. 5125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 513600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_bss_set_channel(struct mwifiex_private *priv, 514600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar struct mwifiex_chan_freq_power *chan) 5155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 5165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_adapter *adapter = priv->adapter; 5175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_chan_freq_power *cfp = NULL; 5185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 5195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!chan) 5205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 5215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 5225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!chan->channel && !chan->freq) 5235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 5245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (adapter->adhoc_start_band & BAND_AN) 5255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN; 5265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else if (adapter->adhoc_start_band & BAND_A) 5275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->adhoc_start_band = BAND_G | BAND_B; 5285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (chan->channel) { 5295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (chan->channel <= MAX_CHANNEL_BAND_BG) 5306685d109f4b60604fd206cff01355094a2e3b419Yogesh Ashok Powar cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0); 5315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!cfp) { 5326685d109f4b60604fd206cff01355094a2e3b419Yogesh Ashok Powar cfp = mwifiex_get_cfp(priv, BAND_A, 5336685d109f4b60604fd206cff01355094a2e3b419Yogesh Ashok Powar (u16) chan->channel, 0); 5345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (cfp) { 5355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (adapter->adhoc_11n_enabled) 5365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->adhoc_start_band = BAND_A 537500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar | BAND_AN; 5385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else 5395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->adhoc_start_band = BAND_A; 5405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 5435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (chan->freq <= MAX_FREQUENCY_BAND_BG) 5446685d109f4b60604fd206cff01355094a2e3b419Yogesh Ashok Powar cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq); 5455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!cfp) { 5466685d109f4b60604fd206cff01355094a2e3b419Yogesh Ashok Powar cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq); 5475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (cfp) { 5485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (adapter->adhoc_11n_enabled) 5495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->adhoc_start_band = BAND_A 550500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar | BAND_AN; 5515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else 5525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->adhoc_start_band = BAND_A; 5535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!cfp || !cfp->channel) { 5575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(adapter->dev, "invalid channel/freq\n"); 5585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 5595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->adhoc_channel = (u8) cfp->channel; 5615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao chan->channel = cfp->channel; 5625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao chan->freq = cfp->freq; 5635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 5645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 5655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 5665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 5675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 5685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set/get Ad-Hoc channel. 5695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 5705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 5715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it to set or get the ad-hoc channel. 5725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 5735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, 5745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 action, u16 *channel) 5755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 5765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (action == HostCmd_ACT_GEN_GET) { 5775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!priv->media_connected) { 5785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *channel = priv->adhoc_channel; 579636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return 0; 5805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 5825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->adhoc_channel = (u8) *channel; 5835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 5845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 585636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, 586500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar action, 0, channel); 5875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 5885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 5895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 5905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to change Ad-Hoc channel. 5915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 5925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 5935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 5945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 5955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * The function follows the following steps to perform the change - 5965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Get current IBSS information 5975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Get current channel 5985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - If no change is required, return 5995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - If not connected, change channel and return 6005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - If connected, 6015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Disconnect 6025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Change channel 6035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Perform specific SSID scan with same SSID 6045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Start/Join the IBSS 6055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 6065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 607380aeef8941c6b8a3e8de86b5ca000ca986e3b17Dan Carpentermwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) 6085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 609270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 6105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_bss_info bss_info; 6115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ssid_bssid ssid_bssid; 6125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 curr_chan = 0; 6137c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar struct cfg80211_bss *bss = NULL; 6147c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar struct ieee80211_channel *chan; 6154ed5d521b062b7256dcfe46a3194f89ff44fdc66Amitkumar Karwar enum ieee80211_band band; 6165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(&bss_info, 0, sizeof(bss_info)); 6185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Get BSS information */ 6205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (mwifiex_get_bss_info(priv, &bss_info)) 6215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 6225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Get current channel */ 624600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET, 625600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar &curr_chan); 6265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (curr_chan == channel) { 6285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ret = 0; 6295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao goto done; 6305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 6315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", 632500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar curr_chan, channel); 6335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!bss_info.media_connected) { 6355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ret = 0; 6365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao goto done; 6375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 6385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Do disonnect */ 6405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(&ssid_bssid, 0, ETH_ALEN); 641600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); 6425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 643600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, 644380aeef8941c6b8a3e8de86b5ca000ca986e3b17Dan Carpenter &channel); 6455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Do specific SSID scanning */ 647600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if (mwifiex_request_scan(priv, &bss_info.ssid)) { 6485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ret = -1; 6495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao goto done; 6505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 6515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6524ed5d521b062b7256dcfe46a3194f89ff44fdc66Amitkumar Karwar band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 6537c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar chan = __ieee80211_get_channel(priv->wdev->wiphy, 654500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar ieee80211_channel_to_frequency(channel, 655500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar band)); 6567c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 6577c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar /* Find the BSS we want using available scan results */ 6587c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, 6597c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar bss_info.ssid.ssid, bss_info.ssid.ssid_len, 6607c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 6617c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar if (!bss) 6627c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n", 663500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar bss_info.bssid); 6647c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar 6657c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437Amitkumar Karwar ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); 6665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaodone: 6675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 6685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 6695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 6715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to get rate. 6725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 6735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 6745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it to get the current rate if it is connected, 6755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * otherwise, the function returns the lowest supported rate 6765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * for the band. 6775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 6785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, 6795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_rate_cfg *rate_cfg) 6805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 6815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate_cfg->is_rate_auto = priv->is_data_rate_auto; 682cbaaf592b742ccecfd066e796cdb1eda461f4db2Amitkumar Karwar return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, 683cbaaf592b742ccecfd066e796cdb1eda461f4db2Amitkumar Karwar HostCmd_ACT_GEN_GET, 0, NULL); 6845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 6855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 6865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 6875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set rate. 6885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 6895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 6905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it to set the current rate. 6915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 6925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * The function also performs validation checking on the supplied value. 6935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 6945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, 6955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_rate_cfg *rate_cfg) 6965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 6975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u8 rates[MWIFIEX_SUPPORTED_RATES]; 698270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar u8 *rate; 699270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int rate_index, ret; 7005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; 701270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar u32 i; 7025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_adapter *adapter = priv->adapter; 7035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (rate_cfg->is_rate_auto) { 7055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(bitmap_rates, 0, sizeof(bitmap_rates)); 7065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Support all HR/DSSS rates */ 7075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bitmap_rates[0] = 0x000F; 7085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Support all OFDM rates */ 7095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bitmap_rates[1] = 0x00FF; 7105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Support all HT-MCSs rate */ 7115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates) - 3; i++) 7125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bitmap_rates[i + 2] = 0xFFFF; 7135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bitmap_rates[9] = 0x3FFF; 7145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 7155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(rates, 0, sizeof(rates)); 7165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao mwifiex_get_active_data_rates(priv, rates); 7175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate = rates; 7185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao for (i = 0; (rate[i] && i < MWIFIEX_SUPPORTED_RATES); i++) { 7195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(adapter->dev, "info: rate=%#x wanted=%#x\n", 7205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate[i], rate_cfg->rate); 7215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f)) 7225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 7235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 7243d82de0fa584fbe73cf74a3bbc906c8710c523b8Yogesh Ashok Powar if ((i == MWIFIEX_SUPPORTED_RATES) || !rate[i]) { 7255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(adapter->dev, "fixed data rate %#x is out " 7265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "of range\n", rate_cfg->rate); 7275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 7285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 7295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(bitmap_rates, 0, sizeof(bitmap_rates)); 7305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 731572e8f3ead47ad223fb428a4f1db986317e8e0ecAmitkumar Karwar rate_index = mwifiex_data_rate_to_index(rate_cfg->rate); 7325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Only allow b/g rates to be set */ 7345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && 7355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate_index <= MWIFIEX_RATE_INDEX_HRDSSS3) { 7365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bitmap_rates[0] = 1 << rate_index; 7375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 7385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate_index -= 1; /* There is a 0x00 in the table */ 7395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (rate_index >= MWIFIEX_RATE_INDEX_OFDM0 && 7405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate_index <= MWIFIEX_RATE_INDEX_OFDM7) 7415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao bitmap_rates[1] = 1 << (rate_index - 7425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao MWIFIEX_RATE_INDEX_OFDM0); 7435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 7445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 7455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 746600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, 747600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, bitmap_rates); 7485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 7505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 7515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 7535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set/get rate. 7545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 7555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function can be used to set/get either the rate value or the 7565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * rate index. 7575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 7585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, 7595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_rate_cfg *rate_cfg) 7605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 761270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int status; 7625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!rate_cfg) 7645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 7655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (rate_cfg->action == HostCmd_ACT_GEN_GET) 767600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg); 7685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else 769600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg); 7705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return status; 7725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 7735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 7755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to get the data rate. 7765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 7775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 7785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 7795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 7805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint mwifiex_drv_get_data_rate(struct mwifiex_private *priv, 7815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_rate_cfg *rate) 7825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 783270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 7845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); 7865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate->action = HostCmd_ACT_GEN_GET; 787600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_rate_ioctl_cfg(priv, rate); 7885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 7895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!ret) { 79049753128d8fc976576c497c81962cf1ae57174aaDan Carpenter if (rate->is_rate_auto) 791e3bea1c8751d297c197949db01aa1e7adbc1104dBing Zhao rate->rate = mwifiex_index_to_data_rate(priv, 792500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar priv->tx_rate, 793500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar priv->tx_htinfo 794500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar ); 79549753128d8fc976576c497c81962cf1ae57174aaDan Carpenter else 7965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rate->rate = priv->data_rate; 7975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 7985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ret = -1; 7995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 8005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 8015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 8025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 8035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 8045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 8055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set tx power configuration. 8065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 8075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 8085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it. 8095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 8105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * For non-auto power mode, all the following power groups are set - 8115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Modulation class HR/DSSS 8125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Modulation class OFDM 8135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Modulation class HTBW20 8145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - Modulation class HTBW40 8155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 816600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_set_tx_power(struct mwifiex_private *priv, 817600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar struct mwifiex_power_cfg *power_cfg) 8185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 819270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 820270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar struct host_cmd_ds_txpwr_cfg *txp_cfg; 821270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar struct mwifiex_types_power_group *pg_tlv; 822270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar struct mwifiex_power_group *pg; 823270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar u8 *buf; 8245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 dbm = 0; 8255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 8265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!power_cfg->is_power_auto) { 8275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dbm = (u16) power_cfg->power_level; 8285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if ((dbm < priv->min_tx_power_level) || 8295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao (dbm > priv->max_tx_power_level)) { 8305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(priv->adapter->dev, "txpower value %d dBm" 831500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar " is out of range (%d dBm-%d dBm)\n", 832500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar dbm, priv->min_tx_power_level, 833500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar priv->max_tx_power_level); 8345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 8355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 8365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 8375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); 8385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!buf) { 8395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", 840500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar __func__); 841b53575ecf939a4f752de87eabf1adbcfa4478a6cChristoph Fritz return -ENOMEM; 8425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 8435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 8445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf; 8455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); 8465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!power_cfg->is_power_auto) { 8475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao txp_cfg->mode = cpu_to_le32(1); 848500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar pg_tlv = (struct mwifiex_types_power_group *) 849500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar (buf + sizeof(struct host_cmd_ds_txpwr_cfg)); 8505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg_tlv->type = TLV_TYPE_POWER_GROUP; 8515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); 852500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar pg = (struct mwifiex_power_group *) 853500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar (buf + sizeof(struct host_cmd_ds_txpwr_cfg) 854500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar + sizeof(struct mwifiex_types_power_group)); 8555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Power group for modulation class HR/DSSS */ 8565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->first_rate_code = 0x00; 8575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->last_rate_code = 0x03; 8585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->modulation_class = MOD_CLASS_HR_DSSS; 8595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_step = 0; 8605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_min = (s8) dbm; 8615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_max = (s8) dbm; 8625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg++; 8635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Power group for modulation class OFDM */ 8645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->first_rate_code = 0x00; 8655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->last_rate_code = 0x07; 8665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->modulation_class = MOD_CLASS_OFDM; 8675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_step = 0; 8685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_min = (s8) dbm; 8695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_max = (s8) dbm; 8705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg++; 8715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Power group for modulation class HTBW20 */ 8725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->first_rate_code = 0x00; 8735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->last_rate_code = 0x20; 8745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->modulation_class = MOD_CLASS_HT; 8755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_step = 0; 8765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_min = (s8) dbm; 8775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_max = (s8) dbm; 8785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->ht_bandwidth = HT_BW_20; 8795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg++; 8805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Power group for modulation class HTBW40 */ 8815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->first_rate_code = 0x00; 8825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->last_rate_code = 0x20; 8835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->modulation_class = MOD_CLASS_HT; 8845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_step = 0; 8855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_min = (s8) dbm; 8865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->power_max = (s8) dbm; 8875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pg->ht_bandwidth = HT_BW_40; 8885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 889600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, 890600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, buf); 8915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 892600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar kfree(buf); 8935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 8945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 8955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 8965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 8975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to get power save mode. 8985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 8995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 9005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it. 9015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 902600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) 9035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 904270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 9055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_adapter *adapter = priv->adapter; 9065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 sub_cmd; 9075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 908600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if (*ps_mode) 909600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; 910600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar else 911600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; 912600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; 913600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 914600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar sub_cmd, BITMAP_STA_PS, NULL); 915600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if ((!ret) && (sub_cmd == DIS_AUTO_PS)) 916600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_async(priv, 917500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_CMD_802_11_PS_MODE_ENH, 918500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar GET_PS, 0, NULL); 9195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 9205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 9215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 9225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 9235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 9245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set/reset WPA IE. 9255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 9265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * The supplied WPA IE is treated as a opaque buffer. Only the first field 9275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * is checked to determine WPA version. If buffer length is zero, the existing 9285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * WPA IE is reset. 9295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 9305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, 9315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u8 *ie_data_ptr, u16 ie_len) 9325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 9335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ie_len) { 9345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ie_len > sizeof(priv->wpa_ie)) { 9355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(priv->adapter->dev, 9365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "failed to copy WPA IE, too big\n"); 9375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 9385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 9395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(priv->wpa_ie, ie_data_ptr, ie_len); 9405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wpa_ie_len = (u8) ie_len; 9415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", 942500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar priv->wpa_ie_len, priv->wpa_ie[0]); 9435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 9445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (priv->wpa_ie[0] == WLAN_EID_WPA) { 9455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wpa_enabled = true; 9465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else if (priv->wpa_ie[0] == WLAN_EID_RSN) { 9475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wpa2_enabled = true; 9485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 9495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wpa_enabled = false; 9505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wpa2_enabled = false; 9515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 9525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 9535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(priv->wpa_ie, 0, sizeof(priv->wpa_ie)); 9545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wpa_ie_len = 0; 9555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, "info: reset wpa_ie_len=%d IE=%#x\n", 9565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wpa_ie_len, priv->wpa_ie[0]); 9575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wpa_enabled = false; 9585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wpa2_enabled = false; 9595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 9605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 9615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 9625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 9635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 9645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 9655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set/reset WAPI IE. 9665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 9675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * The supplied WAPI IE is treated as a opaque buffer. Only the first field 9685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * is checked to internally enable WAPI. If buffer length is zero, the existing 9695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * WAPI IE is reset. 9705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 9715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_set_wapi_ie(struct mwifiex_private *priv, 9725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u8 *ie_data_ptr, u16 ie_len) 9735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 9745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ie_len) { 9755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ie_len > sizeof(priv->wapi_ie)) { 9765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, 9775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "info: failed to copy WAPI IE, too big\n"); 9785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 9795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 9805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(priv->wapi_ie, ie_data_ptr, ie_len); 9815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wapi_ie_len = ie_len; 9825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n", 983500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar priv->wapi_ie_len, priv->wapi_ie[0]); 9845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 9855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) 9865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wapi_enabled = true; 9875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 9885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(priv->wapi_ie, 0, sizeof(priv->wapi_ie)); 9895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wapi_ie_len = ie_len; 9905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, 9915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "info: Reset wapi_ie_len=%d IE=%#x\n", 9925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wapi_ie_len, priv->wapi_ie[0]); 9935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->sec_info.wapi_enabled = false; 9945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 9955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 9965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 9975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 9985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 9995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set WAPI key. 10005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 10015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 10025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it. 10035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 1004600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarstatic int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, 10055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_encrypt_key *encrypt_key) 10065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 10075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1008636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 1009500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, 1010500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar encrypt_key); 10115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 10125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 10135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 10145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set WEP network key. 10155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 10165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 10175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it, after validation checks. 10185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 1019600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarstatic int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, 10205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_encrypt_key *encrypt_key) 10215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 1022270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 1023270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar struct mwifiex_wep_key *wep_key; 10245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao int index; 10255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 10265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (priv->wep_key_curr_index >= NUM_WEP_KEYS) 10275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wep_key_curr_index = 0; 10285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao wep_key = &priv->wep_key[priv->wep_key_curr_index]; 10295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao index = encrypt_key->key_index; 10305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (encrypt_key->key_disable) { 10315eb02e44adc92a71bae3ff60acb1eea5ada14e93Amitkumar Karwar priv->sec_info.wep_enabled = 0; 10325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else if (!encrypt_key->key_len) { 10335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Copy the required key as the current key */ 10345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao wep_key = &priv->wep_key[index]; 10355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!wep_key->key_length) { 1036600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar dev_err(priv->adapter->dev, 10375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "key not set, so cannot enable it\n"); 10385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 10395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 10405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wep_key_curr_index = (u16) index; 10415eb02e44adc92a71bae3ff60acb1eea5ada14e93Amitkumar Karwar priv->sec_info.wep_enabled = 1; 10425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 10435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao wep_key = &priv->wep_key[index]; 10445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); 10455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Copy the key in the driver */ 10465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(wep_key->key_material, 10475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key->key_material, 10485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key->key_len); 10495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao wep_key->key_index = index; 10505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao wep_key->key_length = encrypt_key->key_len; 10515eb02e44adc92a71bae3ff60acb1eea5ada14e93Amitkumar Karwar priv->sec_info.wep_enabled = 1; 10525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 10535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (wep_key->key_length) { 10545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Send request to firmware */ 1055600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_async(priv, 1056600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_CMD_802_11_KEY_MATERIAL, 1057600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, NULL); 10585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ret) 10595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 10605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 10615eb02e44adc92a71bae3ff60acb1eea5ada14e93Amitkumar Karwar if (priv->sec_info.wep_enabled) 10625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; 10635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else 10645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; 10655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1066600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, 1067600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_SET, 0, 1068600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar &priv->curr_pkt_filter); 10695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 10705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 10715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 10725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 10735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 10745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set WPA key. 10755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 10765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 10775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it, after validation checks. 10785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 10795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Current driver only supports key length of up to 32 bytes. 10805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 10815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function can also be used to disable a currently set key. 10825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 1083600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarstatic int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, 10845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_encrypt_key *encrypt_key) 10855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 1086270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 10875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u8 remove_key = false; 10885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct host_cmd_ds_802_11_key_material *ibss_key; 10895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 10905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Current driver only supports key length of up to 32 bytes */ 1091a37316586d926a10d66b5585c5d91683d6468f68Amitkumar Karwar if (encrypt_key->key_len > WLAN_MAX_KEY_LEN) { 1092600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar dev_err(priv->adapter->dev, "key length too long\n"); 10935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 10945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 10955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1096eecd8250e492ffc4e7b72953cda9c2f3ba0e6cccBing Zhao if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 10975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* 10985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IBSS/WPA-None uses only one key (Group) for both receiving 10995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * and sending unicast and multicast packets. 11005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 11015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Send the key as PTK to firmware */ 11025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 1103600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_async(priv, 1104500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_CMD_802_11_KEY_MATERIAL, 1105500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_ACT_GEN_SET, 1106500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar KEY_INFO_ENABLED, encrypt_key); 11075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ret) 11085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 11095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ibss_key = &priv->aes_key; 11115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(ibss_key, 0, 11125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao sizeof(struct host_cmd_ds_802_11_key_material)); 11135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Copy the key in the driver */ 11145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(ibss_key->key_param_set.key, encrypt_key->key_material, 11155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key->key_len); 11165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(&ibss_key->key_param_set.key_len, &encrypt_key->key_len, 11175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao sizeof(ibss_key->key_param_set.key_len)); 11185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ibss_key->key_param_set.key_type_id 11195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao = cpu_to_le16(KEY_TYPE_ID_TKIP); 11206a35a0ac5771fa962c45926678d1f194cbc98c4eYogesh Ashok Powar ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED); 11215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Send the key as GTK to firmware */ 11235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; 11245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 11255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!encrypt_key->key_index) 11275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 11285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (remove_key) 1130600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_sync(priv, 1131500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_CMD_802_11_KEY_MATERIAL, 1132500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_ACT_GEN_SET, 1133500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar !KEY_INFO_ENABLED, encrypt_key); 11345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else 1135600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_sync(priv, 1136500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_CMD_802_11_KEY_MATERIAL, 1137500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_ACT_GEN_SET, 1138500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar KEY_INFO_ENABLED, encrypt_key); 11395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 11415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 11425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 11445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set/get network keys. 11455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 11465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This is a generic key handling function which supports WEP, WPA 11475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * and WAPI. 11485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 11495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int 11505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, 11515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_encrypt_key *encrypt_key) 11525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 1153270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int status; 11545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (encrypt_key->is_wapi_key) 1156600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key); 11575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) 1158600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key); 11595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao else 1160600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key); 11615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return status; 11625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 11635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 11655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function returns the driver version. 11665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 11675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 11685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, 11695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao int max_len) 11705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 11715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao union { 11725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u32 l; 11735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u8 c[4]; 11745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } ver; 11755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao char fw_ver[32]; 11765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ver.l = adapter->fw_release_number; 11785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]); 11795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao snprintf(version, max_len, driver_version, fw_ver); 11815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(adapter->dev, "info: MWIFIEX VERSION: %s\n", version); 11835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 11855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 11865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 11875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 11885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to get signal information. 11895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 11905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 11915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 11925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 1193600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwarint mwifiex_get_signal_info(struct mwifiex_private *priv, 11945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_get_signal *signal) 11955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 1196270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int status; 11975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1198c4859fbcfc12d5cfe8c30a33ad37d192a3093a7bAmitkumar Karwar signal->selector = ALL_RSSI_INFO_MASK; 11995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1200600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar /* Signal info can be obtained only if connected */ 1201600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if (!priv->media_connected) { 1202600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar dev_dbg(priv->adapter->dev, 1203600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar "info: Can not get signal in disconnected state\n"); 1204600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar return -1; 1205600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar } 1206600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar 1207600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, 1208600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_GET, 0, signal); 12095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!status) { 1211c4859fbcfc12d5cfe8c30a33ad37d192a3093a7bAmitkumar Karwar if (signal->selector & BCN_RSSI_AVG_MASK) 121267a50035b3f9335b9e5800c32149173e797b9cc0Bing Zhao priv->qual_level = signal->bcn_rssi_avg; 1213c4859fbcfc12d5cfe8c30a33ad37d192a3093a7bAmitkumar Karwar if (signal->selector & BCN_NF_AVG_MASK) 121467a50035b3f9335b9e5800c32149173e797b9cc0Bing Zhao priv->qual_noise = signal->bcn_nf_avg; 12155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 12165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return status; 12185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 12195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 12215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to set encoding parameters. 12225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 12235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 12245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 12255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 12265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, 12275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao int key_len, u8 key_index, int disable) 12285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 12295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_encrypt_key encrypt_key; 12305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); 12325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key.key_len = key_len; 12335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!disable) { 12345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key.key_index = key_index; 12355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (key_len) 12365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(encrypt_key.key_material, key, key_len); 12375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 12385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao encrypt_key.key_disable = true; 12395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 12405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1241636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); 12425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 12435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 12455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to get extended version. 12465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 12475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 12485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 12495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 12505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 12515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_get_ver_ext(struct mwifiex_private *priv) 12525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 12535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ver_ext ver_ext; 12545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); 1256636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, 1257500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_ACT_GEN_GET, 0, &ver_ext)) 1258636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return -1; 12595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1260636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return 0; 12615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 12625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 12645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to get statistics information. 12655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 12665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 12675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 12685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 12695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 12705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_get_stats_info(struct mwifiex_private *priv, 12715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_get_stats *log) 12725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 127367a50035b3f9335b9e5800c32149173e797b9cc0Bing Zhao return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, 1274500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar HostCmd_ACT_GEN_GET, 0, log); 12755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 12765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 12785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to read/write register. 12795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 12805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function prepares the correct firmware command and 12815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * issues it. 12825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 12835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Access to the following registers are supported - 12845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - MAC 12855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - BBP 12865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - RF 12875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - PMIC 12885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * - CAU 12895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 12905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, 12915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_reg_rw *reg_rw, 12925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 action) 12935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 12945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 cmd_no; 12955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 12965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao switch (le32_to_cpu(reg_rw->type)) { 12975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case MWIFIEX_REG_MAC: 12985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cmd_no = HostCmd_CMD_MAC_REG_ACCESS; 12995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 13005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case MWIFIEX_REG_BBP: 13015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cmd_no = HostCmd_CMD_BBP_REG_ACCESS; 13025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 13035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case MWIFIEX_REG_RF: 13045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cmd_no = HostCmd_CMD_RF_REG_ACCESS; 13055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 13065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case MWIFIEX_REG_PMIC: 13075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cmd_no = HostCmd_CMD_PMIC_REG_ACCESS; 13085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 13095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case MWIFIEX_REG_CAU: 13105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao cmd_no = HostCmd_CMD_CAU_REG_ACCESS; 13115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 13125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao default: 13135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 13145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 13155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1316636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); 13175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 13195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 13215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to write to a register. 13225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 13235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 13245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 13255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 13265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 13275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, 13285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u32 reg_offset, u32 reg_value) 13295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 13305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_reg_rw reg_rw; 13315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao reg_rw.type = cpu_to_le32(reg_type); 13335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao reg_rw.offset = cpu_to_le32(reg_offset); 13345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao reg_rw.value = cpu_to_le32(reg_value); 13355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1336636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar return mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); 13375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 13385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 13405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to read from a register. 13415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 13425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 13435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 13445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 13455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 13465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, 13475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u32 reg_offset, u32 *value) 13485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 1349270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 13505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_reg_rw reg_rw; 13515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao reg_rw.type = cpu_to_le32(reg_type); 13535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao reg_rw.offset = cpu_to_le32(reg_offset); 1354600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); 13555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ret) 13575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao goto done; 13585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *value = le32_to_cpu(reg_rw.value); 13605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaodone: 13625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 13635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 13645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 13665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to read from EEPROM. 13675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 13685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 13695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 13705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 13715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 13725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, 13735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u8 *value) 13745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 1375270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar int ret; 13765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_read_eeprom rd_eeprom; 13775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rd_eeprom.offset = cpu_to_le16((u16) offset); 13795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao rd_eeprom.byte_count = cpu_to_le16((u16) bytes); 13805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1381600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar /* Send request to firmware */ 1382600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, 1383600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar HostCmd_ACT_GEN_GET, 0, &rd_eeprom); 13845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 1385600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar if (!ret) 1386600f5d909a54a8dccf8c8c23898fc2e91bc0953eAmitkumar Karwar memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); 13875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 13885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 13895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 13905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 13915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function sets a generic IE. In addition to generic IE, it can 13925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * also handle WPA, WPA2 and WAPI IEs. 13935e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 13945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int 13955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, 13965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 ie_len) 13975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 13985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao int ret = 0; 13995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct ieee_types_vendor_header *pvendor_ie; 14005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao const u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 }; 14015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao const u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 }; 14025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* If the passed length is zero, reset the buffer */ 14045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (!ie_len) { 14055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->gen_ie_buf_len = 0; 14065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wps.session_enable = false; 14075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 14095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else if (!ie_data_ptr) { 14105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 14115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 14125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; 14135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Test to see if it is a WPA IE, if not, then it is a gen IE */ 1414500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar if (((pvendor_ie->element_id == WLAN_EID_WPA) && 1415500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || 1416500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar (pvendor_ie->element_id == WLAN_EID_RSN)) { 14175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* IE is a WPA/WPA2 IE so call set_wpa function */ 14195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len); 14205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wps.session_enable = false; 14215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 14235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else if (pvendor_ie->element_id == WLAN_EID_BSS_AC_ACCESS_DELAY) { 14245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* IE is a WAPI IE so call set_wapi function */ 14255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ret = mwifiex_set_wapi_ie(priv, ie_data_ptr, ie_len); 14265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 14285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 14295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* 14305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Verify that the passed length is not larger than the 14315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * available space remaining in the buffer 14325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 14335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (ie_len < (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) { 14345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Test to see if it is a WPS IE, if so, enable 14365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * wps session flag 14375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 14385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; 1439500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && 1440500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { 14415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->wps.session_enable = true; 14425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_dbg(priv->adapter->dev, 14435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao "info: WPS Session Enabled.\n"); 14445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 14455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Append the passed data to the end of the 14475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao genIeBuffer */ 14485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr, 1449500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar ie_len); 14505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Increment the stored buffer length by the 14515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao size passed */ 14525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao priv->gen_ie_buf_len += ie_len; 14535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 14545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Passed data does not fit in the remaining 14555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao buffer space */ 14565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao ret = -1; 14575e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 14585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14595e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao /* Return 0, or -1 for error case */ 14605e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return ret; 14615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 14625e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 14645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IOCTL request handler to set/get generic IE. 14655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 14665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * In addition to various generic IEs, this function can also be 14675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * used to set the ARP filter. 14685e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 14695e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaostatic int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv, 14705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_misc_gen_ie *gen_ie, 14715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao u16 action) 14725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 14735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_adapter *adapter = priv->adapter; 14745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 14755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao switch (gen_ie->type) { 14765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case MWIFIEX_IE_TYPE_GEN_IE: 14775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (action == HostCmd_ACT_GEN_GET) { 14785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao gen_ie->len = priv->wpa_ie_len; 14795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(gen_ie->ie_data, priv->wpa_ie, gen_ie->len); 14805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 14815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao mwifiex_set_gen_ie_helper(priv, gen_ie->ie_data, 14825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao (u16) gen_ie->len); 14835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 14845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 14855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao case MWIFIEX_IE_TYPE_ARP_FILTER: 14865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memset(adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 14875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao if (gen_ie->len > ARP_FILTER_MAX_BUF_SIZE) { 14885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->arp_filter_size = 0; 14895e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(adapter->dev, "invalid ARP filter size\n"); 14905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 14915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } else { 14925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(adapter->arp_filter, gen_ie->ie_data, 1493500f747c73ec9bff7692db0031a3fb726166f4d5Yogesh Ashok Powar gen_ie->len); 14945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao adapter->arp_filter_size = gen_ie->len; 14955e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 14965e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao break; 14975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao default: 14985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao dev_err(adapter->dev, "invalid IE type\n"); 14995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -1; 15005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao } 15015e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 15025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 15035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 15045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/* 15055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Sends IOCTL request to set a generic IE. 15065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 15075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function allocates the IOCTL request buffer, fills it 15085e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * with requisite parameters and calls the IOCTL handler. 15095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */ 15105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint 15115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaomwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) 15125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{ 15135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao struct mwifiex_ds_misc_gen_ie gen_ie; 15145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 151567a50035b3f9335b9e5800c32149173e797b9cc0Bing Zhao if (ie_len > IEEE_MAX_IE_SIZE) 15165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -EFAULT; 15175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 15185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE; 15195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao gen_ie.len = ie_len; 15205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao memcpy(gen_ie.ie_data, ie, ie_len); 1521636c4598499eeacce0893dc8d91113b904bd531eYogesh Ashok Powar if (mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET)) 15225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return -EFAULT; 15235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao 15245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao return 0; 15255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao} 1526