14adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "includes.h"
24adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <sys/ioctl.h>
34adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <net/if_arp.h>
44adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <net/if.h>
54adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <sys/stat.h>
64adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <fcntl.h>
74adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <sys/types.h>
84adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <sys/wait.h>
94adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <netlink/genl/genl.h>
104adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <netlink/genl/family.h>
114adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <netlink/genl/ctrl.h>
124adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <netlink/msg.h>
134adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include <netlink/attr.h>
144adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1556d9b8481df7e4c2a17ed743dd6c8dac083583adColin Cross#include "linux_wext.h"
164adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "common.h"
174adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "driver.h"
184adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "eloop.h"
194adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "driver_wext.h"
204adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "ieee802_11_defs.h"
214adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "wpa_common.h"
224adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "wpa_ctrl.h"
234adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "wpa_supplicant_i.h"
244adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "config_ssid.h"
254adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "wpa_debug.h"
264adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "linux_ioctl.h"
274adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#include "driver_nl80211.h"
284adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
294adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#define WPA_EVENT_DRIVER_STATE          "CTRL-EVENT-DRIVER-STATE "
304adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#define DRV_NUMBER_SEQUENTIAL_ERRORS     4
314adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
324adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#define WPA_PS_ENABLED   0
334adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#define WPA_PS_DISABLED  1
344adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
354adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#define BLUETOOTH_COEXISTENCE_MODE_ENABLED   0
364adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#define BLUETOOTH_COEXISTENCE_MODE_DISABLED  1
374adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer#define BLUETOOTH_COEXISTENCE_MODE_SENSE     2
384adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
394adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
404adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerstatic int g_drv_errors = 0;
414adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerstatic int g_power_mode = 0;
424adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
434adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerint send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg,
444adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer                       int (*valid_handler)(struct nl_msg *, void *),
454adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer                       void *valid_data);
464adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
474adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerstatic void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
484adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer{
494adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	g_drv_errors++;
504adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (g_drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
514adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		g_drv_errors = 0;
524adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
534adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	}
544adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer}
554adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
564adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerstatic int get_link_signal(struct nl_msg *msg, void *arg)
574adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer{
584adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct nlattr *tb[NL80211_ATTR_MAX + 1];
594adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
604adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
614adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
624adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
634adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	};
644adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
654adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
664adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		[NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
674adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		[NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
684adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
694adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
704adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	};
714adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct wpa_signal_info *sig_change = arg;
724adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
734adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
744adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		  genlmsg_attrlen(gnlh, 0), NULL);
754adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (!tb[NL80211_ATTR_STA_INFO] ||
764adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	    nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
774adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			     tb[NL80211_ATTR_STA_INFO], policy))
784adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		return NL_SKIP;
794adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (!sinfo[NL80211_STA_INFO_SIGNAL])
804adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		return NL_SKIP;
814adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
824adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	sig_change->current_signal =
834adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		(s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
844adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
854adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
864adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
874adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer				     sinfo[NL80211_STA_INFO_TX_BITRATE],
884adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer				     rate_policy)) {
894adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			sig_change->current_txrate = 0;
904adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		} else {
914adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			if (rinfo[NL80211_RATE_INFO_BITRATE]) {
924adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer				sig_change->current_txrate =
934adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer					nla_get_u16(rinfo[
944adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer					     NL80211_RATE_INFO_BITRATE]) * 100;
954adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			}
964adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		}
974adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	}
984adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
994adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	return NL_SKIP;
1004adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer}
1014adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1024adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerstatic int wpa_driver_get_link_signal(void *priv, struct wpa_signal_info *sig)
1034adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer{
1044adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct i802_bss *bss = priv;
1054adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct wpa_driver_nl80211_data *drv = bss->drv;
1064adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct nl_msg *msg;
1074adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	int ret = -1;
1084adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1094adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	sig->current_signal = -9999;
1104adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	sig->current_txrate = 0;
1114adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1124adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	msg = nlmsg_alloc();
1134adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (!msg)
1144adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		return -1;
1154adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1164adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1174adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		    0, NL80211_CMD_GET_STATION, 0);
1184adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1194adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1204adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
1214adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1224adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	ret = send_and_recv_msgs(drv, msg, get_link_signal, sig);
1234adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	msg = NULL;
1244adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (ret < 0)
1254adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		wpa_printf(MSG_ERROR, "nl80211: get link signal fail: %d", ret);
1264adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveernla_put_failure:
1274adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	nlmsg_free(msg);
1284adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	return ret;
1294adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer}
1304adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1314adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerstatic int wpa_driver_toggle_btcoex_state(char state)
1324adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer{
1334adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	int ret;
1344adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	int fd = open("/sys/devices/platform/wl1271/bt_coex_state", O_RDWR, 0);
1354adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (fd == -1)
1364adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		return -1;
1374adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1384adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	ret = write(fd, &state, sizeof(state));
1394adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	close(fd);
1404adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1414adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	wpa_printf(MSG_DEBUG, "%s:  set btcoex state to '%c' result = %d", __func__,
1424adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		   state, ret);
1434adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	return ret;
1444adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer}
1454adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1464adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerstatic int wpa_driver_set_power_save(void *priv, int state)
1474adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer{
1484adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct i802_bss *bss = priv;
1494adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct wpa_driver_nl80211_data *drv = bss->drv;
1504adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct nl_msg *msg;
1514adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	int ret = -1;
1524adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	enum nl80211_ps_state ps_state;
1534adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1544adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	msg = nlmsg_alloc();
1554adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (!msg)
1564adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		return -1;
1574adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1584adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1594adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		    NL80211_CMD_SET_POWER_SAVE, 0);
1604adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1614adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (state == WPA_PS_ENABLED)
1624adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		ps_state = NL80211_PS_ENABLED;
1634adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	else
1644adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		ps_state = NL80211_PS_DISABLED;
1654adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1664adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1674adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
1684adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1694adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1704adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	msg = NULL;
1714adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (ret < 0)
1724adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		wpa_printf(MSG_ERROR, "nl80211: Set power mode fail: %d", ret);
1734adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveernla_put_failure:
1744adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	nlmsg_free(msg);
1754adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	return ret;
1764adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer}
1774adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1784adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveerint wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
1794adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer				  size_t buf_len )
1804adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer{
1814adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct i802_bss *bss = priv;
1824adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct wpa_driver_nl80211_data *drv = bss->drv;
1834adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	struct ifreq ifr;
1844adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	int ret = 0;
1854adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
1864adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	if (os_strcasecmp(cmd, "STOP") == 0) {
1874adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
1884adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
1894adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if (os_strcasecmp(cmd, "START") == 0) {
1904adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1);
1914adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
1924adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if (os_strcasecmp(cmd, "RELOAD") == 0) {
1934adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
1944adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
1954adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		int mode;
1964adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		mode = atoi(cmd + 10);
1974adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		ret = wpa_driver_set_power_save(priv, mode);
1984adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (ret < 0) {
1994adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			wpa_driver_send_hang_msg(drv);
2004adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		} else {
2014adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			g_power_mode = mode;
2024adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			g_drv_errors = 0;
2034adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		}
2044adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) {
2054adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", g_power_mode);
2064adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if (os_strncasecmp(cmd, "BTCOEXMODE ", 11) == 0) {
2074adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		int mode = atoi(cmd + 11);
2084adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (mode == BLUETOOTH_COEXISTENCE_MODE_DISABLED) { /* disable BT-coex */
2094adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			ret = wpa_driver_toggle_btcoex_state('0');
2104adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		} else if (mode == BLUETOOTH_COEXISTENCE_MODE_SENSE) { /* enable BT-coex */
2114adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			ret = wpa_driver_toggle_btcoex_state('1');
2124adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		} else {
2134adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			wpa_printf(MSG_DEBUG, "invalid btcoex mode: %d", mode);
2144adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			ret = -1;
2154adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		}
2164adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if ((os_strcasecmp(cmd, "RSSI") == 0) || (os_strcasecmp(cmd, "RSSI-APPROX") == 0)) {
2174adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		struct wpa_signal_info sig;
2184adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		int rssi;
2194adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
2204adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (!drv->associated)
2214adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			return -1;
2224adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
2234adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		ret = wpa_driver_get_link_signal(priv, &sig);
2244adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (ret < 0) {
2254adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			wpa_driver_send_hang_msg(drv);
2264adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		} else {
2274adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			rssi = sig.current_signal;
2284adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			wpa_printf(MSG_DEBUG, "%s rssi %d\n", drv->ssid, rssi);
2294adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			ret = os_snprintf(buf, buf_len, "%s rssi %d\n", drv->ssid, rssi);
2304adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		}
2314adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if (os_strcasecmp(cmd, "LINKSPEED") == 0) {
2324adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		struct wpa_signal_info sig;
2334adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		int linkspeed;
2344adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
2354adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (!drv->associated)
2364adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			return -1;
2374adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
2384adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		ret = wpa_driver_get_link_signal(priv, &sig);
2394adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (ret < 0) {
2404adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			wpa_driver_send_hang_msg(drv);
2414adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		} else {
2424adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			linkspeed = sig.current_txrate / 1000;
2434adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			wpa_printf(MSG_DEBUG, "LinkSpeed %d\n", linkspeed);
2444adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			ret = os_snprintf(buf, buf_len, "LinkSpeed %d\n", linkspeed);
2454adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		}
2464adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
2474adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		u8 macaddr[ETH_ALEN] = {};
2484adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer
2494adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		ret = linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, macaddr);
2504adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		if (!ret)
2514adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer			ret = os_snprintf(buf, buf_len,
2524adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
2534adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	} else {
2544adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer		wpa_printf(MSG_INFO, "%s: Unsupported command %s", __func__, cmd);
2554adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	}
2564adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer	return ret;
2574adf0a82f66de9379c5e37d5dd0831a70cb6f236Vishal Mahaveer}
258