/**
  Copyright (c) 2008 - 2013 Quantenna Communications Inc
  All Rights Reserved

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

 **/

#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/version.h>

#include <linux/netdevice.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/rtnetlink.h>
#include <asm/hardware.h>
#include <asm/board/board_config.h>

#include <qtn/qdrv_sch.h>
#include <qtn/topaz_tqe_cpuif.h>
#include <qtn/topaz_fwt_db.h>

#ifdef CONFIG_QVSP
#include "qtn/qvsp.h"
#endif

#include "qdrv_features.h"
#include "qdrv_debug.h"
#include "qdrv_mac.h"
#include "qdrv_soc.h"
#include "qdrv_muc.h"
#include "qdrv_hal.h"
#include "qdrv_comm.h"
#include "qdrv_vap.h"
#include "qdrv_wlan.h"

extern void indicate_association(void);
extern void indicate_disassociation(void);
extern unsigned int g_led_assoc_indicate;

static bool wps_button_not_initd = 1;
static bool igmp_query_timer_not_initd = 1;
// TBD - Need to move this to a more suitable place
static int vnet_init(struct net_device *dev)
{
	struct qdrv_vap *qv = netdev_priv(dev);
	struct qdrv_wlan *qw = qv->parent;
	struct host_ioctl *ioctl;

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "-->Enter\n");

	ioctl = vnet_alloc_ioctl(qv);
	if (!ioctl) {
		DBGPRINTF_E("Failed to allocate message\n");
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return -1;
	}

	ioctl->ioctl_command = IOCTL_DEV_DEVOPEN;
	ioctl->ioctl_arg1 = qv->devid;
	ioctl->ioctl_arg2 = 0;
	ioctl->ioctl_argp = (u32) NULL;
	ioctl->ioctl_next = 0;
	ioctl->ioctl_status = 0;

	vnet_send_ioctl(qv, ioctl);

	napi_enable(&qv->napi);
	napi_schedule(&qv->napi);

	netif_start_queue(dev);

	/* Open the device for the 802.11 layer */
	ieee80211_open(dev);

	/* Set up the WPS button IRQ handler */
	// TBD - Need to move this to a more suitable place
	if (wps_button_not_initd) {
		wps_button_not_initd = 0;
		qdrv_wps_button_init(dev);
	}

	if (igmp_query_timer_not_initd &&
			qv->iv.iv_opmode == IEEE80211_M_HOSTAP) {
		qdrv_wlan_igmp_query_timer_start(qw);
		igmp_query_timer_not_initd = 0;
	}

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");

	return(0);
}

static int vnet_stop(struct net_device *dev)
{
	struct qdrv_vap *qv = netdev_priv(dev);
	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "-->Enter\n");

	/* close the device for the 802.11 layer */
	ieee80211_stop(dev);

	napi_disable(&qv->napi);
	netif_stop_queue(dev);

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");

	return 0;
}

static __sram_data struct net_device_ops vnet_device_ops;

static void vnet_start(struct net_device * dev)
{
	ether_setup(dev);

	dev->netdev_ops = &vnet_device_ops;
	dev->tx_queue_len = 500;
}

static int qdrv_vap_80211_newstate_callback(struct ieee80211vap *vap,
	enum ieee80211_state nstate, int arg)
{
	struct qdrv_vap *qv = container_of(vap, struct qdrv_vap, iv);
	struct qdrv_wlan *qw = (struct qdrv_wlan *)qv->parent;
	int error;
	int stamode;
	struct ieee80211com *ic = vap->iv_ic;
	enum ieee80211_state ostate;

	ostate = vap->iv_state;

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "-->Enter, caller %p\n", __builtin_return_address(0));

	if(vap->iv_state != nstate)
	{
		DBGPRINTF(DBG_LL_NOTICE, QDRV_LF_VAP,
				"New state for \"%s\" %s -> %s\n",
				vap->iv_dev->name, ieee80211_state_name[vap->iv_state],
				ieee80211_state_name[nstate]);
	}

	stamode = (vap->iv_opmode == IEEE80211_M_STA ||
				vap->iv_opmode == IEEE80211_M_IBSS ||
				vap->iv_opmode == IEEE80211_M_AHDEMO);

	switch (nstate) {
	case IEEE80211_S_RUN:
		DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
				"IEEE80211_S_RUN\n");
		switch (vap->iv_opmode) {

		case IEEE80211_M_HOSTAP:
			DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
					"IEEE80211_M_HOSTAP - Send Beacon\n");
			ic->ic_beacon_update(vap);

			break;
		case IEEE80211_M_STA:
		case IEEE80211_M_IBSS:
		case IEEE80211_M_AHDEMO:
			DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
				"IEEE80211_M_STA\n");
			indicate_association();
			ic->ic_join_bss(vap);
			SMSTAT(qw, sm_sta_associated);
			break;
		default:
			break;
		}
		break;
	case IEEE80211_S_INIT://    = 0,    /* default state */
		DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"IEEE80211_S_INIT\n");
		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
			ic->ic_beacon_stop(vap);
		} else if (vap->iv_opmode == IEEE80211_M_STA) {
			/* Pend disassociation with AP before TDLS link return to base channel */
			if (!ieee80211_tdls_return_to_base_channel(vap, 1))
				return 0;
		}
		indicate_disassociation();
		break;
	case IEEE80211_S_SCAN://    = 1,    /* scanning */
		DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
				"IEEE80211_S_SCAN\n");
		indicate_disassociation();
		if (arg == IEEE80211_SCAN_FAIL_TIMEOUT) {
			if (ostate == IEEE80211_S_AUTH) {
				SMSTAT(qw, sm_scan_auth_fail_scan_pend);
			} else if (ostate == IEEE80211_S_ASSOC) {
				SMSTAT(qw, sm_scan_assoc_fail_scan_pend);
			}
		}
		else if (arg == 0) {
			SMSTAT(qw, sm_scan_pend);
		}
		break;

	case IEEE80211_S_AUTH://    = 2,    /* try to authenticate */
		DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
				"IEEE80211_S_AUTH\n");
		indicate_disassociation();
		if (stamode) {
			if (ostate == IEEE80211_S_SCAN) {
				SMSTAT(qw, sm_auth_pend);
			} else {
				SMSTAT(qw, sm_run_deauth_auth_pend);
			}
		}
		break;
	case IEEE80211_S_ASSOC://   = 3,    /* try to assoc */
		DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
				"IEEE80211_S_ASSOC\n");
		indicate_disassociation();
		if (stamode) {
			if (ostate == IEEE80211_S_AUTH) {
				SMSTAT(qw, sm_assoc_pend);
			} else {
				SMSTAT(qw, sm_run_disassoc_assoc_pend);
			}
		}
		break;
	default:
		DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
				"<unknown state %d>\n", nstate);
		indicate_disassociation();
		break;
	}

	/* Pend disassociation before tearing down all of TDLS links */
	if (ieee80211_tdls_pend_disassociation(vap, nstate, arg))
		return 0;

	/* Invoke the parent method to complete the work.*/
	error = (*qv->qv_newstate)(vap, nstate, arg);

	return error;
}

int qdrv_vap_wds_mode(struct qdrv_vap *qv)
{
	return(qv->iv.iv_flags_ext & IEEE80211_FEXT_WDS ? 1 : 0);
}

#ifdef CONFIG_QVSP
static int qdrv_qvsp_ioctl(void *qw_, uint32_t param, uint32_t value)
{
#if TOPAZ_QTM
	struct qdrv_wlan *qw = qw_;

	switch (param) {
	case QVSP_CFG_FAT_MIN_CHECK_INTV:
		qw->vsp_check_intvl = value / MSEC_PER_SEC;
		break;
	case QVSP_CFG_ENABLED:
		if (value) {
			/* Give stats part 2 check interval to warm up */
			qw->vsp_enabling = 2;
		}
		break;
	default:
		break;
	}
#endif

	return qdrv_hostlink_qvsp(qw_, param, value);
}
#endif

static void qdrv_vap_set_last(struct qdrv_mac *mac)
{
	int i = QDRV_MAX_VAPS;

	while (i--) {
		if (mac->vnet[i]) {
			break;
		}
	}

	mac->vnet_last = i;
}

int qdrv_vap_vlan2index_sync(struct qdrv_vap *qv, uint16_t mode, uint16_t vid)
{
	uint8_t vap_id = qv->qv_vap_idx;
	uint8_t last = 0;

	if (mode == QVLAN_MODE_DYNAMIC)
		return 0;

	if (mode != QVLAN_MODE_ACCESS)
		vid = VLANID_INDEX_INITVAL;

	qdrv_sch_vlan2index[vap_id] = vid;

	/* find the last vap bound to a vlan */
	for (vap_id = 0; vap_id < ARRAY_SIZE(qdrv_sch_vlan2index); vap_id++) {
		if (qdrv_sch_vlan2index[vap_id] != VLANID_INDEX_INITVAL) {
			last = vap_id + 1;
		}
	}
	qdrv_vap_vlan_max = last;

#if !defined(CONFIG_TOPAZ_PCIE_HOST) && !defined(CONFIG_TOPAZ_PCIE_TARGET)
	qdrv_sch_set_vlanpath();
#endif
	return 0;
}

#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
int qdrv_get_active_sub_port(const struct net_bridge_port *p,
		uint32_t *sub_port_bitmap, int size)
{
	struct topaz_fwt_sw_mcast_entry *mcast_entry;
	int i;
	struct ieee80211vap *vap;
	struct ieee80211com *ic;
	struct ieee80211_node *ni;
	int skip;

	if (size != sizeof(mcast_entry->node_bitmap)) {
		DBGPRINTF_LIMIT_E("bitmap length is invalid - %d/%d\n",
			size, sizeof(mcast_entry->node_bitmap));
		return 0;
	}

	/* Use the ipff entry, which has the bit set for each active node */
	mcast_entry = fwt_db_get_sw_mcast_ff();
	memcpy(sub_port_bitmap, mcast_entry->node_bitmap, size);

	vap = (struct ieee80211vap *)netdev_priv(p->dev);
	/* something unexpected */
	if (vap->iv_dev != p->dev) {
		DBGPRINTF_LIMIT_E("%s: net_device mismatch - %p/%p\n", __FUNCTION__,
			vap->iv_dev, p->dev);
		return 0;
	}

	ic = vap->iv_ic;

	/* some nodes(sub ports) in 'sub_port_bitmap' may not belong to 'vap' */
	for (i = 0; i < QTN_NCIDX_MAX; i++) {
		if ((sub_port_bitmap[BR_SUBPORT_IDX(i)] & BR_SUBPORT_BITMAP(i)) == 0)
			continue;

		ni = ieee80211_find_node_by_idx(ic, vap, i);
		if (ni == NULL) {
			/* node not found or doesn't belong to 'vap' */
			skip = 1;
		} else if (ni->ni_node_idx == 0) {
			/* race condition  */
			skip = 1;
		} else {
			skip = 0;
		}

		if (ni != NULL)
			ieee80211_free_node(ni);

		if (skip)
			sub_port_bitmap[BR_SUBPORT_IDX(i)] &= ~BR_SUBPORT_BITMAP(i);
	}

	for (i = 0; i < ARRAY_SIZE(mcast_entry->node_bitmap); i++) {
		if (sub_port_bitmap[i])
			return 1;
	}

	return 0;
}

int qdrv_check_active_sub_port(const struct net_bridge_port *p,
		const uint32_t sub_port)
{
	struct net_device *dev;
	struct ieee80211vap *vap;
	struct ieee80211com *ic;
	struct ieee80211_node_table *nt;
	struct ieee80211_node *ni;

	dev = p->dev;
	vap = netdev_priv(dev);

	if (vap->iv_dev != dev)
		return -1;

	BUG_ON(QTN_NCIDX_MAX < IEEE80211_NODE_IDX_UNMAP(sub_port));

	ic = vap->iv_ic;
	nt = &ic->ic_sta;

	IEEE80211_NODE_LOCK_IRQ(nt);
	ni = ic->ic_node_idx_ni[IEEE80211_NODE_IDX_UNMAP(sub_port)];
	IEEE80211_NODE_UNLOCK_IRQ(nt);

	return (ni && ieee80211_node_is_running(ni));
}
#endif

int qdrv_vap_init(struct qdrv_mac *mac, struct host_ioctl_hifinfo *hifinfo,
	u32 arg1, u32 arg2)
{
	struct qdrv_vap *qv;
	struct net_device *vdev;
	int opmode = 0;
	int vap_idx = 0;
	int i;
	struct ieee80211com *ic = NULL;
	struct ieee80211vap *vap = NULL;
	struct qdrv_wlan *qw;
	int stamode;
	int repeater_mode;
	unsigned int qv_devid = arg1 & IOCTL_DEVATTACH_DEVID_MASK;
	unsigned int dev_devid = QDRV_WLANID_FROM_DEVID(qv_devid);

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "-->Enter\n");

	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"name         : %s\n", hifinfo->hi_name);
	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"semmap       : %d\n", hifinfo->hi_semmap[0]);
	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"mbox         : 0x%08x\n", hifinfo->hi_mboxstart);
	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"rxfifo       : 0x%08x\n", hifinfo->hi_rxfifo);
	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"scanirq      : 0x%08x\n", hifinfo->hi_scanirq);
	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"scanfifo     : 0x%08x\n", hifinfo->hi_scanfifo);
	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"qv_devid     : 0x%08x\n", qv_devid);
	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"dev_devid    : 0x%08x\n", dev_devid);

	/* Search for an empty VAP slot */
	for (i = 0; i < QDRV_MAX_VAPS; i++) {
		if (mac->vnet[i] == NULL) {
			/* Found one */
			vap_idx = i;
			break;
		}
	}

	/* Check if we found one */
	if (i == QDRV_MAX_VAPS) {
		DBGPRINTF_E("No empty VAP slot available for \"%s\"\n",
			hifinfo->hi_name);
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return(-1);
	}

	vdev = dev_get_by_name(&init_net, hifinfo->hi_name);
	if (vdev != NULL) {
		DBGPRINTF_E("The device name \"%s\" already exists\n",
			hifinfo->hi_name);
		dev_put(vdev);
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return(-1);
	}

	/* Allocate our device */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	vdev = alloc_netdev(sizeof(struct qdrv_vap), hifinfo->hi_name, NET_NAME_UNKNOWN, vnet_start);
#else
	vdev = alloc_netdev(sizeof(struct qdrv_vap), hifinfo->hi_name, vnet_start);
#endif
	if (vdev == NULL) {
		DBGPRINTF_E("Unable to allocate device \"%s\"\n",
			hifinfo->hi_name);
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return(-1);
	}

	opmode = (arg1  >> 24) & 0xF;

	qv = netdev_priv(vdev);
	memset(qv, 0, sizeof(struct qdrv_vap));

	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"qv 0x%08x iv 0x%08x dev 0x%08x\n",
			(unsigned int) qv, (unsigned int) &qv->iv, (unsigned int) vdev);

	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"vap_idx %d opmode %d\n", vap_idx, opmode);

	qv->ndev = vdev;
	qv->parent = mac->data;
	qw = (struct qdrv_wlan *)qv->parent;
	qv->devid = qv_devid;
	qv->qv_vap_idx = hifinfo->hi_vapid;
	if (qv->qv_vap_idx >= QTN_MAX_BSS_VAPS)
		panic("vapid: %u is out of range!\n", qv->qv_vap_idx);
	vdev->dev_id = dev_devid;

	vdev->qtn_flags |= QTN_FLAG_WIFI_DEVICE;
	TAILQ_INIT(&qv->allnodes);

	vdev->if_port = TOPAZ_TQE_WMAC_PORT;

	netif_napi_add(vdev, &qv->napi, qdrv_rx_poll, board_napi_budget());

	memcpy(vdev->dev_addr, hifinfo->hi_macaddr, IEEE80211_ADDR_LEN);

	spin_lock_init(&qv->lock);
	spin_lock_init(&qv->bc_lock);
	spin_lock_init(&qv->ni_lst_lock);

	/* Initiate a VAP setup */
	if (ieee80211_vap_setup(&((struct qdrv_wlan *) mac->data)->ic, vdev,
		hifinfo->hi_name, qv->devid, opmode, IEEE80211_NO_STABEACONS) < 0) {
		DBGPRINTF_E("The 802.11 layer failed to setup the VAP\n");
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return -1;
	}

	/* Replace newstate function with our own */
	qv->qv_newstate = qv->iv.iv_newstate;
	qv->iv.iv_newstate = qdrv_vap_80211_newstate_callback;

	/* Take the RTNL lock since register_netdevice() is used instead of */
	/* register_netdev() in ieee80211_vap_attach()                      */
	rtnl_lock();

	/* Complete the VAP setup */
	if (ieee80211_vap_attach(&qv->iv,
		ieee80211_media_change, ieee80211_media_status) < 0) {
		DBGPRINTF_E("The 802.11 layer failed to attach the VAP\n");
		rtnl_unlock();
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return -1;
	}

	ic = &((struct qdrv_wlan *) mac->data)->ic;
	vap = &qv->iv;

	vap->iv_sta_assoc_limit = QTN_ASSOC_LIMIT;
	vap->iv_ssid_group = 0;

	stamode = (vap->iv_opmode == IEEE80211_M_STA ||
				vap->iv_opmode == IEEE80211_M_IBSS ||
				vap->iv_opmode == IEEE80211_M_AHDEMO);

	repeater_mode = (ic->ic_flags_ext & IEEE80211_FEXT_REPEATER);

	if (stamode || repeater_mode) {
		ic->ic_mindwell_active = QDRV_WLAN_STA_MIN_DWELLTIME_ACTIVE;
		ic->ic_mindwell_passive = QDRV_WLAN_STA_MIN_DWELLTIME_PASSIVE;
		ic->ic_maxdwell_active = QDRV_WLAN_STA_MAX_DWELLTIME_ACTIVE;
		ic->ic_maxdwell_passive = QDRV_WLAN_STA_MAX_DWELLTIME_PASSIVE;
		ic->ic_opmode = IEEE80211_M_STA;
		QDRV_SET_SM_FLAG(qw->sm_stats, QDRV_WLAN_SM_STATE_STA);

		if (repeater_mode)
			ic->ic_roaming = IEEE80211_ROAMING_AUTO;
	} else {
		ic->ic_mindwell_active = QDRV_WLAN_AP_MIN_DWELLTIME_ACTIVE;
		ic->ic_mindwell_passive = QDRV_WLAN_AP_MIN_DWELLTIME_PASSIVE;
		ic->ic_maxdwell_active = QDRV_WLAN_AP_MAX_DWELLTIME_ACTIVE;
		ic->ic_maxdwell_passive = QDRV_WLAN_AP_MAX_DWELLTIME_PASSIVE;
		ic->ic_opmode = IEEE80211_M_HOSTAP;
		QDRV_SET_SM_FLAG(qw->sm_stats, QDRV_WLAN_SM_STATE_AP);

		/* Force auto roaming for AP in case it was set to manual when in STA mode */
		ic->ic_roaming = IEEE80211_ROAMING_AUTO;
	}

#ifdef QTN_BG_SCAN
	ic->ic_qtn_bgscan.dwell_msecs_active = QDRV_WLAN_QTN_BGSCAN_DWELLTIME_ACTIVE;
	ic->ic_qtn_bgscan.dwell_msecs_passive = QDRV_WLAN_QTN_BGSCAN_DWELLTIME_PASSIVE;
	ic->ic_qtn_bgscan.duration_msecs_active = QDRV_WLAN_QTN_BGSCAN_DURATION_ACTIVE;
	ic->ic_qtn_bgscan.duration_msecs_passive_fast = QDRV_WLAN_QTN_BGSCAN_DURATION_PASSIVE_FAST;
	ic->ic_qtn_bgscan.duration_msecs_passive_normal = QDRV_WLAN_QTN_BGSCAN_DURATION_PASSIVE_NORMAL;
	ic->ic_qtn_bgscan.duration_msecs_passive_slow = QDRV_WLAN_QTN_BGSCAN_DURATION_PASSIVE_SLOW;
	ic->ic_qtn_bgscan.thrshld_fat_passive_fast = QDRV_WLAN_QTN_BGSCAN_THRESHLD_PASSIVE_FAST;
	ic->ic_qtn_bgscan.thrshld_fat_passive_normal = QDRV_WLAN_QTN_BGSCAN_THRESHLD_PASSIVE_NORMAL;
	ic->ic_qtn_bgscan.debug_flags = 0;
#endif /* QTN_BG_SCAN */

	rtnl_unlock();

	/* vlan configuration structure associated with the device */
	if (switch_alloc_vlan_dev(TOPAZ_TQE_WMAC_PORT, dev_devid, vdev->ifindex) == NULL) {
		DBGPRINTF_E("failed to bind vlan dev to VAP\n");
		ieee80211_vap_detach(&qv->iv);
		return -1;
	}

	/* Set some debug stuff */
	qv->iv.iv_debug |= IEEE80211_MSG_DEBUG |
				IEEE80211_MSG_INPUT |
				IEEE80211_MSG_ASSOC |
				IEEE80211_MSG_AUTH |
				IEEE80211_MSG_OUTPUT;

	/* Disable some ... */
	qv->iv.iv_debug &= ~IEEE80211_MSG_DEBUG;
	qv->iv.iv_debug  = 0;
	((struct net_device_ops *)(vdev->netdev_ops))->ndo_start_xmit = qdrv_tx_hardstart;
	((struct net_device_ops *)(vdev->netdev_ops))->ndo_open = vnet_init;
	((struct net_device_ops *)(vdev->netdev_ops))->ndo_stop = vnet_stop;

	TAILQ_INIT(&qv->ni_lncb_lst);

#ifdef CONFIG_QVSP
	if (qw->qvsp == NULL) {
		qw->qvsp = qvsp_init(&qdrv_qvsp_ioctl, qw, vdev, stamode,
			ic->ic_vsp_cb_cfg, ic->ic_vsp_cb_strm_ctrl, ic->ic_vsp_cb_strm_ext_throttler,
			sizeof(struct ieee80211_node), sizeof(struct ieee80211vap));
		if (qw->qvsp && qdrv_wlan_vsp_3rdpt_init(qw)) {
			printk("Could not initialize VSP 3rd party client control\n");
		}
	} else if (vap->iv_opmode == IEEE80211_M_WDS) {
		qvsp_inactive_flag_set(qw->qvsp, QVSP_INACTIVE_WDS);
	}
	if (repeater_mode && vap->iv_opmode == IEEE80211_M_HOSTAP)
		ic->ic_vsp_change_stamode(ic, 0);
#endif

	qv->iv.iv_vapnode_idx = IEEE80211_NODE_IDX_MAP(hifinfo->hi_vapnode_idx);
	qdrv_tx_sch_attach(qv);
	if (ic->ic_rf_chipid == CHIPID_DUAL && vap->iv_opmode != IEEE80211_M_WDS) {
		/* Disable one-bit dynamic auto-correlation on RFIC5 */
		ic->ic_setparam(vap->iv_bss, IEEE80211_PARAM_DYNAMIC_AC, 0, NULL, 0);
	}
	/* initial bss node will be created before the qdisc; reinitialize */
	if (vap->iv_bss) {
		qdrv_tx_sch_node_data_init(qdrv_tx_sch_vap_get_qdisc(vdev),
				qw->tx_sch_shared_data, &vap->iv_bss->ni_tx_sch, 1);
	}

	/*
	 * Finally, set vnet pointer. Needs to be done after all init is
	 * complete, or there will be synchronization problem with
	 * qdrv_tx_wake_queue or others.
	 */
	mac->vnet[vap_idx] = vdev;
	qdrv_vap_set_last(mac);

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");

	return 0;
}

/* Any resource allocated to VAP cleanup here */
void qdrv_vap_resource_cleanup(struct qdrv_vap *qv)
{
	if (qv->bc_skb != NULL) {
		dev_kfree_skb_any(qv->bc_skb);
		qv->bc_skb = NULL;
		}
}

static int qdrv_get_hostap_count(struct ieee80211com *ic, struct ieee80211vap *vap)
{
	int count = 0;

	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
		if (vap->iv_opmode == IEEE80211_M_HOSTAP)
			count++;
	}

	return count;
}

int qdrv_vap_exit(struct qdrv_mac *mac, struct net_device *vdev)
{
	struct qdrv_vap *qv = netdev_priv(vdev);
#ifdef CONFIG_QVSP
	struct qdrv_wlan *qw = (struct qdrv_wlan *)qv->parent;
	struct ieee80211com *ic = qv->iv.iv_ic;
	struct ieee80211vap *vap = &qv->iv;
	int repeater_mode = ic->ic_flags_ext & IEEE80211_FEXT_REPEATER;

	if (repeater_mode &&
			vap->iv_opmode == IEEE80211_M_HOSTAP &&
			qdrv_get_hostap_count(ic, vap) == 1)
		ic->ic_vsp_change_stamode(ic, 1);

	qvsp_exit(&qw->qvsp, vdev);

	if (qw->qvsp == NULL) {
		qdrv_wlan_vsp_3rdpt_exit(qw);
	}
#endif

	rtnl_lock();
	ieee80211_vap_detach(&qv->iv);
	rtnl_unlock();

#ifdef CONFIG_QVSP
	if (qw->qvsp && (qdrv_wlan_query_wds(ic) == 0) ) {
		qvsp_inactive_flag_clear(qw->qvsp, QVSP_INACTIVE_WDS);
	}
#endif

	return 0;
}

int qdrv_vap_exit_muc_done(struct qdrv_mac *mac, struct net_device *vdev)
{
	struct qdrv_vap *qv = netdev_priv(vdev);
	int vnet_found = 0;
	int i;

	for (i = 0; i < QDRV_MAX_VAPS; i++) {
		if (mac->vnet[i] == vdev) {
			mac->vnet[i] = NULL;
			qdrv_vap_set_last(mac);
			vnet_found = 1;
		}
	}

	if (!vnet_found) {
		DBGPRINTF_E("vap %s not found in mac\n", vdev->name);
		DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");
		return -ENODEV;
	}

	DBGPRINTF(DBG_LL_INFO, QDRV_LF_VAP,
			"Delete VAP qv 0x%p \"%s\" (%d)\n", qv, vdev->name, i);

	if (mac->vnet[0] == NULL && igmp_query_timer_not_initd == 0) {
		struct qdrv_wlan *qw = (struct qdrv_wlan *)qv->parent;
		qdrv_wlan_igmp_timer_stop(qw);
		igmp_query_timer_not_initd = 1;
	}

	if (mac->vnet[0] == NULL && wps_button_not_initd == 0) {
		qdrv_wps_button_exit();
		wps_button_not_initd = 1;
	}

	qdrv_vap_resource_cleanup(qv);

	qdrv_tx_done_flush_vap(qv);

	/* release switch vlan */
	switch_free_vlan_dev_by_idx(vdev->dev_id);

	/* Destroy it ... */
	rtnl_lock();
	ieee80211_vap_detach_late(&qv->iv);
	rtnl_unlock();

	return 0;
}

int qdrv_exit_all_vaps(struct qdrv_mac *mac)
{
	int i;

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "-->Enter\n");

	for (i = 0; i < QDRV_MAX_VAPS; i++) {
		if (mac->vnet[i]) {
			qdrv_vap_exit(mac, mac->vnet[i]);
		}
	}

	DBGPRINTF(DBG_LL_ALL, QDRV_LF_TRACE, "<--Exit\n");

	return(0);
}

