/*
 * Copyright (c) 2012-2012 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.
 *
 */

#include <linux/kernel.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <net/netlink.h>

#include "cfg80211.h"
#include "commands.h"
#include "core.h"
#include "util.h"
#include "bus.h"

/* Supported rates to be advertised to the cfg80211 */
static struct ieee80211_rate qtnf_rates_2g[] = {
	{.bitrate = 10, .hw_value = 2, },
	{.bitrate = 20, .hw_value = 4, },
	{.bitrate = 55, .hw_value = 11, },
	{.bitrate = 110, .hw_value = 22, },
	{.bitrate = 60, .hw_value = 12, },
	{.bitrate = 90, .hw_value = 18, },
	{.bitrate = 120, .hw_value = 24, },
	{.bitrate = 180, .hw_value = 36, },
	{.bitrate = 240, .hw_value = 48, },
	{.bitrate = 360, .hw_value = 72, },
	{.bitrate = 480, .hw_value = 96, },
	{.bitrate = 540, .hw_value = 108, },
};

/* Supported rates to be advertised to the cfg80211 */
static struct ieee80211_rate qtnf_rates_5g[] = {
	{.bitrate = 60, .hw_value = 12, },
	{.bitrate = 90, .hw_value = 18, },
	{.bitrate = 120, .hw_value = 24, },
	{.bitrate = 180, .hw_value = 36, },
	{.bitrate = 240, .hw_value = 48, },
	{.bitrate = 360, .hw_value = 72, },
	{.bitrate = 480, .hw_value = 96, },
	{.bitrate = 540, .hw_value = 108, },
};

/* Supported crypto cipher suits to be advertised to cfg80211 */
static const u32 qtnf_cipher_suites[] = {
	WLAN_CIPHER_SUITE_TKIP,
	WLAN_CIPHER_SUITE_CCMP,
	WLAN_CIPHER_SUITE_AES_CMAC,
};

/* Supported mgmt frame types to be advertised to cfg80211 */
static const struct ieee80211_txrx_stypes
qtnf_mgmt_stypes[NUM_NL80211_IFTYPES] = {
	[NL80211_IFTYPE_STATION] = {
		.tx = BIT(IEEE80211_STYPE_ACTION >> 4),
		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
	},
	[NL80211_IFTYPE_AP] = {
		.tx = BIT(IEEE80211_STYPE_ACTION >> 4),
		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
	},
};

static int
qtnf_change_virtual_intf(struct wiphy *wiphy,
			 struct net_device *dev,
			 enum nl80211_iftype type,
			 struct vif_params *params)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	u8 *mac_addr;
	int ret;

	if (params)
		mac_addr = params->macaddr;
	else
		mac_addr = NULL;

	qtnf_scan_done(vif->mac, true);

	ret = qtnf_cmd_send_change_intf_type(vif, type, mac_addr);
	if (ret) {
		pr_err("VIF%u.%u: failed to change VIF type: %d\n",
		       vif->mac->macid, vif->vifid, ret);
		return ret;
	}

	vif->wdev.iftype = type;
	return 0;
}

int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
{
	struct net_device *netdev =  wdev->netdev;
	struct qtnf_vif *vif;

	if (WARN_ON(!netdev))
		return -EFAULT;

	vif = qtnf_netdev_get_priv(wdev->netdev);

	qtnf_scan_done(vif->mac, true);

	if (qtnf_cmd_send_del_intf(vif))
		pr_err("VIF%u.%u: failed to delete VIF\n", vif->mac->macid,
		       vif->vifid);

	/* Stop data */
	netif_tx_stop_all_queues(netdev);
	if (netif_carrier_ok(netdev))
		netif_carrier_off(netdev);

	if (netdev->reg_state == NETREG_REGISTERED)
		unregister_netdevice(netdev);

	vif->netdev->ieee80211_ptr = NULL;
	vif->netdev = NULL;
	vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
	eth_zero_addr(vif->mac_addr);

	return 0;
}

static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
						  const char *name,
						  unsigned char name_assign_t,
						  enum nl80211_iftype type,
						  struct vif_params *params)
{
	struct qtnf_wmac *mac;
	struct qtnf_vif *vif;
	u8 *mac_addr = NULL;

	mac = wiphy_priv(wiphy);

	if (!mac)
		return ERR_PTR(-EFAULT);

	switch (type) {
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_AP:
		vif = qtnf_mac_get_free_vif(mac);
		if (!vif) {
			pr_err("MAC%u: no free VIF available\n", mac->macid);
			return ERR_PTR(-EFAULT);
		}

		eth_zero_addr(vif->mac_addr);
		vif->bss_priority = QTNF_DEF_BSS_PRIORITY;
		vif->wdev.wiphy = wiphy;
		vif->wdev.iftype = type;
		vif->sta_state = QTNF_STA_DISCONNECTED;
		break;
	default:
		pr_err("MAC%u: unsupported IF type %d\n", mac->macid, type);
		return ERR_PTR(-ENOTSUPP);
	}

	if (params)
		mac_addr = params->macaddr;

	if (qtnf_cmd_send_add_intf(vif, type, mac_addr)) {
		pr_err("VIF%u.%u: failed to add VIF\n", mac->macid, vif->vifid);
		goto err_cmd;
	}

	if (!is_valid_ether_addr(vif->mac_addr)) {
		pr_err("VIF%u.%u: FW reported bad MAC: %pM\n",
		       mac->macid, vif->vifid, vif->mac_addr);
		goto err_mac;
	}

	if (qtnf_core_net_attach(mac, vif, name, name_assign_t, type)) {
		pr_err("VIF%u.%u: failed to attach netdev\n", mac->macid,
		       vif->vifid);
		goto err_net;
	}

	vif->wdev.netdev = vif->netdev;
	return &vif->wdev;

err_net:
	vif->netdev = NULL;
err_mac:
	qtnf_cmd_send_del_intf(vif);
err_cmd:
	vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;

	return ERR_PTR(-EFAULT);
}

static int qtnf_mgmt_set_appie(struct qtnf_vif *vif,
			       const struct cfg80211_beacon_data *info)
{
	int ret = 0;

	if (!info->beacon_ies || !info->beacon_ies_len) {
		ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON,
						   NULL, 0);
	} else {
		ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON,
						   info->beacon_ies,
						   info->beacon_ies_len);
	}

	if (ret)
		goto out;

	if (!info->proberesp_ies || !info->proberesp_ies_len) {
		ret = qtnf_cmd_send_mgmt_set_appie(vif,
						   QLINK_MGMT_FRAME_PROBE_RESP,
						   NULL, 0);
	} else {
		ret = qtnf_cmd_send_mgmt_set_appie(vif,
						   QLINK_MGMT_FRAME_PROBE_RESP,
						   info->proberesp_ies,
						   info->proberesp_ies_len);
	}

	if (ret)
		goto out;

	if (!info->assocresp_ies || !info->assocresp_ies_len) {
		ret = qtnf_cmd_send_mgmt_set_appie(vif,
						   QLINK_MGMT_FRAME_ASSOC_RESP,
						   NULL, 0);
	} else {
		ret = qtnf_cmd_send_mgmt_set_appie(vif,
						   QLINK_MGMT_FRAME_ASSOC_RESP,
						   info->assocresp_ies,
						   info->assocresp_ies_len);
	}

out:
	return ret;
}

static int qtnf_change_beacon(struct wiphy *wiphy, struct net_device *dev,
			      struct cfg80211_beacon_data *info)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);

	if (!(vif->bss_status & QTNF_STATE_AP_START)) {
		pr_err("VIF%u.%u: not started\n", vif->mac->macid, vif->vifid);
		return -EFAULT;
	}

	return qtnf_mgmt_set_appie(vif, info);
}

static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev,
			 struct cfg80211_ap_settings *settings)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct qtnf_bss_config *bss_cfg;
	int ret;

	if (!cfg80211_chandef_identical(&mac->chandef, &settings->chandef)) {
		memcpy(&mac->chandef, &settings->chandef, sizeof(mac->chandef));
		if (vif->vifid != 0)
			pr_warn("%s: unexpected chan %u (%u MHz)\n", dev->name,
				settings->chandef.chan->hw_value,
				settings->chandef.chan->center_freq);
	}

	bss_cfg = &vif->bss_cfg;
	memset(bss_cfg, 0, sizeof(*bss_cfg));

	bss_cfg->bcn_period = settings->beacon_interval;
	bss_cfg->dtim = settings->dtim_period;
	bss_cfg->auth_type = settings->auth_type;
	bss_cfg->privacy = settings->privacy;

	bss_cfg->ssid_len = settings->ssid_len;
	memcpy(&bss_cfg->ssid, settings->ssid, bss_cfg->ssid_len);

	memcpy(&bss_cfg->crypto, &settings->crypto,
	       sizeof(struct cfg80211_crypto_settings));

	ret = qtnf_cmd_send_config_ap(vif);
	if (ret) {
		pr_err("VIF%u.%u: failed to push config to FW\n",
		       vif->mac->macid, vif->vifid);
		goto out;
	}

	if (!(vif->bss_status & QTNF_STATE_AP_CONFIG)) {
		pr_err("VIF%u.%u: AP config failed in FW\n", vif->mac->macid,
		       vif->vifid);
		ret = -EFAULT;
		goto out;
	}

	ret = qtnf_mgmt_set_appie(vif, &settings->beacon);
	if (ret) {
		pr_err("VIF%u.%u: failed to add IEs to beacon\n",
		       vif->mac->macid, vif->vifid);
		goto out;
	}

	ret = qtnf_cmd_send_start_ap(vif);
	if (ret) {
		pr_err("VIF%u.%u: failed to start AP\n", vif->mac->macid,
		       vif->vifid);
		goto out;
	}

	if (!(vif->bss_status & QTNF_STATE_AP_START)) {
		pr_err("VIF%u.%u: FW failed to start AP operation\n",
		       vif->mac->macid, vif->vifid);
		ret = -EFAULT;
	}

out:
	return ret;
}

static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	qtnf_scan_done(vif->mac, true);

	ret = qtnf_cmd_send_stop_ap(vif);
	if (ret) {
		pr_err("VIF%u.%u: failed to stop AP operation in FW\n",
		       vif->mac->macid, vif->vifid);
		vif->bss_status &= ~QTNF_STATE_AP_START;
		vif->bss_status &= ~QTNF_STATE_AP_CONFIG;

		netif_carrier_off(vif->netdev);
	}

	return ret;
}

static int qtnf_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct qtnf_vif *vif;
	int ret;

	vif = qtnf_mac_get_base_vif(mac);
	if (!vif) {
		pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
		return -EFAULT;
	}

	if (changed & (WIPHY_PARAM_RETRY_LONG | WIPHY_PARAM_RETRY_SHORT)) {
		pr_err("MAC%u: can't modify retry params\n", mac->macid);
		return -EOPNOTSUPP;
	}

	ret = qtnf_cmd_send_update_phy_params(mac, changed);
	if (ret)
		pr_err("MAC%u: failed to update PHY params\n", mac->macid);

	return ret;
}

static void
qtnf_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
			 u16 frame_type, bool reg)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);
	u16 mgmt_type;
	u16 new_mask;
	u16 qlink_frame_type = 0;

	mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;

	if (reg)
		new_mask = vif->mgmt_frames_bitmask | BIT(mgmt_type);
	else
		new_mask = vif->mgmt_frames_bitmask & ~BIT(mgmt_type);

	if (new_mask == vif->mgmt_frames_bitmask)
		return;

	switch (frame_type & IEEE80211_FCTL_STYPE) {
	case IEEE80211_STYPE_PROBE_REQ:
		qlink_frame_type = QLINK_MGMT_FRAME_PROBE_REQ;
		break;
	case IEEE80211_STYPE_ACTION:
		qlink_frame_type = QLINK_MGMT_FRAME_ACTION;
		break;
	default:
		pr_warn("VIF%u.%u: unsupported frame type: %X\n",
			vif->mac->macid, vif->vifid,
			(frame_type & IEEE80211_FCTL_STYPE) >> 4);
		return;
	}

	if (qtnf_cmd_send_register_mgmt(vif, qlink_frame_type, reg)) {
		pr_warn("VIF%u.%u: failed to %sregister mgmt frame type 0x%x\n",
			vif->mac->macid, vif->vifid, reg ? "" : "un",
			frame_type);
		return;
	}

	vif->mgmt_frames_bitmask = new_mask;
	pr_debug("VIF%u.%u: %sregistered mgmt frame type 0x%x\n",
		 vif->mac->macid, vif->vifid, reg ? "" : "un", frame_type);
}

static int
qtnf_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
	     struct cfg80211_mgmt_tx_params *params, u64 *cookie)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);
	const struct ieee80211_mgmt *mgmt_frame = (void *)params->buf;
	u32 short_cookie = prandom_u32();
	u16 flags = 0;

	*cookie = short_cookie;

	if (params->offchan)
		flags |= QLINK_MGMT_FRAME_TX_FLAG_OFFCHAN;

	if (params->no_cck)
		flags |= QLINK_MGMT_FRAME_TX_FLAG_NO_CCK;

	if (params->dont_wait_for_ack)
		flags |= QLINK_MGMT_FRAME_TX_FLAG_ACK_NOWAIT;

	pr_debug("%s freq:%u; FC:%.4X; DA:%pM; len:%zu; C:%.8X; FL:%.4X\n",
		 wdev->netdev->name, params->chan->center_freq,
		 le16_to_cpu(mgmt_frame->frame_control), mgmt_frame->da,
		 params->len, short_cookie, flags);

	return qtnf_cmd_send_mgmt_frame(vif, short_cookie, flags,
					params->chan->center_freq,
					params->buf, params->len);
}

static int
qtnf_get_station(struct wiphy *wiphy, struct net_device *dev,
		 const u8 *mac, struct station_info *sinfo)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);

	return qtnf_cmd_get_sta_info(vif, mac, sinfo);
}

static int
qtnf_dump_station(struct wiphy *wiphy, struct net_device *dev,
		  int idx, u8 *mac, struct station_info *sinfo)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	const struct qtnf_sta_node *sta_node;
	int ret;

	sta_node = qtnf_sta_list_lookup_index(&vif->sta_list, idx);

	if (unlikely(!sta_node))
		return -ENOENT;

	ether_addr_copy(mac, sta_node->mac_addr);

	ret = qtnf_cmd_get_sta_info(vif, sta_node->mac_addr, sinfo);

	if (unlikely(ret == -ENOENT)) {
		qtnf_sta_list_del(&vif->sta_list, mac);
		cfg80211_del_sta(vif->netdev, mac, GFP_KERNEL);
		sinfo->filled = 0;
	}

	return ret;
}

static int qtnf_add_key(struct wiphy *wiphy, struct net_device *dev,
			u8 key_index, bool pairwise, const u8 *mac_addr,
			struct key_params *params)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	ret = qtnf_cmd_send_add_key(vif, key_index, pairwise, mac_addr, params);
	if (ret)
		pr_err("VIF%u.%u: failed to add key: cipher=%x idx=%u pw=%u\n",
		       vif->mac->macid, vif->vifid, params->cipher, key_index,
		       pairwise);

	return ret;
}

static int qtnf_del_key(struct wiphy *wiphy, struct net_device *dev,
			u8 key_index, bool pairwise, const u8 *mac_addr)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	ret = qtnf_cmd_send_del_key(vif, key_index, pairwise, mac_addr);
	if (ret)
		pr_err("VIF%u.%u: failed to delete key: idx=%u pw=%u\n",
		       vif->mac->macid, vif->vifid, key_index, pairwise);

	return ret;
}

static int qtnf_set_default_key(struct wiphy *wiphy, struct net_device *dev,
				u8 key_index, bool unicast, bool multicast)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	ret = qtnf_cmd_send_set_default_key(vif, key_index, unicast, multicast);
	if (ret)
		pr_err("VIF%u.%u: failed to set dflt key: idx=%u uc=%u mc=%u\n",
		       vif->mac->macid, vif->vifid, key_index, unicast,
		       multicast);

	return ret;
}

static int
qtnf_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev,
			  u8 key_index)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	ret = qtnf_cmd_send_set_default_mgmt_key(vif, key_index);
	if (ret)
		pr_err("VIF%u.%u: failed to set default MGMT key: idx=%u\n",
		       vif->mac->macid, vif->vifid, key_index);

	return ret;
}

static int
qtnf_change_station(struct wiphy *wiphy, struct net_device *dev,
		    const u8 *mac, struct station_parameters *params)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	ret = qtnf_cmd_send_change_sta(vif, mac, params);
	if (ret)
		pr_err("VIF%u.%u: failed to change STA %pM\n",
		       vif->mac->macid, vif->vifid, mac);

	return ret;
}

static int
qtnf_del_station(struct wiphy *wiphy, struct net_device *dev,
		 struct station_del_parameters *params)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	if (params->mac &&
	    (vif->wdev.iftype == NL80211_IFTYPE_AP) &&
	    !is_broadcast_ether_addr(params->mac) &&
	    !qtnf_sta_list_lookup(&vif->sta_list, params->mac))
		return 0;

	ret = qtnf_cmd_send_del_sta(vif, params);
	if (ret)
		pr_err("VIF%u.%u: failed to delete STA %pM\n",
		       vif->mac->macid, vif->vifid, params->mac);
	return ret;
}

static void qtnf_scan_timeout(unsigned long data)
{
	struct qtnf_wmac *mac = (struct qtnf_wmac *)data;

	pr_warn("mac%d scan timed out\n", mac->macid);
	qtnf_scan_done(mac, true);
}

static int
qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
{
	struct qtnf_wmac *mac = wiphy_priv(wiphy);

	mac->scan_req = request;

	if (qtnf_cmd_send_scan(mac)) {
		pr_err("MAC%u: failed to start scan\n", mac->macid);
		mac->scan_req = NULL;
		return -EFAULT;
	}

	mac->scan_timeout.data = (unsigned long)mac;
	mac->scan_timeout.function = qtnf_scan_timeout;
	mod_timer(&mac->scan_timeout,
		  jiffies + QTNF_SCAN_TIMEOUT_SEC * HZ);

	return 0;
}

static int
qtnf_connect(struct wiphy *wiphy, struct net_device *dev,
	     struct cfg80211_connect_params *sme)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct cfg80211_chan_def chandef;
	struct qtnf_bss_config *bss_cfg;
	int ret;

	if (vif->wdev.iftype != NL80211_IFTYPE_STATION)
		return -EOPNOTSUPP;

	if (vif->sta_state != QTNF_STA_DISCONNECTED)
		return -EBUSY;

	bss_cfg = &vif->bss_cfg;
	memset(bss_cfg, 0, sizeof(*bss_cfg));

	if (sme->channel) {
		/* FIXME: need to set proper nl80211_channel_type value */
		cfg80211_chandef_create(&chandef, sme->channel,
					NL80211_CHAN_HT20);
		/* fall-back to minimal safe chandef description */
		if (!cfg80211_chandef_valid(&chandef))
			cfg80211_chandef_create(&chandef, sme->channel,
						NL80211_CHAN_HT20);

		memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));
	}

	bss_cfg->ssid_len = sme->ssid_len;
	memcpy(&bss_cfg->ssid, sme->ssid, bss_cfg->ssid_len);
	bss_cfg->auth_type = sme->auth_type;
	bss_cfg->privacy = sme->privacy;
	bss_cfg->mfp = sme->mfp;

	if ((sme->bg_scan_period > 0) &&
	    (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD))
		bss_cfg->bg_scan_period = sme->bg_scan_period;
	else if (sme->bg_scan_period == -1)
		bss_cfg->bg_scan_period = QTNF_DEFAULT_BG_SCAN_PERIOD;
	else
		bss_cfg->bg_scan_period = 0; /* disabled */

	bss_cfg->connect_flags = 0;

	if (sme->flags & ASSOC_REQ_DISABLE_HT)
		bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_HT;
	if (sme->flags & ASSOC_REQ_DISABLE_VHT)
		bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT;
	if (sme->flags & ASSOC_REQ_USE_RRM)
		bss_cfg->connect_flags |= QLINK_STA_CONNECT_USE_RRM;

	memcpy(&bss_cfg->crypto, &sme->crypto, sizeof(bss_cfg->crypto));
	if (sme->bssid)
		ether_addr_copy(bss_cfg->bssid, sme->bssid);
	else
		eth_zero_addr(bss_cfg->bssid);

	ret = qtnf_cmd_send_connect(vif, sme);
	if (ret) {
		pr_err("VIF%u.%u: failed to connect\n", vif->mac->macid,
		       vif->vifid);
		return ret;
	}

	vif->sta_state = QTNF_STA_CONNECTING;
	return 0;
}

static int
qtnf_disconnect(struct wiphy *wiphy, struct net_device *dev,
		u16 reason_code)
{
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct qtnf_vif *vif;
	int ret;

	vif = qtnf_mac_get_base_vif(mac);
	if (!vif) {
		pr_err("MAC%u: primary VIF is not configured\n", mac->macid);
		return -EFAULT;
	}

	if (vif->wdev.iftype != NL80211_IFTYPE_STATION)
		return -EOPNOTSUPP;

	if (vif->sta_state == QTNF_STA_DISCONNECTED)
		return 0;

	ret = qtnf_cmd_send_disconnect(vif, reason_code);
	if (ret) {
		pr_err("VIF%u.%u: failed to disconnect\n", mac->macid,
		       vif->vifid);
		return ret;
	}

	vif->sta_state = QTNF_STA_DISCONNECTED;
	return 0;
}

static int
qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev,
		 int idx, struct survey_info *survey)
{
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct ieee80211_supported_band *sband;
	struct cfg80211_chan_def *chandef;
	struct ieee80211_channel *chan;
	struct qtnf_chan_stats stats;
	struct qtnf_vif *vif;
	int ret;

	vif = qtnf_netdev_get_priv(dev);
	chandef = &mac->chandef;

	sband = wiphy->bands[NL80211_BAND_2GHZ];
	if (sband && idx >= sband->n_channels) {
		idx -= sband->n_channels;
		sband = NULL;
	}

	if (!sband)
		sband = wiphy->bands[NL80211_BAND_5GHZ];

	if (!sband || idx >= sband->n_channels)
		return -ENOENT;

	chan = &sband->channels[idx];
	memset(&stats, 0, sizeof(stats));

	survey->channel = chan;
	survey->filled = 0x0;

	if (chandef->chan) {
		if (chan->hw_value == chandef->chan->hw_value)
			survey->filled = SURVEY_INFO_IN_USE;
	}

	ret = qtnf_cmd_get_chan_stats(mac, chan->hw_value, &stats);
	switch (ret) {
	case 0:
		if (unlikely(stats.chan_num != chan->hw_value)) {
			pr_err("received stats for channel %d instead of %d\n",
			       stats.chan_num, chan->hw_value);
			ret = -EINVAL;
			break;
		}

		survey->filled |= SURVEY_INFO_TIME |
				 SURVEY_INFO_TIME_SCAN |
				 SURVEY_INFO_TIME_BUSY |
				 SURVEY_INFO_TIME_RX |
				 SURVEY_INFO_TIME_TX |
				 SURVEY_INFO_NOISE_DBM;

		survey->time_scan = stats.cca_try;
		survey->time = stats.cca_try;
		survey->time_tx = stats.cca_tx;
		survey->time_rx = stats.cca_rx;
		survey->time_busy = stats.cca_busy;
		survey->noise = stats.chan_noise;
		break;
	case -ENOENT:
		pr_debug("no stats for channel %u\n", chan->hw_value);
		ret = 0;
		break;
	default:
		pr_debug("failed to get chan(%d) stats from card\n",
			 chan->hw_value);
		ret = -EINVAL;
		break;
	}

	return ret;
}

static int
qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
		 struct cfg80211_chan_def *chandef)
{
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct net_device *ndev = wdev->netdev;
	struct qtnf_vif *vif;

	if (!ndev)
		return -ENODEV;

	vif = qtnf_netdev_get_priv(wdev->netdev);

	switch (vif->wdev.iftype) {
	case NL80211_IFTYPE_STATION:
		if (vif->sta_state == QTNF_STA_DISCONNECTED) {
			pr_warn("%s: STA disconnected\n", ndev->name);
			return -ENODATA;
		}
		break;
	case NL80211_IFTYPE_AP:
		if (!(vif->bss_status & QTNF_STATE_AP_START)) {
			pr_warn("%s: AP not started\n", ndev->name);
			return -ENODATA;
		}
		break;
	default:
		pr_err("unsupported vif type (%d)\n", vif->wdev.iftype);
		return -ENODATA;
	}

	if (!cfg80211_chandef_valid(&mac->chandef)) {
		pr_err("invalid channel settings on %s\n", ndev->name);
		return -ENODATA;
	}

	memcpy(chandef, &mac->chandef, sizeof(*chandef));
	return 0;
}

static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
			       struct cfg80211_csa_settings *params)
{
	struct qtnf_wmac *mac = wiphy_priv(wiphy);
	struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
	int ret;

	pr_debug("%s: chan(%u) count(%u) radar(%u) block_tx(%u)\n", dev->name,
		 params->chandef.chan->hw_value, params->count,
		 params->radar_required, params->block_tx);

	switch (vif->wdev.iftype) {
	case NL80211_IFTYPE_AP:
		if (!(vif->bss_status & QTNF_STATE_AP_START)) {
			pr_warn("AP not started on %s\n", dev->name);
			return -ENOTCONN;
		}
		break;
	default:
		pr_err("unsupported vif type (%d) on %s\n",
		       vif->wdev.iftype, dev->name);
		return -EOPNOTSUPP;
	}

	if (vif->vifid != 0) {
		if (!(mac->status & QTNF_MAC_CSA_ACTIVE))
			return -EOPNOTSUPP;

		if (!cfg80211_chandef_identical(&params->chandef,
						&mac->csa_chandef))
			return -EINVAL;

		return 0;
	}

	if (!cfg80211_chandef_valid(&params->chandef)) {
		pr_err("%s: invalid channel\n", dev->name);
		return -EINVAL;
	}

	if (cfg80211_chandef_identical(&params->chandef, &mac->chandef)) {
		pr_err("%s: switch request to the same channel\n", dev->name);
		return -EALREADY;
	}

	ret = qtnf_cmd_send_chan_switch(mac, params);
	if (ret)
		pr_warn("%s: failed to switch to channel (%u)\n",
			dev->name, params->chandef.chan->hw_value);

	return ret;
}

static struct cfg80211_ops qtn_cfg80211_ops = {
	.add_virtual_intf	= qtnf_add_virtual_intf,
	.change_virtual_intf	= qtnf_change_virtual_intf,
	.del_virtual_intf	= qtnf_del_virtual_intf,
	.start_ap		= qtnf_start_ap,
	.change_beacon		= qtnf_change_beacon,
	.stop_ap		= qtnf_stop_ap,
	.set_wiphy_params	= qtnf_set_wiphy_params,
	.mgmt_frame_register	= qtnf_mgmt_frame_register,
	.mgmt_tx		= qtnf_mgmt_tx,
	.change_station		= qtnf_change_station,
	.del_station		= qtnf_del_station,
	.get_station		= qtnf_get_station,
	.dump_station		= qtnf_dump_station,
	.add_key		= qtnf_add_key,
	.del_key		= qtnf_del_key,
	.set_default_key	= qtnf_set_default_key,
	.set_default_mgmt_key	= qtnf_set_default_mgmt_key,
	.scan			= qtnf_scan,
	.connect		= qtnf_connect,
	.disconnect		= qtnf_disconnect,
	.dump_survey		= qtnf_dump_survey,
	.get_channel		= qtnf_get_channel,
	.channel_switch		= qtnf_channel_switch
};

static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in,
				       struct regulatory_request *req)
{
	struct qtnf_wmac *mac = wiphy_priv(wiphy_in);
	struct qtnf_bus *bus = mac->bus;
	struct wiphy *wiphy;
	unsigned int mac_idx;
	enum nl80211_band band;
	int ret;

	pr_debug("MAC%u: initiator=%d alpha=%c%c\n", mac->macid, req->initiator,
		 req->alpha2[0], req->alpha2[1]);

	ret = qtnf_cmd_reg_notify(bus, req);
	if (ret) {
		if (ret != -EOPNOTSUPP && ret != -EALREADY)
			pr_err("failed to update reg domain to %c%c\n",
			       req->alpha2[0], req->alpha2[1]);
		return;
	}

	for (mac_idx = 0; mac_idx < QTNF_MAX_MAC; ++mac_idx) {
		if (!(bus->hw_info.mac_bitmap & (1 << mac_idx)))
			continue;

		mac = bus->mac[mac_idx];
		wiphy = priv_to_wiphy(mac);

		for (band = 0; band < NUM_NL80211_BANDS; ++band) {
			if (!wiphy->bands[band])
				continue;

			ret = qtnf_cmd_get_mac_chan_info(mac,
							 wiphy->bands[band]);
			if (ret)
				pr_err("failed to get chan info for mac %u band %u\n",
				       mac_idx, band);
		}
	}
}

void qtnf_band_setup_htvht_caps(struct qtnf_mac_info *macinfo,
				struct ieee80211_supported_band *band)
{
	struct ieee80211_sta_ht_cap *ht_cap;
	struct ieee80211_sta_vht_cap *vht_cap;

	ht_cap = &band->ht_cap;
	ht_cap->ht_supported = true;
	memcpy(&ht_cap->cap, &macinfo->ht_cap.cap_info,
	       sizeof(u16));
	ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
	ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
	memcpy(&ht_cap->mcs, &macinfo->ht_cap.mcs,
	       sizeof(ht_cap->mcs));

	if (macinfo->phymode_cap & QLINK_PHYMODE_AC) {
		vht_cap = &band->vht_cap;
		vht_cap->vht_supported = true;
		memcpy(&vht_cap->cap,
		       &macinfo->vht_cap.vht_cap_info, sizeof(u32));
		/* Update MCS support for VHT */
		memcpy(&vht_cap->vht_mcs,
		       &macinfo->vht_cap.supp_mcs,
		       sizeof(struct ieee80211_vht_mcs_info));
	}
}

struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus)
{
	struct wiphy *wiphy;

	wiphy = wiphy_new(&qtn_cfg80211_ops, sizeof(struct qtnf_wmac));
	if (!wiphy)
		return NULL;

	set_wiphy_dev(wiphy, bus->dev);

	return wiphy;
}

static int qtnf_wiphy_setup_if_comb(struct wiphy *wiphy,
				    struct ieee80211_iface_combination *if_comb,
				    const struct qtnf_mac_info *mac_info)
{
	size_t max_interfaces = 0;
	u16 interface_modes = 0;
	size_t i;

	if (unlikely(!mac_info->limits || !mac_info->n_limits))
		return -ENOENT;

	if_comb->limits = mac_info->limits;
	if_comb->n_limits = mac_info->n_limits;

	for (i = 0; i < mac_info->n_limits; i++) {
		max_interfaces += mac_info->limits[i].max;
		interface_modes |= mac_info->limits[i].types;
	}

	if_comb->num_different_channels = 1;
	if_comb->beacon_int_infra_match = true;
	if_comb->max_interfaces = max_interfaces;
	if_comb->radar_detect_widths = mac_info->radar_detect_widths;
	wiphy->interface_modes = interface_modes;

	return 0;
}

int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
{
	struct wiphy *wiphy = priv_to_wiphy(mac);
	struct ieee80211_iface_combination *iface_comb = NULL;
	int ret;

	if (!wiphy) {
		pr_err("invalid wiphy pointer\n");
		return -EFAULT;
	}

	iface_comb = kzalloc(sizeof(*iface_comb), GFP_KERNEL);
	if (!iface_comb)
		return -ENOMEM;

	ret = qtnf_wiphy_setup_if_comb(wiphy, iface_comb, &mac->macinfo);
	if (ret)
		goto out;

	pr_info("MAC%u: phymode=%#x radar=%#x\n", mac->macid,
		mac->macinfo.phymode_cap, mac->macinfo.radar_detect_widths);

	wiphy->frag_threshold = mac->macinfo.frag_thr;
	wiphy->rts_threshold = mac->macinfo.rts_thr;
	wiphy->retry_short = mac->macinfo.sretry_limit;
	wiphy->retry_long = mac->macinfo.lretry_limit;
	wiphy->coverage_class = mac->macinfo.coverage_class;

	wiphy->max_scan_ssids = QTNF_MAX_SSID_LIST_LENGTH;
	wiphy->max_scan_ie_len = QTNF_MAX_VSIE_LEN;
	wiphy->mgmt_stypes = qtnf_mgmt_stypes;
	wiphy->max_remain_on_channel_duration = 5000;

	wiphy->iface_combinations = iface_comb;
	wiphy->n_iface_combinations = 1;
	wiphy->max_num_csa_counters = 2;

	/* Initialize cipher suits */
	wiphy->cipher_suites = qtnf_cipher_suites;
	wiphy->n_cipher_suites = ARRAY_SIZE(qtnf_cipher_suites);
	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
	wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
			WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
			WIPHY_FLAG_AP_UAPSD |
			WIPHY_FLAG_HAS_CHANNEL_SWITCH;

	wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
				    NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2;

	wiphy->available_antennas_tx = mac->macinfo.num_tx_chain;
	wiphy->available_antennas_rx = mac->macinfo.num_rx_chain;

	wiphy->max_ap_assoc_sta = mac->macinfo.max_ap_assoc_sta;

	ether_addr_copy(wiphy->perm_addr, mac->macaddr);

	if (hw_info->hw_capab & QLINK_HW_SUPPORTS_REG_UPDATE) {
		wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
			REGULATORY_CUSTOM_REG;
		wiphy->reg_notifier = qtnf_cfg80211_reg_notifier;
		wiphy_apply_custom_regulatory(wiphy, hw_info->rd);
	} else {
		wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
	}

	ret = wiphy_register(wiphy);
	if (ret < 0)
		goto out;

	if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
		ret = regulatory_set_wiphy_regd(wiphy, hw_info->rd);
	else if (isalpha(hw_info->rd->alpha2[0]) &&
		 isalpha(hw_info->rd->alpha2[1]))
		ret = regulatory_hint(wiphy, hw_info->rd->alpha2);

out:
	if (ret) {
		kfree(iface_comb);
		return ret;
	}

	return 0;
}

void qtnf_netdev_updown(struct net_device *ndev, bool up)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);

	if (qtnf_cmd_send_updown_intf(vif, up))
		pr_err("failed to send up/down command to FW\n");
}

void qtnf_virtual_intf_cleanup(struct net_device *ndev)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
	struct qtnf_wmac *mac = wiphy_priv(vif->wdev.wiphy);

	if (vif->wdev.iftype == NL80211_IFTYPE_STATION) {
		switch (vif->sta_state) {
		case QTNF_STA_DISCONNECTED:
			break;
		case QTNF_STA_CONNECTING:
			cfg80211_connect_result(vif->netdev,
						vif->bss_cfg.bssid, NULL, 0,
						NULL, 0,
						WLAN_STATUS_UNSPECIFIED_FAILURE,
						GFP_KERNEL);
			qtnf_disconnect(vif->wdev.wiphy, ndev,
					WLAN_REASON_DEAUTH_LEAVING);
			break;
		case QTNF_STA_CONNECTED:
			cfg80211_disconnected(vif->netdev,
					      WLAN_REASON_DEAUTH_LEAVING,
					      NULL, 0, 1, GFP_KERNEL);
			qtnf_disconnect(vif->wdev.wiphy, ndev,
					WLAN_REASON_DEAUTH_LEAVING);
			break;
		}

		vif->sta_state = QTNF_STA_DISCONNECTED;
	}

	qtnf_scan_done(mac, true);
}

void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif)
{
	if (vif->wdev.iftype == NL80211_IFTYPE_STATION) {
		switch (vif->sta_state) {
		case QTNF_STA_CONNECTING:
			cfg80211_connect_result(vif->netdev,
						vif->bss_cfg.bssid, NULL, 0,
						NULL, 0,
						WLAN_STATUS_UNSPECIFIED_FAILURE,
						GFP_KERNEL);
			break;
		case QTNF_STA_CONNECTED:
			cfg80211_disconnected(vif->netdev,
					      WLAN_REASON_DEAUTH_LEAVING,
					      NULL, 0, 1, GFP_KERNEL);
			break;
		case QTNF_STA_DISCONNECTED:
			break;
		}
	}

	cfg80211_shutdown_all_interfaces(vif->wdev.wiphy);
	vif->sta_state = QTNF_STA_DISCONNECTED;
}

void qtnf_band_init_rates(struct ieee80211_supported_band *band)
{
	switch (band->band) {
	case NL80211_BAND_2GHZ:
		band->bitrates = qtnf_rates_2g;
		band->n_bitrates = ARRAY_SIZE(qtnf_rates_2g);
		break;
	case NL80211_BAND_5GHZ:
		band->bitrates = qtnf_rates_5g;
		band->n_bitrates = ARRAY_SIZE(qtnf_rates_5g);
		break;
	default:
		band->bitrates = NULL;
		band->n_bitrates = 0;
		break;
	}
}
