/*
 * Linux cfgp2p driver
 *
 * Copyright (C) 1999-2019, Broadcom.
 *
 *      Unless you and Broadcom execute a separate written software license
 * agreement governing use of this software, this software is licensed to you
 * under the terms of the GNU General Public License version 2 (the "GPL"),
 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 * following added to such license:
 *
 *      As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules, and to copy and
 * distribute the resulting executable under terms of your choice, provided that
 * you also meet, for each linked independent module, the terms and conditions of
 * the license of that module.  An independent module is a module which is not
 * derived from this software.  The special exception does not apply to any
 * modifications of the software.
 *
 *      Notwithstanding the above, under no circumstances may you combine this
 * software in any way with any other Broadcom software provided under a license
 * other than the GPL, without Broadcom's express prior written consent.
 *
 *
 * <<Broadcom-WL-IPTag/Open:>>
 *
 * $Id: wl_cfgp2p.c 819430 2019-05-13 11:38:06Z $
 *
 */
#include <typedefs.h>
#include <linuxver.h>
#include <osl.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/if_arp.h>
#include <asm/uaccess.h>

#include <bcmutils.h>
#include <bcmstdlib_s.h>
#include <bcmendian.h>
#include <ethernet.h>
#include <802.11.h>
#include <net/rtnetlink.h>

#include <wl_cfg80211.h>
#include <wl_cfgp2p.h>
#include <wl_cfgscan.h>
#include <wldev_common.h>
#include <wl_android.h>
#include <dngl_stats.h>
#include <dhd.h>
#include <dhd_linux.h>
#include <dhdioctl.h>
#include <wlioctl.h>
#include <dhd_cfg80211.h>
#include <dhd_bus.h>
#include <dhd_config.h>

static s8 scanparambuf[WLC_IOCTL_SMLEN];
static bool wl_cfgp2p_has_ie(const bcm_tlv_t *ie, const u8 **tlvs, u32 *tlvs_len,
                             const u8 *oui, u32 oui_len, u8 type);

static s32 wl_cfgp2p_cancel_listen(struct bcm_cfg80211 *cfg, struct net_device *ndev,
	struct wireless_dev *wdev, bool notify);

#if defined(WL_ENABLE_P2P_IF)
static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev);
static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd);
static int wl_cfgp2p_if_open(struct net_device *net);
static int wl_cfgp2p_if_stop(struct net_device *net);

static const struct net_device_ops wl_cfgp2p_if_ops = {
	.ndo_open       = wl_cfgp2p_if_open,
	.ndo_stop       = wl_cfgp2p_if_stop,
	.ndo_do_ioctl   = wl_cfgp2p_do_ioctl,
	.ndo_start_xmit = wl_cfgp2p_start_xmit,
};
#endif /* WL_ENABLE_P2P_IF */

bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len)
{
	wifi_p2p_pub_act_frame_t *pact_frm;

	if (frame == NULL)
		return false;
	pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
	if (frame_len < sizeof(wifi_p2p_pub_act_frame_t) -1)
		return false;

	if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
		pact_frm->action == P2P_PUB_AF_ACTION &&
		pact_frm->oui_type == P2P_VER &&
		memcmp(pact_frm->oui, P2P_OUI, sizeof(pact_frm->oui)) == 0) {
		return true;
	}

	return false;
}

bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len)
{
	wifi_p2p_action_frame_t *act_frm;

	if (frame == NULL)
		return false;
	act_frm = (wifi_p2p_action_frame_t *)frame;
	if (frame_len < sizeof(wifi_p2p_action_frame_t) -1)
		return false;

	if (act_frm->category == P2P_AF_CATEGORY &&
		act_frm->type  == P2P_VER &&
		memcmp(act_frm->OUI, P2P_OUI, DOT11_OUI_LEN) == 0) {
		return true;
	}

	return false;
}

#define GAS_RESP_LEN		2
#define DOUBLE_TLV_BODY_OFF	4
#define GAS_RESP_OFFSET		4
#define GAS_CRESP_OFFSET	5

bool wl_cfgp2p_find_gas_subtype(u8 subtype, u8* data, u32 len)
{
	const bcm_tlv_t *ie = (bcm_tlv_t *)data;
	const u8 *frame = NULL;
	u16 id, flen;

	/* Skipped first ANQP Element, if frame has anqp elemnt */
	ie = bcm_parse_tlvs(ie, len, DOT11_MNG_ADVERTISEMENT_ID);

	if (ie == NULL)
		return false;

	frame = (const uint8 *)ie + ie->len + TLV_HDR_LEN + GAS_RESP_LEN;
	id = ((u16) (((frame)[1] << 8) | (frame)[0]));
	flen = ((u16) (((frame)[3] << 8) | (frame)[2]));

	/* If the contents match the OUI and the type */
	if (flen >= WFA_OUI_LEN + 1 &&
		id ==  P2PSD_GAS_NQP_INFOID &&
		!bcmp(&frame[DOUBLE_TLV_BODY_OFF], (const uint8*)WFA_OUI, WFA_OUI_LEN) &&
		subtype == frame[DOUBLE_TLV_BODY_OFF+WFA_OUI_LEN]) {
		return true;
	}

	return false;
}

bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
{

	wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;

	if (frame == NULL)
		return false;

	sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
	if (frame_len < (sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1))
		return false;
	if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
		return false;

#ifdef WL11U
	if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP)
		return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE,
			(u8 *)sd_act_frm->query_data + GAS_RESP_OFFSET,
			frame_len);

	else if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP)
		return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE,
			(u8 *)sd_act_frm->query_data + GAS_CRESP_OFFSET,
			frame_len);
	else if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ ||
		sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ)
		return true;
	else
		return false;
#else
	if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ ||
		sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP ||
		sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ ||
		sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP)
		return true;
	else
		return false;
#endif /* WL11U */
}

bool wl_cfgp2p_is_p2p_gas_action(void *frame, u32 frame_len)
{

	wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;

	if (frame == NULL)
		return false;

	sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
	if (frame_len < (sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1))
		return false;
	if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
		return false;

	if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ)
		return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE,
			(u8 *)sd_act_frm->query_data,
			frame_len);
	else
		return false;
}

void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len, u32 channel)
{
	wifi_p2p_pub_act_frame_t *pact_frm;
	wifi_p2p_action_frame_t *act_frm;
	wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;
	if (!frame || frame_len <= 2)
		return;

	if (wl_cfgp2p_is_pub_action(frame, frame_len)) {
		pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
		switch (pact_frm->subtype) {
			case P2P_PAF_GON_REQ:
				CFGP2P_ACTION(("%s P2P Group Owner Negotiation Req Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_GON_RSP:
				CFGP2P_ACTION(("%s P2P Group Owner Negotiation Rsp Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_GON_CONF:
				CFGP2P_ACTION(("%s P2P Group Owner Negotiation Confirm Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_INVITE_REQ:
				CFGP2P_ACTION(("%s P2P Invitation Request  Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_INVITE_RSP:
				CFGP2P_ACTION(("%s P2P Invitation Response Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_DEVDIS_REQ:
				CFGP2P_ACTION(("%s P2P Device Discoverability Request Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_DEVDIS_RSP:
				CFGP2P_ACTION(("%s P2P Device Discoverability Response Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_PROVDIS_REQ:
				CFGP2P_ACTION(("%s P2P Provision Discovery Request Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_PAF_PROVDIS_RSP:
				CFGP2P_ACTION(("%s P2P Provision Discovery Response Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			default:
				CFGP2P_ACTION(("%s Unknown Public Action Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));

		}

	} else if (wl_cfgp2p_is_p2p_action(frame, frame_len)) {
		act_frm = (wifi_p2p_action_frame_t *)frame;
		switch (act_frm->subtype) {
			case P2P_AF_NOTICE_OF_ABSENCE:
				CFGP2P_ACTION(("%s P2P Notice of Absence Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_AF_PRESENCE_REQ:
				CFGP2P_ACTION(("%s P2P Presence Request Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_AF_PRESENCE_RSP:
				CFGP2P_ACTION(("%s P2P Presence Response Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			case P2P_AF_GO_DISC_REQ:
				CFGP2P_ACTION(("%s P2P Discoverability Request Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
				break;
			default:
				CFGP2P_ACTION(("%s Unknown P2P Action Frame,"
					" channel=%d\n", (tx)? "TX": "RX", channel));
		}

	} else if (wl_cfgp2p_is_gas_action(frame, frame_len)) {
		sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
		switch (sd_act_frm->action) {
			case P2PSD_ACTION_ID_GAS_IREQ:
				CFGP2P_ACTION(("%s GAS Initial Request,"
					" channel=%d\n", (tx)? "TX" : "RX", channel));
				break;
			case P2PSD_ACTION_ID_GAS_IRESP:
				CFGP2P_ACTION(("%s GAS Initial Response,"
					" channel=%d\n", (tx)? "TX" : "RX", channel));
				break;
			case P2PSD_ACTION_ID_GAS_CREQ:
				CFGP2P_ACTION(("%s GAS Comback Request,"
					" channel=%d\n", (tx)? "TX" : "RX", channel));
				break;
			case P2PSD_ACTION_ID_GAS_CRESP:
				CFGP2P_ACTION(("%s GAS Comback Response,"
					" channel=%d\n", (tx)? "TX" : "RX", channel));
				break;
			default:
				CFGP2P_ACTION(("%s Unknown GAS Frame,"
					" channel=%d\n", (tx)? "TX" : "RX", channel));
		}

	}
}

/*
 *  Initialize variables related to P2P
 *
 */
s32
wl_cfgp2p_init_priv(struct bcm_cfg80211 *cfg)
{
#ifdef WL_P2P_USE_RANDMAC
	struct ether_addr primary_mac;
#endif /* WL_P2P_USE_RANDMAC */
	cfg->p2p = MALLOCZ(cfg->osh, sizeof(struct p2p_info));
	if (cfg->p2p == NULL) {
		CFGP2P_ERR(("struct p2p_info allocation failed\n"));
		return -ENOMEM;
	}
#ifdef WL_P2P_USE_RANDMAC
	get_primary_mac(cfg, &primary_mac);
	wl_cfgp2p_generate_bss_mac(cfg, &primary_mac);
#endif /* WL_P2P_USE_RANDMAC */
	wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY) = bcmcfg_to_prmry_ndev(cfg);
	wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_PRIMARY) = 0;
	wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) = NULL;
	wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = 0;
	wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION1) = NULL;
	wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_CONNECTION1) = -1;
	wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_CONNECTION2) = NULL;
	wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_CONNECTION2) = -1;
	return BCME_OK;

}
/*
 *  Deinitialize variables related to P2P
 *
 */
void
wl_cfgp2p_deinit_priv(struct bcm_cfg80211 *cfg)
{
	CFGP2P_INFO(("In\n"));
	if (cfg->p2p) {
		MFREE(cfg->osh, cfg->p2p, sizeof(struct p2p_info));
		cfg->p2p = NULL;
	}
	cfg->p2p_supported = 0;
}
/*
 * Set P2P functions into firmware
 */
s32
wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg)
{
	struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
	s32 ret = BCME_OK;
	s32 val = 0;
#ifdef WL_P2P_USE_RANDMAC
	struct ether_addr *p2p_dev_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE);
#else
	struct ether_addr null_eth_addr = { { 0, 0, 0, 0, 0, 0 } };
	struct ether_addr *p2p_dev_addr = &null_eth_addr;
#endif // endif
	/* Do we have to check whether APSTA is enabled or not ? */
	ret = wldev_iovar_getint(ndev, "apsta", &val);
	if (ret < 0) {
		CFGP2P_ERR(("get apsta error %d\n", ret));
		return ret;
	}
	if (val == 0) {
		val = 1;
		ret = wldev_ioctl_set(ndev, WLC_DOWN, &val, sizeof(s32));
		if (ret < 0) {
			CFGP2P_ERR(("WLC_DOWN error %d\n", ret));
			return ret;
		}

		ret = wldev_iovar_setint(ndev, "apsta", val);
		if (ret < 0) {
			/* return error and fail the initialization */
			CFGP2P_ERR(("wl apsta %d set error. ret: %d\n", val, ret));
			return ret;
		}

		ret = wldev_ioctl_set(ndev, WLC_UP, &val, sizeof(s32));
		if (ret < 0) {
			CFGP2P_ERR(("WLC_UP error %d\n", ret));
			return ret;
		}
	}

	/* In case of COB type, firmware has default mac address
	 * After Initializing firmware, we have to set current mac address to
	 * firmware for P2P device address
	 */
	ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", p2p_dev_addr,
		sizeof(*p2p_dev_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
	if (ret && ret != BCME_UNSUPPORTED) {
		CFGP2P_ERR(("failed to update device address ret %d\n", ret));
	}
	return ret;
}

int wl_cfg_multip2p_operational(struct bcm_cfg80211 *cfg)
{
	if (!cfg->p2p) {
		CFGP2P_DBG(("p2p not enabled! \n"));
		return false;
	}

	if ((wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_CONNECTION1) != -1) &&
	    (wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_CONNECTION2) != -1))
		return true;
	else
		return false;
}

/* Create a new P2P BSS.
 * Parameters:
 * @mac      : MAC address of the BSS to create
 * @if_type  : interface type: WL_P2P_IF_GO or WL_P2P_IF_CLIENT
 * @chspec   : chspec to use if creating a GO BSS.
 * Returns 0 if success.
 */
s32
wl_cfgp2p_ifadd(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type,
            chanspec_t chspec)
{
	wl_p2p_if_t ifreq;
	s32 err;
	struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);

	ifreq.type = if_type;
	ifreq.chspec = chspec;
	memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));

	CFGP2P_ERR(("---cfg p2p_ifadd "MACDBG" %s %u\n",
		MAC2STRDBG(ifreq.addr.octet),
		(if_type == WL_P2P_IF_GO) ? "go" : "client",
	        (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT));

	err = wldev_iovar_setbuf(ndev, "p2p_ifadd", &ifreq, sizeof(ifreq),
		cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
	if (unlikely(err < 0)) {
		printk("'cfg p2p_ifadd' error %d\n", err);
		return err;
	}

	return err;
}

/* Disable a P2P BSS.
 * Parameters:
 * @mac      : MAC address of the BSS to disable
 * Returns 0 if success.
 */
s32
wl_cfgp2p_ifdisable(struct bcm_cfg80211 *cfg, struct ether_addr *mac)
{
	s32 ret;
	struct net_device *netdev = bcmcfg_to_prmry_ndev(cfg);

	CFGP2P_INFO(("------ cfg p2p_ifdis "MACDBG" dev->ifindex:%d \n",
		MAC2STRDBG(mac->octet), netdev->ifindex));
	ret = wldev_iovar_setbuf(netdev, "p2p_ifdis", mac, sizeof(*mac),
		cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
	if (unlikely(ret < 0)) {
		printk("'cfg p2p_ifdis' error %d\n", ret);
	}
	return ret;
}

/* Delete a P2P BSS.
 * Parameters:
 * @mac      : MAC address of the BSS to delete
 * Returns 0 if success.
 */
s32
wl_cfgp2p_ifdel(struct bcm_cfg80211 *cfg, struct ether_addr *mac)
{
	s32 ret;
#ifdef WL_DISABLE_HE_P2P
	s32 bssidx = 0;
#endif /* WL_DISABLE_HE_P2P */
	struct net_device *netdev = bcmcfg_to_prmry_ndev(cfg);

	CFGP2P_ERR(("------ cfg p2p_ifdel "MACDBG" dev->ifindex:%d\n",
	    MAC2STRDBG(mac->octet), netdev->ifindex));
	ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac),
		cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
	if (unlikely(ret < 0)) {
		printk("'cfg p2p_ifdel' error %d\n", ret);
	}
#ifdef WL_DISABLE_HE_P2P
	if ((bssidx = wl_get_bssidx_by_wdev(cfg, netdev->ieee80211_ptr)) < 0) {
		WL_ERR(("Find index failed\n"));
		ret = BCME_ERROR;
		return ret;
	}
	WL_DBG(("Enabling back HE for P2P\n"));
	wl_cfg80211_set_he_mode(netdev, cfg, bssidx, WL_IF_TYPE_P2P_DISC, TRUE);
	if (ret < 0) {
		WL_ERR(("failed to set he features, error=%d\n", ret));
	}
#endif /* WL_DISABLE_HE_P2P */

	return ret;
}

/* Change a P2P Role.
 * Parameters:
 * @mac      : MAC address of the BSS to change a role
 * Returns 0 if success.
 */
s32
wl_cfgp2p_ifchange(struct bcm_cfg80211 *cfg, struct ether_addr *mac, u8 if_type,
            chanspec_t chspec, s32 conn_idx)
{
	wl_p2p_if_t ifreq;
	s32 err;

	struct net_device *netdev =  wl_to_p2p_bss_ndev(cfg, conn_idx);

	ifreq.type = if_type;
	ifreq.chspec = chspec;
	memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));

	CFGP2P_INFO(("---cfg p2p_ifchange "MACDBG" %s %u"
		" chanspec 0x%04x\n", MAC2STRDBG(ifreq.addr.octet),
		(if_type == WL_P2P_IF_GO) ? "go" : "client",
		(chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT,
		ifreq.chspec));

	err = wldev_iovar_setbuf(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq),
		cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
	if (unlikely(err < 0)) {
		printk("'cfg p2p_ifupd' error %d\n", err);
	} else if (if_type == WL_P2P_IF_GO) {
		cfg->p2p->p2p_go_count++;
	}
	return err;
}

/* Get the index of a created P2P BSS.
 * Parameters:
 * @mac      : MAC address of the created BSS
 * @index    : output: index of created BSS
 * Returns 0 if success.
 */
s32
wl_cfgp2p_ifidx(struct bcm_cfg80211 *cfg, struct ether_addr *mac, s32 *index)
{
	s32 ret;
	u8 getbuf[64];
	struct net_device *dev = bcmcfg_to_prmry_ndev(cfg);

	CFGP2P_INFO(("---cfg p2p_if "MACDBG"\n", MAC2STRDBG(mac->octet)));

	ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac), getbuf,
		sizeof(getbuf), wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_PRIMARY), NULL);

	if (ret == 0) {
		memcpy(index, getbuf, sizeof(s32));
		CFGP2P_DBG(("---cfg p2p_if   ==> %d\n", *index));
	}

	return ret;
}

static s32
wl_cfgp2p_set_discovery(struct bcm_cfg80211 *cfg, s32 on)
{
	s32 ret = BCME_OK;
	struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
	CFGP2P_DBG(("enter\n"));

	ret = wldev_iovar_setint(ndev, "p2p_disc", on);

	if (unlikely(ret < 0)) {
		CFGP2P_ERR(("p2p_disc %d error %d\n", on, ret));
	}

	return ret;
}

/* Set the WL driver's P2P mode.
 * Parameters :
 * @mode      : is one of WL_P2P_DISC_ST_{SCAN,LISTEN,SEARCH}.
 * @channel   : the channel to listen
 * @listen_ms : the time (milli seconds) to wait
 * @bssidx    : bss index for BSSCFG
 * Returns 0 if success
 */

s32
wl_cfgp2p_set_p2p_mode(struct bcm_cfg80211 *cfg, u8 mode, u32 channel, u16 listen_ms, int bssidx)
{
	wl_p2p_disc_st_t discovery_mode;
	s32 ret;
	struct net_device *dev;
	CFGP2P_DBG(("enter\n"));

	if (unlikely(bssidx == WL_INVALID)) {
		CFGP2P_ERR((" %d index out of range\n", bssidx));
		return -1;
	}

	dev = wl_cfgp2p_find_ndev(cfg, bssidx);
	if (unlikely(dev == NULL)) {
		CFGP2P_ERR(("bssidx %d is not assigned\n", bssidx));
		return BCME_NOTFOUND;
	}

#ifdef P2PLISTEN_AP_SAMECHN
	CFGP2P_DBG(("p2p0 listen channel %d  AP connection chan %d \n",
		channel, cfg->channel));
	if ((mode == WL_P2P_DISC_ST_LISTEN) && (cfg->channel == channel)) {
		struct net_device *primary_ndev = bcmcfg_to_prmry_ndev(cfg);

		if (cfg->p2p_resp_apchn_status) {
			CFGP2P_DBG(("p2p_resp_apchn_status already ON \n"));
			return BCME_OK;
		}

		if (wl_get_drv_status(cfg, CONNECTED, primary_ndev)) {
			ret = wl_cfg80211_set_p2p_resp_ap_chn(primary_ndev, 1);
			cfg->p2p_resp_apchn_status = true;
			CFGP2P_DBG(("p2p_resp_apchn_status ON \n"));
			return ret;
		}
	}
#endif /* P2PLISTEN_AP_SAMECHN */

	/* Put the WL driver into P2P Listen Mode to respond to P2P probe reqs */
	discovery_mode.state = mode;
	discovery_mode.chspec = wl_ch_host_to_driver(channel);
	discovery_mode.dwell = listen_ms;
	ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode,
		sizeof(discovery_mode), cfg->ioctl_buf, WLC_IOCTL_MAXLEN,
		bssidx, &cfg->ioctl_buf_sync);

	return ret;
}

/* Get the index of the P2P Discovery BSS */
static s32
wl_cfgp2p_get_disc_idx(struct bcm_cfg80211 *cfg, s32 *index)
{
	s32 ret;
	struct net_device *dev = wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY);

	ret = wldev_iovar_getint(dev, "p2p_dev", index);
	CFGP2P_INFO(("p2p_dev bsscfg_idx=%d ret=%d\n", *index, ret));

	if (unlikely(ret <  0)) {
	    CFGP2P_ERR(("'p2p_dev' error %d\n", ret));
		return ret;
	}
	return ret;
}

int wl_cfgp2p_get_conn_idx(struct bcm_cfg80211 *cfg)
{
	int i;
	s32 connected_cnt;
	dhd_pub_t *dhd =  (dhd_pub_t *)(cfg->pub);
	if (!dhd)
		return (-ENODEV);
	for (i = P2PAPI_BSSCFG_CONNECTION1; i < P2PAPI_BSSCFG_MAX; i++) {
		if (wl_to_p2p_bss_bssidx(cfg, i) == -1) {
			if (i == P2PAPI_BSSCFG_CONNECTION2) {
				if (!(dhd->op_mode & DHD_FLAG_MP2P_MODE)) {
					CFGP2P_ERR(("Multi p2p not supported"));
					return BCME_ERROR;
				}
				if ((connected_cnt = wl_get_drv_status_all(cfg, CONNECTED)) > 1) {
					CFGP2P_ERR(("Failed to create second p2p interface"
						"Already one connection exists"));
					return BCME_ERROR;
				}
			}
		return i;
		}
	}
	return BCME_ERROR;
}

s32
wl_cfgp2p_init_discovery(struct bcm_cfg80211 *cfg)
{

	s32 bssidx = 0;
	s32 ret = BCME_OK;
	struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);

	BCM_REFERENCE(ndev);
	CFGP2P_DBG(("enter\n"));

	if (wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) > 0) {
		CFGP2P_ERR(("do nothing, already initialized\n"));
		goto exit;
	}

	ret = wl_cfgp2p_set_discovery(cfg, 1);
	if (ret < 0) {
		CFGP2P_ERR(("set discover error\n"));
		goto exit;
	}
	/* Enable P2P Discovery in the WL Driver */
	ret = wl_cfgp2p_get_disc_idx(cfg, &bssidx);
	if (ret < 0) {
		goto exit;
	}

	/* In case of CFG80211 case, check if p2p_discovery interface has allocated p2p_wdev */
	if (!cfg->p2p_wdev) {
		CFGP2P_ERR(("p2p_wdev is NULL.\n"));
		ret = -ENODEV;
		goto exit;
	}

	/* Once p2p also starts using interface_create iovar, the ifidx may change.
	 * so that time, the ifidx returned in WLC_E_IF should be used for populating
	 * the netinfo
	 */
	ret = wl_alloc_netinfo(cfg, NULL, cfg->p2p_wdev, WL_IF_TYPE_STA, 0, bssidx, 0);
	if (unlikely(ret)) {
		goto exit;
	}
	wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) =
	    wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY);
	wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = bssidx;

	/* Set the initial discovery state to SCAN */
	ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
		wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));

	if (unlikely(ret != 0)) {
		CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n"));
		wl_cfgp2p_set_discovery(cfg, 0);
		wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = 0;
		wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) = NULL;
		ret = 0;
		goto exit;
	}

	/* Clear our saved WPS and P2P IEs for the discovery BSS */
	wl_cfg80211_clear_p2p_disc_ies(cfg);
exit:
	if (ret) {
		wl_flush_fw_log_buffer(ndev, FW_LOGSET_MASK_ALL);
	}
	return ret;
}

/* Deinitialize P2P Discovery
 * Parameters :
 * @cfg        : wl_private data
 * Returns 0 if succes
 */
static s32
wl_cfgp2p_deinit_discovery(struct bcm_cfg80211 *cfg)
{
	s32 ret = BCME_OK;
	s32 bssidx;

	CFGP2P_DBG(("enter\n"));
	bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE);
	if (bssidx <= 0) {
		CFGP2P_ERR(("do nothing, not initialized\n"));
		return -1;
	}

	/* Clear our saved WPS and P2P IEs for the discovery BSS */
	wl_cfg80211_clear_p2p_disc_ies(cfg);

	/* Set the discovery state to SCAN */
	wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
	            bssidx);
	/* Disable P2P discovery in the WL driver (deletes the discovery BSSCFG) */
	ret = wl_cfgp2p_set_discovery(cfg, 0);

	/* Remove the p2p disc entry in the netinfo */
	wl_dealloc_netinfo_by_wdev(cfg, cfg->p2p_wdev);

	wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE) = WL_INVALID;
	wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE) = NULL;

	return ret;

}
/* Enable P2P Discovery
 * Parameters:
 * @cfg	: wl_private data
 * @ie  : probe request ie (WPS IE + P2P IE)
 * @ie_len   : probe request ie length
 * Returns 0 if success.
 */
s32
wl_cfgp2p_enable_discovery(struct bcm_cfg80211 *cfg, struct net_device *dev,
	const u8 *ie, u32 ie_len)
{
	s32 ret = BCME_OK;
	s32 bssidx;
	bcm_struct_cfgdev *cfgdev;

	CFGP2P_DBG(("enter\n"));
	mutex_lock(&cfg->if_sync);
#ifdef WL_IFACE_MGMT
	if ((ret = wl_cfg80211_handle_if_role_conflict(cfg, WL_IF_TYPE_P2P_DISC)) != BCME_OK) {
		WL_ERR(("secondary iface is active, p2p enable discovery is not supported\n"));
		goto exit;
	}
#endif /* WL_IFACE_MGMT */

	if (wl_get_p2p_status(cfg, DISCOVERY_ON)) {
		CFGP2P_DBG((" DISCOVERY is already initialized, we have nothing to do\n"));
		goto set_ie;
	}

	ret = wl_cfgp2p_init_discovery(cfg);
	if (unlikely(ret < 0)) {
		CFGP2P_ERR((" init discovery error %d\n", ret));
		goto exit;
	}

	wl_set_p2p_status(cfg, DISCOVERY_ON);
	/* Set wsec to any non-zero value in the discovery bsscfg to ensure our
	 * P2P probe responses have the privacy bit set in the 802.11 WPA IE.
	 * Some peer devices may not initiate WPS with us if this bit is not set.
	 */
	ret = wldev_iovar_setint_bsscfg(wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE),
			"wsec", AES_ENABLED, wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
	if (unlikely(ret < 0)) {
		CFGP2P_ERR((" wsec error %d\n", ret));
	}
set_ie:
	if (ie_len) {

		if (bcmcfg_to_prmry_ndev(cfg) == dev) {
			bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE);
		} else if ((bssidx = wl_get_bssidx_by_wdev(cfg, cfg->p2p_wdev)) < 0) {
			WL_ERR(("Find p2p index from wdev(%p) failed\n", cfg->p2p_wdev));
			ret = BCME_ERROR;
			goto exit;
		}

#if defined(WL_CFG80211_P2P_DEV_IF)
		/* For 3.8+ kernels, pass p2p discovery wdev */
		cfgdev = cfg->p2p_wdev;
#else
		/* Prior to 3.8 kernel, there is no netless p2p, so pass p2p0 ndev */
		cfgdev = ndev_to_cfgdev(dev);
#endif /* WL_CFG80211_P2P_DEV_IF */
		ret = wl_cfg80211_set_mgmt_vndr_ies(cfg, cfgdev,
				bssidx, VNDR_IE_PRBREQ_FLAG, ie, ie_len);
		if (unlikely(ret < 0)) {
			CFGP2P_ERR(("set probreq ie occurs error %d\n", ret));
			goto exit;
		}
	}
exit:
	if (ret) {
		wl_flush_fw_log_buffer(dev, FW_LOGSET_MASK_ALL);
	}
	mutex_unlock(&cfg->if_sync);
	return ret;
}

/* Disable P2P Discovery
 * Parameters:
 * @cfg       : wl_private_data
 * Returns 0 if success.
 */
s32
wl_cfgp2p_disable_discovery(struct bcm_cfg80211 *cfg)
{
	s32 ret = BCME_OK;
	s32 bssidx;

	CFGP2P_DBG((" enter\n"));
	wl_clr_p2p_status(cfg, DISCOVERY_ON);

	if (!cfg->p2p) { // terence 20130113: Fix for p2p NULL pointer
		ret = BCME_ERROR;
		CFGP2P_ERR(("wl->p2p is NULL\n"));
		goto exit;
	}

#ifdef DHD_IFDEBUG
	WL_ERR(("%s: bssidx: %d\n",
		__FUNCTION__, (cfg)->p2p->bss[P2PAPI_BSSCFG_DEVICE].bssidx));
#endif // endif
	bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE);
	if (bssidx <= 0) {
		CFGP2P_ERR((" do nothing, not initialized\n"));
		return 0;
	}

	ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx);
	if (unlikely(ret < 0)) {
		CFGP2P_ERR(("unable to set WL_P2P_DISC_ST_SCAN\n"));
	}
	/* Do a scan abort to stop the driver's scan engine in case it is still
	 * waiting out an action frame tx dwell time.
	 */
#ifdef NOT_YET
	if (wl_get_p2p_status(cfg, SCANNING)) {
		p2pwlu_scan_abort(hdl, FALSE);
	}
#endif // endif
	wl_clr_p2p_status(cfg, DISCOVERY_ON);
	ret = wl_cfgp2p_deinit_discovery(cfg);

exit:
	return ret;
}

/* Scan parameters */
#define P2PAPI_SCAN_NPROBES 1
#define P2PAPI_SCAN_DWELL_TIME_MS 80
#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
#define P2PAPI_SCAN_HOME_TIME_MS 60
#define P2PAPI_SCAN_NPROBS_TIME_MS 30
#define P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS 100
s32
wl_cfgp2p_escan(struct bcm_cfg80211 *cfg, struct net_device *dev, u16 active_scan,
	u32 num_chans, u16 *channels,
	s32 search_state, u16 action, u32 bssidx, struct ether_addr *tx_dst_addr,
	p2p_scan_purpose_t p2p_scan_purpose)
{
	s32 ret = BCME_OK;
	s32 memsize;
	s32 eparams_size;
	u32 i;
	s8 *memblk;
	wl_p2p_scan_t *p2p_params;
	wl_escan_params_t *eparams;
	wl_escan_params_v2_t *eparams_v2;
	wlc_ssid_t ssid;
	u32 sync_id = 0;
	s32 nprobes = 0;
	s32 active_time = 0;
	const struct ether_addr *mac_addr = NULL;
	u32 scan_type = 0;
	struct net_device *pri_dev = NULL;

	pri_dev = wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_PRIMARY);
	/* Allocate scan params which need space for 3 channels and 0 ssids */
	if (cfg->scan_params_v2) {
		eparams_size = (WL_SCAN_PARAMS_V2_FIXED_SIZE +
			OFFSETOF(wl_escan_params_v2_t, params)) +
			num_chans * sizeof(eparams->params.channel_list[0]);
	} else {
		eparams_size = (WL_SCAN_PARAMS_FIXED_SIZE +
			OFFSETOF(wl_escan_params_t, params)) +
			num_chans * sizeof(eparams->params.channel_list[0]);
	}

	memsize = sizeof(wl_p2p_scan_t) + eparams_size;
	memblk = scanparambuf;
	if (memsize > sizeof(scanparambuf)) {
		CFGP2P_ERR((" scanpar buf too small (%u > %zu)\n",
		    memsize, sizeof(scanparambuf)));
		return -1;
	}
	bzero(memblk, memsize);
	bzero(cfg->ioctl_buf, WLC_IOCTL_MAXLEN);
	if (search_state == WL_P2P_DISC_ST_SEARCH) {
		/*
		 * If we in SEARCH STATE, we don't need to set SSID explictly
		 * because dongle use P2P WILDCARD internally by default
		 */
		wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SEARCH, 0, 0, bssidx);
		/* use null ssid */
		ssid.SSID_len = 0;
		bzero(&ssid.SSID, sizeof(ssid.SSID));
	} else if (search_state == WL_P2P_DISC_ST_SCAN) {
		/* SCAN STATE 802.11 SCAN
		 * WFD Supplicant has p2p_find command with (type=progressive, type= full)
		 * So if P2P_find command with type=progressive,
		 * we have to set ssid to P2P WILDCARD because
		 * we just do broadcast scan unless setting SSID
		 */
		wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx);
		/* use wild card ssid */
		ssid.SSID_len = WL_P2P_WILDCARD_SSID_LEN;
		bzero(&ssid.SSID, sizeof(ssid.SSID));
		memcpy(&ssid.SSID, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN);
	} else {
		CFGP2P_ERR((" invalid search state %d\n", search_state));
		return -1;
	}

	/* Fill in the P2P scan structure at the start of the iovar param block */
	p2p_params = (wl_p2p_scan_t*) memblk;
	p2p_params->type = 'E';

	if (!active_scan) {
		scan_type = WL_SCANFLAGS_PASSIVE;
	}

	if (tx_dst_addr == NULL) {
		mac_addr = &ether_bcast;
	} else {
		mac_addr = tx_dst_addr;
	}

	switch (p2p_scan_purpose) {
		case P2P_SCAN_SOCIAL_CHANNEL:
			active_time = P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS;
			break;
		case P2P_SCAN_AFX_PEER_NORMAL:
		case P2P_SCAN_AFX_PEER_REDUCED:
			active_time = P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS;
			break;
		case P2P_SCAN_CONNECT_TRY:
			active_time = WL_SCAN_CONNECT_DWELL_TIME_MS;
			break;
		default:
			active_time = wl_get_drv_status_all(cfg, CONNECTED) ?
				-1 : P2PAPI_SCAN_DWELL_TIME_MS;
			break;
	}

	if (p2p_scan_purpose == P2P_SCAN_CONNECT_TRY) {
		nprobes = active_time /
			WL_SCAN_JOIN_PROBE_INTERVAL_MS;
	} else {
		nprobes = active_time /
			P2PAPI_SCAN_NPROBS_TIME_MS;
	}

	if (nprobes <= 0) {
		nprobes = 1;
	}

	wl_escan_set_sync_id(sync_id, cfg);
	/* Fill in the Scan structure that follows the P2P scan structure */
	if (cfg->scan_params_v2) {
		eparams_v2 = (wl_escan_params_v2_t*) (p2p_params + 1);
		eparams_v2->version = htod16(ESCAN_REQ_VERSION_V2);
		eparams_v2->action =  htod16(action);
		eparams_v2->params.version = htod16(WL_SCAN_PARAMS_VERSION_V2);
		eparams_v2->params.length = htod16(sizeof(wl_scan_params_v2_t));
		eparams_v2->params.bss_type = DOT11_BSSTYPE_ANY;
		eparams_v2->params.scan_type = htod32(scan_type);
		(void)memcpy_s(&eparams_v2->params.bssid, ETHER_ADDR_LEN, mac_addr, ETHER_ADDR_LEN);
		eparams_v2->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS);
		eparams_v2->params.active_time = htod32(active_time);
		eparams_v2->params.nprobes = htod32(nprobes);
		eparams_v2->params.passive_time = htod32(-1);
		eparams_v2->sync_id = sync_id;
		for (i = 0; i < num_chans; i++) {
			eparams_v2->params.channel_list[i] =
				wl_ch_host_to_driver(channels[i]);
		}
		eparams_v2->params.channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
			(num_chans & WL_SCAN_PARAMS_COUNT_MASK));
		if (ssid.SSID_len)
			(void)memcpy_s(&eparams_v2->params.ssid,
					sizeof(wlc_ssid_t), &ssid, sizeof(wlc_ssid_t));
		sync_id = eparams_v2->sync_id;
	} else {
		eparams = (wl_escan_params_t*) (p2p_params + 1);
		eparams->version = htod32(ESCAN_REQ_VERSION);
		eparams->action =  htod16(action);
		eparams->params.bss_type = DOT11_BSSTYPE_ANY;
		eparams->params.scan_type = htod32(scan_type);
		(void)memcpy_s(&eparams->params.bssid, ETHER_ADDR_LEN, mac_addr, ETHER_ADDR_LEN);
		eparams->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS);
		eparams->params.active_time = htod32(active_time);
		eparams->params.nprobes = htod32(nprobes);
		eparams->params.passive_time = htod32(-1);
		eparams->sync_id = sync_id;
		for (i = 0; i < num_chans; i++) {
			eparams->params.channel_list[i] =
				wl_ch_host_to_driver(channels[i]);
		}
		eparams->params.channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
			(num_chans & WL_SCAN_PARAMS_COUNT_MASK));
		if (ssid.SSID_len)
			(void)memcpy_s(&eparams->params.ssid,
					sizeof(wlc_ssid_t), &ssid, sizeof(wlc_ssid_t));
		sync_id = eparams->sync_id;
	}

	wl_escan_set_type(cfg, WL_SCANTYPE_P2P);

	CFGP2P_DBG(("nprobes:%d active_time:%d\n", nprobes, active_time));
	CFGP2P_DBG(("SCAN CHANNELS : "));
	CFGP2P_DBG(("%d", channels[0]));
	for (i = 1; i < num_chans; i++) {
		CFGP2P_DBG((",%d", channels[i]));
	}
	CFGP2P_DBG(("\n"));

	ret = wldev_iovar_setbuf_bsscfg(pri_dev, "p2p_scan",
		memblk, memsize, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync);
	WL_MSG(dev->name, "P2P_SEARCH sync ID: %d, bssidx: %d\n", sync_id, bssidx);
	if (ret == BCME_OK) {
		wl_set_p2p_status(cfg, SCANNING);
	}
	return ret;
}

/* search function to reach at common channel to send action frame
 * Parameters:
 * @cfg       : wl_private data
 * @ndev     : net device for bssidx
 * @bssidx   : bssidx for BSS
 * Returns 0 if success.
 */
s32
wl_cfgp2p_act_frm_search(struct bcm_cfg80211 *cfg, struct net_device *ndev,
	s32 bssidx, s32 channel, struct ether_addr *tx_dst_addr)
{
	s32 ret = 0;
	u32 chan_cnt = 0;
	u16 *default_chan_list = NULL;
	p2p_scan_purpose_t p2p_scan_purpose = P2P_SCAN_AFX_PEER_NORMAL;
	if (!p2p_is_on(cfg) || ndev == NULL || bssidx == WL_INVALID)
		return -EINVAL;
	WL_TRACE_HW4((" Enter\n"));
	if (bssidx == wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_PRIMARY))
		bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE);
	if (channel)
		chan_cnt = AF_PEER_SEARCH_CNT;
	else
		chan_cnt = SOCIAL_CHAN_CNT;

	if (cfg->afx_hdl->pending_tx_act_frm && cfg->afx_hdl->is_active) {
		wl_action_frame_t *action_frame;
		action_frame = &(cfg->afx_hdl->pending_tx_act_frm->action_frame);
		if (wl_cfgp2p_is_p2p_gas_action(action_frame->data, action_frame->len))	{
			chan_cnt = 1;
			p2p_scan_purpose = P2P_SCAN_AFX_PEER_REDUCED;
		}
	}

	default_chan_list = (u16 *)MALLOCZ(cfg->osh, chan_cnt * sizeof(*default_chan_list));
	if (default_chan_list == NULL) {
		CFGP2P_ERR(("channel list allocation failed \n"));
		ret = -ENOMEM;
		goto exit;
	}
	if (channel) {
		u32 i;
		/* insert same channel to the chan_list */
		for (i = 0; i < chan_cnt; i++) {
			default_chan_list[i] = channel;
		}
	} else {
		default_chan_list[0] = SOCIAL_CHAN_1;
		default_chan_list[1] = SOCIAL_CHAN_2;
		default_chan_list[2] = SOCIAL_CHAN_3;
	}
	ret = wl_cfgp2p_escan(cfg, ndev, true, chan_cnt,
		default_chan_list, WL_P2P_DISC_ST_SEARCH,
		WL_SCAN_ACTION_START, bssidx, NULL, p2p_scan_purpose);
	MFREE(cfg->osh, default_chan_list, chan_cnt * sizeof(*default_chan_list));
exit:
	return ret;
}

/* Check whether pointed-to IE looks like WPA. */
#define wl_cfgp2p_is_wpa_ie(ie, tlvs, len)	wl_cfgp2p_has_ie(ie, tlvs, len, \
		(const uint8 *)WPS_OUI, WPS_OUI_LEN, WPA_OUI_TYPE)
/* Check whether pointed-to IE looks like WPS. */
#define wl_cfgp2p_is_wps_ie(ie, tlvs, len)	wl_cfgp2p_has_ie(ie, tlvs, len, \
		(const uint8 *)WPS_OUI, WPS_OUI_LEN, WPS_OUI_TYPE)
/* Check whether the given IE looks like WFA P2P IE. */
#define wl_cfgp2p_is_p2p_ie(ie, tlvs, len)	wl_cfgp2p_has_ie(ie, tlvs, len, \
		(const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P)
/* Check whether the given IE looks like WFA WFDisplay IE. */
#ifndef WFA_OUI_TYPE_WFD
#define WFA_OUI_TYPE_WFD	0x0a			/* WiFi Display OUI TYPE */
#endif // endif
#define wl_cfgp2p_is_wfd_ie(ie, tlvs, len)	wl_cfgp2p_has_ie(ie, tlvs, len, \
		(const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_WFD)

/* Is any of the tlvs the expected entry? If
 * not update the tlvs buffer pointer/length.
 */
static bool
wl_cfgp2p_has_ie(const bcm_tlv_t *ie, const u8 **tlvs, u32 *tlvs_len,
                 const u8 *oui, u32 oui_len, u8 type)
{
	/* If the contents match the OUI and the type */
	if (ie->len >= oui_len + 1 &&
	    !bcmp(ie->data, oui, oui_len) &&
	    type == ie->data[oui_len]) {
		return TRUE;
	}

	/* point to the next ie */
	if (tlvs != NULL) {
		bcm_tlv_buffer_advance_past(ie, tlvs, tlvs_len);
	}

	return FALSE;
}

const wpa_ie_fixed_t *
wl_cfgp2p_find_wpaie(const u8 *parse, u32 len)
{
	const bcm_tlv_t *ie;

	while ((ie = bcm_parse_tlvs(parse, len, DOT11_MNG_VS_ID))) {
		if (wl_cfgp2p_is_wpa_ie(ie, &parse, &len)) {
			return (const wpa_ie_fixed_t *)ie;
		}
	}
	return NULL;
}

const wpa_ie_fixed_t *
wl_cfgp2p_find_wpsie(const u8 *parse, u32 len)
{
	const bcm_tlv_t *ie;

	while ((ie = bcm_parse_tlvs(parse, len, DOT11_MNG_VS_ID))) {
		if (wl_cfgp2p_is_wps_ie(ie, &parse, &len)) {
			return (const wpa_ie_fixed_t *)ie;
		}
	}
	return NULL;
}

wifi_p2p_ie_t *
wl_cfgp2p_find_p2pie(const u8 *parse, u32 len)
{
	bcm_tlv_t *ie;

	while ((ie = bcm_parse_tlvs(parse, len, DOT11_MNG_VS_ID))) {
		if (wl_cfgp2p_is_p2p_ie(ie, &parse, &len)) {
			return (wifi_p2p_ie_t *)ie;
		}
	}
	return NULL;
}

const wifi_wfd_ie_t *
wl_cfgp2p_find_wfdie(const u8 *parse, u32 len)
{
	const bcm_tlv_t *ie;

	while ((ie = bcm_parse_tlvs(parse, len, DOT11_MNG_VS_ID))) {
		if (wl_cfgp2p_is_wfd_ie(ie, &parse, &len)) {
			return (const wifi_wfd_ie_t *)ie;
		}
	}
	return NULL;
}

u32
wl_cfgp2p_vndr_ie(struct bcm_cfg80211 *cfg, u8 *iebuf, s32 pktflag,
            s8 *oui, s32 ie_id, const s8 *data, s32 datalen, const s8* add_del_cmd)
{
	vndr_ie_setbuf_t hdr;	/* aligned temporary vndr_ie buffer header */
	s32 iecount;
	u32 data_offset;

	/* Validate the pktflag parameter */
	if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG |
	            VNDR_IE_ASSOCRSP_FLAG | VNDR_IE_AUTHRSP_FLAG |
	            VNDR_IE_PRBREQ_FLAG | VNDR_IE_ASSOCREQ_FLAG |
	            VNDR_IE_DISASSOC_FLAG))) {
		CFGP2P_ERR(("p2pwl_vndr_ie: Invalid packet flag 0x%x\n", pktflag));
		return -1;
	}

	/* Copy the vndr_ie SET command ("add"/"del") to the buffer */
	strlcpy(hdr.cmd, add_del_cmd, sizeof(hdr.cmd));

	/* Set the IE count - the buffer contains only 1 IE */
	iecount = htod32(1);
	memcpy((void *)&hdr.vndr_ie_buffer.iecount, &iecount, sizeof(s32));

	/* For vendor ID DOT11_MNG_ID_EXT_ID, need to set pkt flag to VNDR_IE_CUSTOM_FLAG */
	if (ie_id == DOT11_MNG_ID_EXT_ID) {
		pktflag = pktflag | VNDR_IE_CUSTOM_FLAG;
	}

	/* Copy packet flags that indicate which packets will contain this IE */
	pktflag = htod32(pktflag);
	memcpy((void *)&hdr.vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag,
		sizeof(u32));

	/* Add the IE ID to the buffer */
	hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id;

	/* Add the IE length to the buffer */
	hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len =
		(uint8) VNDR_IE_MIN_LEN + datalen;

	/* Add the IE OUI to the buffer */
	hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[0] = oui[0];
	hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[1] = oui[1];
	hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[2] = oui[2];

	/* Copy the aligned temporary vndr_ie buffer header to the IE buffer */
	memcpy(iebuf, &hdr, sizeof(hdr) - 1);

	/* Copy the IE data to the IE buffer */
	data_offset =
		(u8*)&hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[0] -
		(u8*)&hdr;
	memcpy(iebuf + data_offset, data, datalen);
	return data_offset + datalen;

}

struct net_device *
wl_cfgp2p_find_ndev(struct bcm_cfg80211 *cfg, s32 bssidx)
{
	u32 i;
	struct net_device *ndev = NULL;
	if (bssidx < 0) {
		CFGP2P_ERR((" bsscfg idx is invalid\n"));
		goto exit;
	}

	for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
		if (bssidx == wl_to_p2p_bss_bssidx(cfg, i)) {
			ndev = wl_to_p2p_bss_ndev(cfg, i);
			break;
		}
	}

exit:
	return ndev;
}
/*
 * Search the driver array idx based on bssidx argument
 * Parameters: Note that this idx is applicable only
 * for primary and P2P interfaces. The virtual AP/STA is not
 * covered here.
 * @cfg     : wl_private data
 * @bssidx : bssidx which indicate bsscfg->idx of firmware.
 * @type   : output arg to store array idx of p2p->bss.
 * Returns error
 */

s32
wl_cfgp2p_find_type(struct bcm_cfg80211 *cfg, s32 bssidx, s32 *type)
{
	u32 i;
	if (bssidx < 0 || type == NULL) {
		CFGP2P_ERR((" argument is invalid\n"));
		goto exit;
	}
	if (!cfg->p2p) {
		CFGP2P_ERR(("p2p if does not exist\n"));
		goto exit;
	}
	for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
		if (bssidx == wl_to_p2p_bss_bssidx(cfg, i)) {
			*type = i;
			return BCME_OK;
		}
	}

exit:
	return BCME_BADARG;
}

/*
 * Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE
 */
s32
wl_cfgp2p_listen_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
	const wl_event_msg_t *e, void *data)
{
	s32 ret = BCME_OK;
	struct net_device *ndev = NULL;

	if (!cfg || !cfg->p2p || !cfgdev)
		return BCME_ERROR;

	CFGP2P_DBG((" Enter\n"));
#ifdef DHD_IFDEBUG
	PRINT_WDEV_INFO(cfgdev);
#endif /* DHD_IFDEBUG */

	ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);

#ifdef P2P_LISTEN_OFFLOADING
	if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS)) {
		wl_clr_p2p_status(cfg, DISC_IN_PROGRESS);
		CFGP2P_ERR(("DISC_IN_PROGRESS cleared\n"));
		if (ndev && (ndev->ieee80211_ptr != NULL)) {
#if defined(WL_CFG80211_P2P_DEV_IF)
			if (cfgdev && ((struct wireless_dev *)cfgdev)->wiphy) {
				cfg80211_remain_on_channel_expired(cfgdev, cfg->last_roc_id,
						&cfg->remain_on_chan, GFP_KERNEL);
			} else {
				CFGP2P_ERR(("Invalid cfgdev. Dropping the"
						"remain_on_channel_expired event.\n"));
			}
#else
			cfg80211_remain_on_channel_expired(cfgdev, cfg->last_roc_id,
					&cfg->remain_on_chan, cfg->remain_on_chan_type, GFP_KERNEL);
#endif /* WL_CFG80211_P2P_DEV_IF */
		}
	}
#endif /* P2P_LISTEN_OFFLOADING */

	if (wl_get_p2p_status(cfg, LISTEN_EXPIRED) == 0) {
		wl_set_p2p_status(cfg, LISTEN_EXPIRED);
		if (timer_pending(&cfg->p2p->listen_timer)) {
			del_timer_sync(&cfg->p2p->listen_timer);
		}

		if (cfg->afx_hdl->is_listen == TRUE &&
			wl_get_drv_status_all(cfg, FINDING_COMMON_CHANNEL)) {
			WL_DBG(("Listen DONE for action frame\n"));
			complete(&cfg->act_frm_scan);
		}
#ifdef WL_CFG80211_SYNC_GON
		else if (wl_get_drv_status_all(cfg, WAITING_NEXT_ACT_FRM_LISTEN)) {
			wl_clr_drv_status(cfg, WAITING_NEXT_ACT_FRM_LISTEN, ndev);
			WL_DBG(("Listen DONE and wake up wait_next_af !!(%d)\n",
				jiffies_to_msecs(jiffies - cfg->af_tx_sent_jiffies)));

			if (wl_get_drv_status_all(cfg, WAITING_NEXT_ACT_FRM))
				wl_clr_drv_status(cfg, WAITING_NEXT_ACT_FRM, ndev);

			complete(&cfg->wait_next_af);
		}
#endif /* WL_CFG80211_SYNC_GON */

#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
		if (wl_get_drv_status_all(cfg, REMAINING_ON_CHANNEL))
#else
		if (wl_get_drv_status_all(cfg, REMAINING_ON_CHANNEL) ||
			wl_get_drv_status_all(cfg, FAKE_REMAINING_ON_CHANNEL))
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
		{
			WL_DBG(("Listen DONE for remain on channel expired\n"));
			wl_clr_drv_status(cfg, REMAINING_ON_CHANNEL, ndev);
#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
			wl_clr_drv_status(cfg, FAKE_REMAINING_ON_CHANNEL, ndev);
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
			if (ndev && (ndev->ieee80211_ptr != NULL)) {
#if defined(WL_CFG80211_P2P_DEV_IF)
				if (cfgdev && ((struct wireless_dev *)cfgdev)->wiphy &&
				    bcmcfg_to_p2p_wdev(cfg)) {
					/*
					 * To prevent kernel panic,
					 * if cfgdev->wiphy may be invalid, adding explicit check
					 */
					cfg80211_remain_on_channel_expired(bcmcfg_to_p2p_wdev(cfg),
						cfg->last_roc_id, &cfg->remain_on_chan, GFP_KERNEL);
				} else
					CFGP2P_ERR(("Invalid cfgdev. Dropping the"
						"remain_on_channel_expired event.\n"));
#else
				if (cfgdev && ((struct wireless_dev *)cfgdev)->wiphy)
					cfg80211_remain_on_channel_expired(cfgdev,
						cfg->last_roc_id, &cfg->remain_on_chan,
						cfg->remain_on_chan_type, GFP_KERNEL);
#endif /* WL_CFG80211_P2P_DEV_IF */
			}
		}
		if (wl_add_remove_eventmsg(bcmcfg_to_prmry_ndev(cfg),
			WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) {
			CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n"));
		}
	} else
		wl_clr_p2p_status(cfg, LISTEN_EXPIRED);

	return ret;

}

/*
 *  Timer expire callback function for LISTEN
 *  We can't report cfg80211_remain_on_channel_expired from Timer ISR context,
 *  so lets do it from thread context.
 */
void
wl_cfgp2p_listen_expired(unsigned long data)
{
	wl_event_msg_t msg;
	struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *) data;
	struct net_device *ndev;
	CFGP2P_DBG((" Enter\n"));

	if (!cfg) {
		CFGP2P_ERR((" No cfg\n"));
		return;
	}
	bzero(&msg, sizeof(wl_event_msg_t));
	msg.event_type =  hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE);
	msg.bsscfgidx  =  wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE);
#if defined(WL_ENABLE_P2P_IF)
	ndev = cfg->p2p_net ? cfg->p2p_net :
		wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE);
#else
	ndev = wl_to_p2p_bss_ndev(cfg, P2PAPI_BSSCFG_DEVICE);
#endif /* WL_ENABLE_P2P_IF */
	if (!ndev) {
		CFGP2P_ERR((" No ndev\n"));
		return;
	}
	wl_cfg80211_event(ndev, &msg, NULL);
}
/*
 *  Routine for cancelling the P2P LISTEN
 */
static s32
wl_cfgp2p_cancel_listen(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                         struct wireless_dev *wdev, bool notify)
{
	WL_DBG(("Enter \n"));
	/* Irrespective of whether timer is running or not, reset
	 * the LISTEN state.
	 */
#ifdef NOT_YET
	wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
		wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
#endif /* NOT_YET */
	if (timer_pending(&cfg->p2p->listen_timer)) {
		del_timer_sync(&cfg->p2p->listen_timer);
		if (notify) {
#if defined(WL_CFG80211_P2P_DEV_IF)
			if (bcmcfg_to_p2p_wdev(cfg))
				cfg80211_remain_on_channel_expired(wdev, cfg->last_roc_id,
					&cfg->remain_on_chan, GFP_KERNEL);
#else
			if (ndev && ndev->ieee80211_ptr)
				cfg80211_remain_on_channel_expired(ndev, cfg->last_roc_id,
					&cfg->remain_on_chan, cfg->remain_on_chan_type, GFP_KERNEL);
#endif /* WL_CFG80211_P2P_DEV_IF */
		}
	}
	return 0;
}
/*
 * Do a P2P Listen on the given channel for the given duration.
 * A listen consists of sitting idle and responding to P2P probe requests
 * with a P2P probe response.
 *
 * This fn assumes dongle p2p device discovery is already enabled.
 * Parameters   :
 * @cfg          : wl_private data
 * @channel     : channel to listen
 * @duration_ms : the time (milli seconds) to wait
 */
s32
wl_cfgp2p_discover_listen(struct bcm_cfg80211 *cfg, s32 channel, u32 duration_ms)
{
#define EXTRA_DELAY_TIME	100
	s32 ret = BCME_OK;
	timer_list_compat_t *_timer;
	s32 extra_delay;
	struct net_device *netdev = bcmcfg_to_prmry_ndev(cfg);

	CFGP2P_DBG((" Enter Listen Channel : %d, Duration : %d\n", channel, duration_ms));
	if (unlikely(wl_get_p2p_status(cfg, DISCOVERY_ON) == 0)) {

		CFGP2P_ERR((" Discovery is not set, so we have noting to do\n"));

		ret = BCME_NOTREADY;
		goto exit;
	}
	if (timer_pending(&cfg->p2p->listen_timer)) {
		CFGP2P_DBG(("previous LISTEN is not completed yet\n"));
		goto exit;

	}
#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
	else
		wl_clr_p2p_status(cfg, LISTEN_EXPIRED);
#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
	if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK) {
			CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n"));
	}

	ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
	            wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
	_timer = &cfg->p2p->listen_timer;

	/*  We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle ,
	 *  otherwise we will wait up to duration_ms + 100ms + duration / 10
	 */
	if (ret == BCME_OK) {
		extra_delay = EXTRA_DELAY_TIME + (duration_ms / 10);
	} else {
		/* if failed to set listen, it doesn't need to wait whole duration. */
		duration_ms = 100 + duration_ms / 20;
		extra_delay = 0;
	}

	INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration_ms, extra_delay);
#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
	wl_clr_p2p_status(cfg, LISTEN_EXPIRED);
#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */

#undef EXTRA_DELAY_TIME
exit:
	return ret;
}

s32
wl_cfgp2p_discover_enable_search(struct bcm_cfg80211 *cfg, u8 enable)
{
	s32 ret = BCME_OK;
	CFGP2P_DBG((" Enter\n"));
	if (!wl_get_p2p_status(cfg, DISCOVERY_ON)) {

		CFGP2P_DBG((" do nothing, discovery is off\n"));
		return ret;
	}
	if (wl_get_p2p_status(cfg, SEARCH_ENABLED) == enable) {
		CFGP2P_DBG(("already : %d\n", enable));
		return ret;
	}

	wl_chg_p2p_status(cfg, SEARCH_ENABLED);
	/* When disabling Search, reset the WL driver's p2p discovery state to
	 * WL_P2P_DISC_ST_SCAN.
	 */
	if (!enable) {
		wl_clr_p2p_status(cfg, SCANNING);
		ret = wl_cfgp2p_set_p2p_mode(cfg, WL_P2P_DISC_ST_SCAN, 0, 0,
		            wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE));
	}

	return ret;
}

/*
 * Callback function for WLC_E_ACTION_FRAME_COMPLETE, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE
 */
s32
wl_cfgp2p_action_tx_complete(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
            const wl_event_msg_t *e, void *data)
{
	s32 ret = BCME_OK;
	u32 event_type = ntoh32(e->event_type);
	u32 status = ntoh32(e->status);
	struct net_device *ndev = NULL;
	u8 bsscfgidx = e->bsscfgidx;

	CFGP2P_DBG((" Enter\n"));

	ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);

	if (wl_get_drv_status_all(cfg, SENDING_ACT_FRM)) {
		if (event_type == WLC_E_ACTION_FRAME_COMPLETE) {

			CFGP2P_DBG((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status));
			if (status == WLC_E_STATUS_SUCCESS) {
				wl_set_p2p_status(cfg, ACTION_TX_COMPLETED);
				CFGP2P_ACTION(("TX actfrm : ACK\n"));
				if (!cfg->need_wait_afrx && cfg->af_sent_channel) {
					CFGP2P_DBG(("no need to wait next AF.\n"));
					wl_stop_wait_next_action_frame(cfg, ndev, bsscfgidx);
				}
			}
			else if (!wl_get_p2p_status(cfg, ACTION_TX_COMPLETED)) {
				wl_set_p2p_status(cfg, ACTION_TX_NOACK);
				if (status == WLC_E_STATUS_SUPPRESS) {
					CFGP2P_ACTION(("TX actfrm : SUPPRES\n"));
				} else {
					CFGP2P_ACTION(("TX actfrm : NO ACK\n"));
				}
				wl_stop_wait_next_action_frame(cfg, ndev, bsscfgidx);
			}
		} else {
			CFGP2P_DBG((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received,"
						"status : %d\n", status));

			if (wl_get_drv_status_all(cfg, SENDING_ACT_FRM))
				complete(&cfg->send_af_done);
		}
	}
	return ret;
}
/* Send an action frame immediately without doing channel synchronization.
 *
 * This function does not wait for a completion event before returning.
 * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action
 * frame is transmitted.
 * The WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE event will be received when an
 * 802.11 ack has been received for the sent action frame.
 */
s32
wl_cfgp2p_tx_action_frame(struct bcm_cfg80211 *cfg, struct net_device *dev,
	wl_af_params_t *af_params, s32 bssidx)
{
	s32 ret = BCME_OK;
	s32 evt_ret = BCME_OK;
	s32 timeout = 0;
	wl_eventmsg_buf_t buf;

	CFGP2P_DBG(("\n"));
	CFGP2P_DBG(("channel : %u , dwell time : %u\n",
	    af_params->channel, af_params->dwell_time));

	wl_clr_p2p_status(cfg, ACTION_TX_COMPLETED);
	wl_clr_p2p_status(cfg, ACTION_TX_NOACK);

	bzero(&buf, sizeof(wl_eventmsg_buf_t));
	wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, true);
	wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, true);
	if ((evt_ret = wl_cfg80211_apply_eventbuffer(bcmcfg_to_prmry_ndev(cfg), cfg, &buf)) < 0)
		return evt_ret;

	cfg->af_sent_channel  = af_params->channel;
#ifdef WL_CFG80211_SYNC_GON
	cfg->af_tx_sent_jiffies = jiffies;
#endif /* WL_CFG80211_SYNC_GON */

	ret = wldev_iovar_setbuf_bsscfg(dev, "actframe", af_params, sizeof(*af_params),
		cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync);

	if (ret < 0) {
		CFGP2P_ACTION(("TX actfrm : ERROR\n"));
		goto exit;
	}

	timeout = wait_for_completion_timeout(&cfg->send_af_done,
		msecs_to_jiffies(af_params->dwell_time + WL_AF_TX_EXTRA_TIME_MAX));

	if (timeout >= 0 && wl_get_p2p_status(cfg, ACTION_TX_COMPLETED)) {
		CFGP2P_DBG(("tx action frame operation is completed\n"));
		ret = BCME_OK;
	} else if (ETHER_ISBCAST(&cfg->afx_hdl->tx_dst_addr)) {
		CFGP2P_DBG(("bcast tx action frame operation is completed\n"));
		ret = BCME_OK;
	} else {
		ret = BCME_ERROR;
		CFGP2P_DBG(("tx action frame operation is failed\n"));
	}
	/* clear status bit for action tx */
	wl_clr_p2p_status(cfg, ACTION_TX_COMPLETED);
	wl_clr_p2p_status(cfg, ACTION_TX_NOACK);

exit:
	CFGP2P_DBG((" via act frame iovar : status = %d\n", ret));

	bzero(&buf, sizeof(wl_eventmsg_buf_t));
	wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, false);
	wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, false);
	if ((evt_ret = wl_cfg80211_apply_eventbuffer(bcmcfg_to_prmry_ndev(cfg), cfg, &buf)) < 0) {
		WL_ERR(("TX frame events revert back failed \n"));
		return evt_ret;
	}

	return ret;
}

/* Generate our P2P Device Address and P2P Interface Address from our primary
 * MAC address.
 */
void
wl_cfgp2p_generate_bss_mac(struct bcm_cfg80211 *cfg, struct ether_addr *primary_addr)
{
	struct ether_addr *mac_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE);
	struct ether_addr *int_addr;

#ifdef WL_P2P_USE_RANDMAC
	dhd_generate_mac_addr(mac_addr);
#else
	memcpy(mac_addr, primary_addr, sizeof(struct ether_addr));
	mac_addr->octet[0] |= 0x02;
	WL_DBG(("P2P Discovery address:"MACDBG "\n", MAC2STRDBG(mac_addr->octet)));
#endif /* WL_P2P_USE_RANDMAC */

	int_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_CONNECTION1);
	memcpy(int_addr, mac_addr, sizeof(struct ether_addr));
	int_addr->octet[4] ^= 0x80;
	WL_DBG(("Primary P2P Interface address:"MACDBG "\n", MAC2STRDBG(int_addr->octet)));

	int_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_CONNECTION2);
	memcpy(int_addr, mac_addr, sizeof(struct ether_addr));
	int_addr->octet[4] ^= 0x90;
}

/* P2P IF Address change to Virtual Interface MAC Address */
void
wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id)
{
	wifi_p2p_ie_t *ie = (wifi_p2p_ie_t*) buf;
	u16 len = ie->len;
	u8 *subel;
	u8 subelt_id;
	u16 subelt_len;
	CFGP2P_DBG((" Enter\n"));

	/* Point subel to the P2P IE's subelt field.
	 * Subtract the preceding fields (id, len, OUI, oui_type) from the length.
	 */
	subel = ie->subelts;
	len -= 4;	/* exclude OUI + OUI_TYPE */

	while (len >= 3) {
	/* attribute id */
		subelt_id = *subel;
		subel += 1;
		len -= 1;

		/* 2-byte little endian */
		subelt_len = *subel++;
		subelt_len |= *subel++ << 8;

		len -= 2;
		len -= subelt_len;	/* for the remaining subelt fields */

		if (subelt_id == element_id) {
			if (subelt_id == P2P_SEID_INTINTADDR) {
				memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
				CFGP2P_INFO(("Intended P2P Interface Address ATTR FOUND\n"));
			} else if (subelt_id == P2P_SEID_DEV_ID) {
				memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
				CFGP2P_INFO(("Device ID ATTR FOUND\n"));
			} else if (subelt_id == P2P_SEID_DEV_INFO) {
				memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
				CFGP2P_INFO(("Device INFO ATTR FOUND\n"));
			} else if (subelt_id == P2P_SEID_GROUP_ID) {
				memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
				CFGP2P_INFO(("GROUP ID ATTR FOUND\n"));
			}			return;
		} else {
			CFGP2P_DBG(("OTHER id : %d\n", subelt_id));
		}
		subel += subelt_len;
	}
}

s32
wl_cfgp2p_supported(struct bcm_cfg80211 *cfg, struct net_device *ndev)
{
	s32 ret = BCME_OK;
	s32 p2p_supported = 0;
	ret = wldev_iovar_getint(ndev, "p2p",
	               &p2p_supported);
	if (ret < 0) {
		if (ret == BCME_UNSUPPORTED) {
			CFGP2P_INFO(("p2p is unsupported\n"));
			return 0;
		} else {
			CFGP2P_ERR(("cfg p2p error %d\n", ret));
			return ret;
		}
	}
	if (cfg->pub->conf->fw_type == FW_TYPE_MESH)
		p2p_supported = 0;
	if (p2p_supported == 1) {
		CFGP2P_INFO(("p2p is supported\n"));
	} else {
		CFGP2P_INFO(("p2p is unsupported\n"));
		p2p_supported = 0;
	}
	return p2p_supported;
}

/* Cleanup P2P resources */
s32
wl_cfgp2p_down(struct bcm_cfg80211 *cfg)
{
	struct net_device *ndev = NULL;
	struct wireless_dev *wdev = NULL;

#if defined(WL_CFG80211_P2P_DEV_IF)
	ndev = bcmcfg_to_prmry_ndev(cfg);
	wdev = bcmcfg_to_p2p_wdev(cfg);
#elif defined(WL_ENABLE_P2P_IF)
	ndev = cfg->p2p_net ? cfg->p2p_net : bcmcfg_to_prmry_ndev(cfg);
	wdev = ndev_to_wdev(ndev);
#endif /* WL_CFG80211_P2P_DEV_IF */

	wl_cfgp2p_cancel_listen(cfg, ndev, wdev, TRUE);
	wl_cfgp2p_disable_discovery(cfg);

#if defined(WL_CFG80211_P2P_DEV_IF) && !defined(KEEP_WIFION_OPTION)
/*
 * In CUSTOMER_HW4 implementation "ifconfig wlan0 down" can get
 * called during phone suspend and customer requires the p2p
 * discovery interface to be left untouched so that the user
 * space can resume without any problem.
 */
	if (cfg->p2p_wdev) {
		/* If p2p wdev is left out, clean it up */
		WL_ERR(("Clean up the p2p discovery IF\n"));
		wl_cfgp2p_del_p2p_disc_if(cfg->p2p_wdev, cfg);
	}
#endif /* WL_CFG80211_P2P_DEV_IF !defined(KEEP_WIFION_OPTION) */

	wl_cfgp2p_deinit_priv(cfg);
	return 0;
}

int wl_cfgp2p_vif_created(struct bcm_cfg80211 *cfg)
{
	if (cfg->p2p && ((wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_CONNECTION1) != -1) ||
		(wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_CONNECTION2) != -1)))
		return true;
	else
		return false;

}

s32
wl_cfgp2p_set_p2p_noa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len)
{
	s32 ret = -1;
	int count, start, duration;
	wl_p2p_sched_t dongle_noa;
	s32 bssidx, type;
	int iovar_len = sizeof(dongle_noa);
	CFGP2P_DBG((" Enter\n"));

	bzero(&dongle_noa, sizeof(dongle_noa));

	if (wl_cfgp2p_vif_created(cfg)) {
		cfg->p2p->noa.desc[0].start = 0;

		sscanf(buf, "%10d %10d %10d", &count, &start, &duration);
		CFGP2P_DBG(("set_p2p_noa count %d start %d duration %d\n",
			count, start, duration));
		if (count != -1)
			cfg->p2p->noa.desc[0].count = count;

		/* supplicant gives interval as start */
		if (start != -1)
			cfg->p2p->noa.desc[0].interval = start;

		if (duration != -1)
			cfg->p2p->noa.desc[0].duration = duration;

		if (cfg->p2p->noa.desc[0].count != 255 && cfg->p2p->noa.desc[0].count != 0) {
			cfg->p2p->noa.desc[0].start = 200;
			dongle_noa.type = WL_P2P_SCHED_TYPE_REQ_ABS;
			dongle_noa.action = WL_P2P_SCHED_ACTION_GOOFF;
			dongle_noa.option = WL_P2P_SCHED_OPTION_TSFOFS;
		}
		else if (cfg->p2p->noa.desc[0].count == 0) {
			cfg->p2p->noa.desc[0].start = 0;
			dongle_noa.type = WL_P2P_SCHED_TYPE_ABS;
			dongle_noa.option = WL_P2P_SCHED_OPTION_NORMAL;
			dongle_noa.action = WL_P2P_SCHED_ACTION_RESET;
		}
		else {
			/* Continuous NoA interval. */
			dongle_noa.action = WL_P2P_SCHED_ACTION_DOZE;
			dongle_noa.type = WL_P2P_SCHED_TYPE_ABS;
			if ((cfg->p2p->noa.desc[0].interval == 102) ||
				(cfg->p2p->noa.desc[0].interval == 100)) {
				cfg->p2p->noa.desc[0].start = 100 -
					cfg->p2p->noa.desc[0].duration;
				dongle_noa.option = WL_P2P_SCHED_OPTION_BCNPCT;
			}
			else {
				dongle_noa.option = WL_P2P_SCHED_OPTION_NORMAL;
			}
		}
		/* Put the noa descriptor in dongle format for dongle */
		dongle_noa.desc[0].count = htod32(cfg->p2p->noa.desc[0].count);
		if (dongle_noa.option == WL_P2P_SCHED_OPTION_BCNPCT) {
			dongle_noa.desc[0].start = htod32(cfg->p2p->noa.desc[0].start);
			dongle_noa.desc[0].duration = htod32(cfg->p2p->noa.desc[0].duration);
		}
		else {
			dongle_noa.desc[0].start = htod32(cfg->p2p->noa.desc[0].start*1000);
			dongle_noa.desc[0].duration = htod32(cfg->p2p->noa.desc[0].duration*1000);
		}
		dongle_noa.desc[0].interval = htod32(cfg->p2p->noa.desc[0].interval*1000);
		bssidx = wl_get_bssidx_by_wdev(cfg, ndev->ieee80211_ptr);
		if (wl_cfgp2p_find_type(cfg, bssidx, &type) != BCME_OK)
			return BCME_ERROR;

		if (dongle_noa.action == WL_P2P_SCHED_ACTION_RESET) {
			iovar_len -= sizeof(wl_p2p_sched_desc_t);
		}

		ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(cfg, type),
			"p2p_noa", &dongle_noa, iovar_len, cfg->ioctl_buf,
			WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);

		if (ret < 0) {
			CFGP2P_ERR(("fw set p2p_noa failed %d\n", ret));
		}
	}
	else {
		CFGP2P_ERR(("ERROR: set_noa in non-p2p mode\n"));
	}
	return ret;
}
s32
wl_cfgp2p_get_p2p_noa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int buf_len)
{

	wifi_p2p_noa_desc_t *noa_desc;
	int len = 0, i;
	char _buf[200];

	CFGP2P_DBG((" Enter\n"));
	buf[0] = '\0';
	if (wl_cfgp2p_vif_created(cfg)) {
		if (cfg->p2p->noa.desc[0].count || cfg->p2p->ops.ops) {
			_buf[0] = 1; /* noa index */
			_buf[1] = (cfg->p2p->ops.ops ? 0x80: 0) |
				(cfg->p2p->ops.ctw & 0x7f); /* ops + ctw */
			len += 2;
			if (cfg->p2p->noa.desc[0].count) {
				noa_desc = (wifi_p2p_noa_desc_t*)&_buf[len];
				noa_desc->cnt_type = cfg->p2p->noa.desc[0].count;
				noa_desc->duration = cfg->p2p->noa.desc[0].duration;
				noa_desc->interval = cfg->p2p->noa.desc[0].interval;
				noa_desc->start = cfg->p2p->noa.desc[0].start;
				len += sizeof(wifi_p2p_noa_desc_t);
			}
			if (buf_len <= len * 2) {
				CFGP2P_ERR(("ERROR: buf_len %d in not enough for"
					"returning noa in string format\n", buf_len));
				return -1;
			}
			/* We have to convert the buffer data into ASCII strings */
			for (i = 0; i < len; i++) {
				snprintf(buf, 3, "%02x", _buf[i]);
				buf += 2;
			}
			buf[i*2] = '\0';
		}
	}
	else {
		CFGP2P_ERR(("ERROR: get_noa in non-p2p mode\n"));
		return -1;
	}
	return len * 2;
}
s32
wl_cfgp2p_set_p2p_ps(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len)
{
	int ps, ctw;
	int ret = -1;
	s32 legacy_ps;
	s32 conn_idx;
	s32 bssidx;
	struct net_device *dev;

	CFGP2P_DBG((" Enter\n"));
	if (wl_cfgp2p_vif_created(cfg)) {
		sscanf(buf, "%10d %10d %10d", &legacy_ps, &ps, &ctw);
		CFGP2P_DBG((" Enter legacy_ps %d ps %d ctw %d\n", legacy_ps, ps, ctw));

		bssidx = wl_get_bssidx_by_wdev(cfg, ndev->ieee80211_ptr);
		if (wl_cfgp2p_find_type(cfg, bssidx, &conn_idx) != BCME_OK)
			return BCME_ERROR;
		dev = wl_to_p2p_bss_ndev(cfg, conn_idx);
		if (ctw != -1) {
			cfg->p2p->ops.ctw = ctw;
			ret = 0;
		}
		if (ps != -1) {
			cfg->p2p->ops.ops = ps;
			ret = wldev_iovar_setbuf(dev,
				"p2p_ops", &cfg->p2p->ops, sizeof(cfg->p2p->ops),
				cfg->ioctl_buf, WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
			if (ret < 0) {
				CFGP2P_ERR(("fw set p2p_ops failed %d\n", ret));
			}
		}

		if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) {
			ret = wldev_ioctl_set(dev,
				WLC_SET_PM, &legacy_ps, sizeof(legacy_ps));
			if (unlikely(ret))
				CFGP2P_ERR(("error (%d)\n", ret));
			wl_cfg80211_update_power_mode(dev);
		}
		else
			CFGP2P_ERR(("ilegal setting\n"));
	}
	else {
		CFGP2P_ERR(("ERROR: set_p2p_ps in non-p2p mode\n"));
		ret = -1;
	}
	return ret;
}

s32
wl_cfgp2p_set_p2p_ecsa(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len)
{
	int ch, bw;
	s32 conn_idx;
	s32 bssidx;
	struct net_device *dev;
	char smbuf[WLC_IOCTL_SMLEN];
	wl_chan_switch_t csa_arg;
	u32 chnsp = 0;
	int err = 0;

	CFGP2P_DBG((" Enter\n"));
	if (wl_cfgp2p_vif_created(cfg)) {
		sscanf(buf, "%10d %10d", &ch, &bw);
		CFGP2P_DBG(("Enter ch %d bw %d\n", ch, bw));

		bssidx = wl_get_bssidx_by_wdev(cfg, ndev->ieee80211_ptr);
		if (wl_cfgp2p_find_type(cfg, bssidx, &conn_idx) != BCME_OK) {
			return BCME_ERROR;
		}
		dev = wl_to_p2p_bss_ndev(cfg, conn_idx);
		if (ch <= 0 || bw <= 0) {
			CFGP2P_ERR(("Negative value not permitted!\n"));
			return BCME_ERROR;
		}

		memset_s(&csa_arg, sizeof(csa_arg), 0, sizeof(csa_arg));
		csa_arg.mode = DOT11_CSA_MODE_ADVISORY;
		csa_arg.count = P2P_ECSA_CNT;
		csa_arg.reg = 0;

		snprintf(buf, len, "%d/%d", ch, bw);
		chnsp = wf_chspec_aton(buf);
		if (chnsp == 0) {
			CFGP2P_ERR(("%s:chsp is not correct\n", __FUNCTION__));
			return BCME_ERROR;
		}
		chnsp = wl_chspec_host_to_driver(chnsp);
		csa_arg.chspec = chnsp;

		err = wldev_iovar_setbuf(dev, "csa", &csa_arg, sizeof(csa_arg),
			smbuf, sizeof(smbuf), NULL);
		if (err) {
			CFGP2P_ERR(("%s:set p2p_ecsa failed:%d\n", __FUNCTION__, err));
			return BCME_ERROR;
		}
	} else {
		CFGP2P_ERR(("ERROR: set_p2p_ecsa in non-p2p mode\n"));
		return BCME_ERROR;
	}
	return BCME_OK;
}

s32
wl_cfgp2p_increase_p2p_bw(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* buf, int len)
{
	int algo;
	int bw;
	int ret = BCME_OK;

	sscanf(buf, "%3d", &bw);
	if (bw == 0) {
		algo = 0;
		ret = wldev_iovar_setbuf(ndev, "mchan_algo", &algo, sizeof(algo), cfg->ioctl_buf,
				WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
		if (ret < 0) {
			CFGP2P_ERR(("fw set mchan_algo failed %d\n", ret));
			return BCME_ERROR;
		}
	} else {
		algo = 1;
		ret = wldev_iovar_setbuf(ndev, "mchan_algo", &algo, sizeof(algo), cfg->ioctl_buf,
				WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
		if (ret < 0) {
			CFGP2P_ERR(("fw set mchan_algo failed %d\n", ret));
			return BCME_ERROR;
		}
		ret = wldev_iovar_setbuf(ndev, "mchan_bw", &bw, sizeof(algo), cfg->ioctl_buf,
				WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
		if (ret < 0) {
			CFGP2P_ERR(("fw set mchan_bw failed %d\n", ret));
			return BCME_ERROR;
		}
	}
	return BCME_OK;
}

const u8 *
wl_cfgp2p_retreive_p2pattrib(const void *buf, u8 element_id)
{
	const wifi_p2p_ie_t *ie = NULL;
	u16 len = 0;
	const u8 *subel;
	u8 subelt_id;
	u16 subelt_len;

	if (!buf) {
		WL_ERR(("P2P IE not present"));
		return 0;
	}

	ie = (const wifi_p2p_ie_t*) buf;
	len = ie->len;

	/* Point subel to the P2P IE's subelt field.
	 * Subtract the preceding fields (id, len, OUI, oui_type) from the length.
	 */
	subel = ie->subelts;
	len -= 4;	/* exclude OUI + OUI_TYPE */

	while (len >= 3) {
		/* attribute id */
		subelt_id = *subel;
		subel += 1;
		len -= 1;

		/* 2-byte little endian */
		subelt_len = *subel++;
		subelt_len |= *subel++ << 8;

		len -= 2;
		len -= subelt_len;	/* for the remaining subelt fields */

		if (subelt_id == element_id) {
			/* This will point to start of subelement attrib after
			 * attribute id & len
			 */
			return subel;
		}

		/* Go to next subelement */
		subel += subelt_len;
	}

	/* Not Found */
	return NULL;
}

#define P2P_GROUP_CAPAB_GO_BIT	0x01

const u8*
wl_cfgp2p_find_attrib_in_all_p2p_Ies(const u8 *parse, u32 len, u32 attrib)
{
	bcm_tlv_t *ie;
	const u8* pAttrib;
	uint ie_len;

	CFGP2P_DBG(("Starting parsing parse %p attrib %d remaining len %d ", parse, attrib, len));
	ie_len = len;
	while ((ie = bcm_parse_tlvs(parse, ie_len, DOT11_MNG_VS_ID))) {
		if (wl_cfgp2p_is_p2p_ie(ie, &parse, &ie_len) == TRUE) {
			/* Have the P2p ie. Now check for attribute */
			if ((pAttrib = wl_cfgp2p_retreive_p2pattrib(ie, attrib)) != NULL) {
				CFGP2P_DBG(("P2P attribute %d was found at parse %p",
					attrib, parse));
				return pAttrib;
			}
			else {
				/* move to next IE */
				bcm_tlv_buffer_advance_past(ie, &parse, &ie_len);

				CFGP2P_INFO(("P2P Attribute %d not found Moving parse"
					" to %p len to %d", attrib, parse, ie_len));
			}
		}
		else {
			/* It was not p2p IE. parse will get updated automatically to next TLV */
			CFGP2P_INFO(("IT was NOT P2P IE parse %p len %d", parse, ie_len));
		}
	}
	CFGP2P_ERR(("P2P attribute %d was NOT found", attrib));
	return NULL;
}

const u8 *
wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length)
{
	const u8 *capability = NULL;
	bool p2p_go	= 0;
	const u8 *ptr = NULL;

	if (bi->length != bi->ie_offset + bi->ie_length) {
		return NULL;
	}

	if ((capability = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset,
	bi->ie_length, P2P_SEID_P2P_INFO)) == NULL) {
		WL_ERR(("P2P Capability attribute not found"));
		return NULL;
	}

	/* Check Group capability for Group Owner bit */
	p2p_go = capability[1] & P2P_GROUP_CAPAB_GO_BIT;
	if (!p2p_go) {
		return bi->BSSID.octet;
	}

	/* In probe responses, DEVICE INFO attribute will be present */
	if (!(ptr = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset,
	bi->ie_length,  P2P_SEID_DEV_INFO))) {
		/* If DEVICE_INFO is not found, this might be a beacon frame.
		 * check for DEVICE_ID in the beacon frame.
		 */
		ptr = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset,
		bi->ie_length,  P2P_SEID_DEV_ID);
	}

	if (!ptr)
		WL_ERR((" Both DEVICE_ID & DEVICE_INFO attribute not present in P2P IE "));

	return ptr;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
static void
wl_cfgp2p_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
{
	snprintf(info->driver, sizeof(info->driver), "p2p");
	snprintf(info->version, sizeof(info->version), "%lu", (unsigned long)(0));
}

struct ethtool_ops cfgp2p_ethtool_ops = {
	.get_drvinfo = wl_cfgp2p_ethtool_get_drvinfo
};
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */

#if defined(WL_ENABLE_P2P_IF)
s32
wl_cfgp2p_register_ndev(struct bcm_cfg80211 *cfg)
{
	int ret = 0;
	struct net_device* net = NULL;
	struct wireless_dev *wdev = NULL;
	uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 };

	if (cfg->p2p_net) {
		CFGP2P_ERR(("p2p_net defined already.\n"));
		return -EINVAL;
	}

	/* Allocate etherdev, including space for private structure */
	if (!(net = alloc_etherdev(sizeof(struct bcm_cfg80211 *)))) {
		CFGP2P_ERR(("%s: OOM - alloc_etherdev\n", __FUNCTION__));
		return -ENODEV;
	}

	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
	if (unlikely(!wdev)) {
		WL_ERR(("Could not allocate wireless device\n"));
		free_netdev(net);
		return -ENOMEM;
	}

	strncpy(net->name, "p2p%d", sizeof(net->name) - 1);
	net->name[IFNAMSIZ - 1] = '\0';

	/* Copy the reference to bcm_cfg80211 */
	memcpy((void *)netdev_priv(net), &cfg, sizeof(struct bcm_cfg80211 *));

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
	ASSERT(!net->open);
	net->do_ioctl = wl_cfgp2p_do_ioctl;
	net->hard_start_xmit = wl_cfgp2p_start_xmit;
	net->open = wl_cfgp2p_if_open;
	net->stop = wl_cfgp2p_if_stop;
#else
	ASSERT(!net->netdev_ops);
	net->netdev_ops = &wl_cfgp2p_if_ops;
#endif

	/* Register with a dummy MAC addr */
	memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN);

	wdev->wiphy = cfg->wdev->wiphy;

	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);

	net->ieee80211_ptr = wdev;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
	net->ethtool_ops = &cfgp2p_ethtool_ops;
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */

	SET_NETDEV_DEV(net, wiphy_dev(wdev->wiphy));

	/* Associate p2p0 network interface with new wdev */
	wdev->netdev = net;

	ret = register_netdev(net);
	if (ret) {
		CFGP2P_ERR((" register_netdevice failed (%d)\n", ret));
		free_netdev(net);
		kfree(wdev);
		return -ENODEV;
	}

	/* store p2p net ptr for further reference. Note that iflist won't have this
	 * entry as there corresponding firmware interface is a "Hidden" interface.
	 */
	cfg->p2p_wdev = wdev;
	cfg->p2p_net = net;

	printk("%s: P2P Interface Registered\n", net->name);

	return ret;
}

s32
wl_cfgp2p_unregister_ndev(struct bcm_cfg80211 *cfg)
{

	if (!cfg || !cfg->p2p_net) {
		CFGP2P_ERR(("Invalid Ptr\n"));
		return -EINVAL;
	}

	unregister_netdev(cfg->p2p_net);
	free_netdev(cfg->p2p_net);

	return 0;
}
static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{

	if (skb)
	{
		CFGP2P_DBG(("(%s) is not used for data operations.Droping the packet.\n",
			ndev->name));
		dev_kfree_skb_any(skb);
	}

	return 0;
}

static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd)
{
	int ret = 0;
	struct bcm_cfg80211 *cfg = *(struct bcm_cfg80211 **)netdev_priv(net);
	struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);

	/* There is no ifidx corresponding to p2p0 in our firmware. So we should
	 * not Handle any IOCTL cmds on p2p0 other than ANDROID PRIVATE CMDs.
	 * For Android PRIV CMD handling map it to primary I/F
	 */
	if (cmd == SIOCDEVPRIVATE+1) {
		ret = wl_android_priv_cmd(ndev, ifr);

	} else {
		CFGP2P_ERR(("%s: IOCTL req 0x%x on p2p0 I/F. Ignoring. \n",
		__FUNCTION__, cmd));
		return -1;
	}

	return ret;
}
#endif 

#if defined(WL_ENABLE_P2P_IF)
static int wl_cfgp2p_if_open(struct net_device *net)
{
	struct wireless_dev *wdev = net->ieee80211_ptr;

	if (!wdev || !wl_cfg80211_is_p2p_active(net))
		return -EINVAL;
	WL_TRACE(("Enter\n"));
#if !defined(WL_IFACE_COMB_NUM_CHANNELS)
	/* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now,
	 * do it here. This will make sure that in concurrent mode, supplicant
	 * is not dependent on a particular order of interface initialization.
	 * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N
	 * -iwlan0.
	 */
	wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT)
		| BIT(NL80211_IFTYPE_P2P_GO));
#endif /* !WL_IFACE_COMB_NUM_CHANNELS */
	wl_cfg80211_do_driver_init(net);

	return 0;
}

static int wl_cfgp2p_if_stop(struct net_device *net)
{
	struct wireless_dev *wdev = net->ieee80211_ptr;
	struct bcm_cfg80211 *cfg = wl_get_cfg(net);

	if (!wdev)
		return -EINVAL;

	wl_cfg80211_scan_stop(cfg, net);

#if !defined(WL_IFACE_COMB_NUM_CHANNELS)
	wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes)
					& (~(BIT(NL80211_IFTYPE_P2P_CLIENT)|
					BIT(NL80211_IFTYPE_P2P_GO)));
#endif /* !WL_IFACE_COMB_NUM_CHANNELS */
	return 0;
}

bool wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops)
{
	return (if_ops == &wl_cfgp2p_if_ops);
}
#endif /* WL_ENABLE_P2P_IF */

#if defined(WL_CFG80211_P2P_DEV_IF)
struct wireless_dev *
wl_cfgp2p_add_p2p_disc_if(struct bcm_cfg80211 *cfg)
{
	struct wireless_dev *wdev = NULL;
	struct ether_addr primary_mac;

	if (!cfg || !cfg->p2p_supported)
		return ERR_PTR(-EINVAL);

	WL_TRACE(("Enter\n"));

	if (cfg->p2p_wdev) {
#ifndef EXPLICIT_DISCIF_CLEANUP
		dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
#endif /* EXPLICIT_DISCIF_CLEANUP */
		/*
		 * This is not expected. This can happen due to
		 * supplicant crash/unclean de-initialization which
		 * didn't free the p2p discovery interface. Indicate
		 * driver hang to user space so that the framework
		 * can rei-init the Wi-Fi.
		 */
		CFGP2P_ERR(("p2p_wdev defined already.\n"));
		wl_probe_wdev_all(cfg);
#ifdef EXPLICIT_DISCIF_CLEANUP
		/*
		 * CUSTOMER_HW4 design doesn't delete the p2p discovery
		 * interface on ifconfig wlan0 down context which comes
		 * without a preceeding NL80211_CMD_DEL_INTERFACE for p2p
		 * discovery. But during supplicant crash the DEL_IFACE
		 * command will not happen and will cause a left over iface
		 * even after ifconfig wlan0 down. So delete the iface
		 * first and then indicate the HANG event
		 */
		wl_cfgp2p_del_p2p_disc_if(cfg->p2p_wdev, cfg);
#else
		dhd->hang_reason = HANG_REASON_IFACE_DEL_FAILURE;
#if defined(BCMPCIE) && defined(DHD_FW_COREDUMP)
		if (dhd->memdump_enabled) {
			/* Load the dongle side dump to host
			 * memory and then BUG_ON()
			 */
			dhd->memdump_type = DUMP_TYPE_IFACE_OP_FAILURE;
			dhd_bus_mem_dump(dhd);
		}
#endif /* BCMPCIE && DHD_FW_COREDUMP */
		net_os_send_hang_message(bcmcfg_to_prmry_ndev(cfg));
		return ERR_PTR(-ENODEV);
#endif /* EXPLICIT_DISCIF_CLEANUP */
	}

	wdev = (struct wireless_dev *)MALLOCZ(cfg->osh, sizeof(*wdev));
	if (unlikely(!wdev)) {
		WL_ERR(("Could not allocate wireless device\n"));
		return ERR_PTR(-ENOMEM);
	}

	bzero(&primary_mac, sizeof(primary_mac));
	get_primary_mac(cfg, &primary_mac);
#ifndef WL_P2P_USE_RANDMAC
	wl_cfgp2p_generate_bss_mac(cfg, &primary_mac);
#endif /* WL_P2P_USE_RANDMAC */

	wdev->wiphy = cfg->wdev->wiphy;
	wdev->iftype = NL80211_IFTYPE_P2P_DEVICE;
	memcpy(wdev->address, wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE), ETHER_ADDR_LEN);

	/* store p2p wdev ptr for further reference. */
	cfg->p2p_wdev = wdev;

	printf("P2P interface registered\n");
	printf("%s: wdev: %p, wdev->net: %p\n", __FUNCTION__, wdev, wdev->netdev);
	return wdev;
}

int
wl_cfgp2p_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
{
	int ret = 0;
	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);

	if (!cfg)
		return -EINVAL;

	WL_TRACE(("Enter\n"));

	ret = wl_cfgp2p_set_firm_p2p(cfg);
	if (unlikely(ret < 0)) {
		CFGP2P_ERR(("Set P2P in firmware failed, ret=%d\n", ret));
		goto exit;
	}

	ret = wl_cfgp2p_enable_discovery(cfg, bcmcfg_to_prmry_ndev(cfg), NULL, 0);
	if (unlikely(ret < 0)) {
		CFGP2P_ERR(("P2P enable discovery failed, ret=%d\n", ret));
		goto exit;
	}

	p2p_on(cfg) = true;
#if defined(P2P_IE_MISSING_FIX)
	cfg->p2p_prb_noti = false;
#endif // endif

	CFGP2P_DBG(("P2P interface started\n"));

exit:
	return ret;
}

void
wl_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
{
	int ret = 0;
	struct net_device *ndev = NULL;
	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);

	if (!cfg)
		return;

	CFGP2P_DBG(("Enter\n"));

	/* Check if cfg80211 interface is already down */
	ndev = bcmcfg_to_prmry_ndev(cfg);
	if (!wl_get_drv_status(cfg, READY, ndev)) {
		WL_DBG(("cfg80211 interface is already down\n"));
		return;	/* it is even not ready */
	}

	ret = wl_cfg80211_scan_stop(cfg, wdev);
	if (unlikely(ret < 0)) {
		CFGP2P_ERR(("P2P scan stop failed, ret=%d\n", ret));
	}

	if (!p2p_is_on(cfg)) {
		return;
	}

#ifdef P2P_LISTEN_OFFLOADING
	wl_cfg80211_p2plo_deinit(cfg);
#endif /* P2P_LISTEN_OFFLOADING */

	/* Cancel any on-going listen */
	wl_cfgp2p_cancel_listen(cfg, bcmcfg_to_prmry_ndev(cfg), wdev, TRUE);

	ret = wl_cfgp2p_disable_discovery(cfg);
	if (unlikely(ret < 0)) {
		CFGP2P_ERR(("P2P disable discovery failed, ret=%d\n", ret));
	}

	p2p_on(cfg) = false;

	CFGP2P_DBG(("Exit. P2P interface stopped\n"));

	return;
}

int
wl_cfgp2p_del_p2p_disc_if(struct wireless_dev *wdev, struct bcm_cfg80211 *cfg)
{
	bool rollback_lock = false;

	if (!wdev || !cfg) {
		WL_ERR(("wdev or cfg is NULL\n"));
		return -EINVAL;
	}

	WL_INFORM(("Enter\n"));

	if (!cfg->p2p_wdev) {
		WL_ERR(("Already deleted p2p_wdev\n"));
		return -EINVAL;
	}

	if (!rtnl_is_locked()) {
		rtnl_lock();
		rollback_lock = true;
	}

	cfg80211_unregister_wdev(wdev);

	if (rollback_lock)
		rtnl_unlock();

	synchronize_rcu();

	MFREE(cfg->osh, wdev, sizeof(*wdev));

	cfg->p2p_wdev = NULL;

	CFGP2P_ERR(("P2P interface unregistered\n"));

	return 0;
}
#endif /* WL_CFG80211_P2P_DEV_IF */

void
wl_cfgp2p_need_wait_actfrmae(struct bcm_cfg80211 *cfg, void *frame, u32 frame_len, bool tx)
{
	wifi_p2p_pub_act_frame_t *pact_frm;
	int status = 0;

	if (!frame || (frame_len < (sizeof(*pact_frm) + WL_P2P_AF_STATUS_OFFSET - 1))) {
		return;
	}

	if (wl_cfgp2p_is_pub_action(frame, frame_len)) {
		pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
		if (pact_frm->subtype == P2P_PAF_GON_RSP && tx) {
			CFGP2P_ACTION(("Check TX P2P Group Owner Negotiation Rsp Frame status\n"));
			status = pact_frm->elts[WL_P2P_AF_STATUS_OFFSET];
			if (status) {
				cfg->need_wait_afrx = false;
				return;
			}
		}
	}

	cfg->need_wait_afrx = true;
	return;
}

int
wl_cfgp2p_is_p2p_specific_scan(struct cfg80211_scan_request *request)
{
	if (request && (request->n_ssids == 1) &&
		(request->n_channels == 1) &&
		IS_P2P_SSID(request->ssids[0].ssid, WL_P2P_WILDCARD_SSID_LEN) &&
		(request->ssids[0].ssid_len > WL_P2P_WILDCARD_SSID_LEN)) {
		return true;
	}
	return false;
}
