// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/if_ether.h>
#include <linux/nospec.h>

#include "core.h"
#include "bus.h"
#include "trans.h"
#include "commands.h"
#include "cfg80211.h"
#include "event.h"
#include "util.h"
#include "switchdev.h"

#define QTNF_PRIMARY_VIF_IDX	0

static bool slave_radar = true;
module_param(slave_radar, bool, 0644);
MODULE_PARM_DESC(slave_radar, "set 0 to disable radar detection in slave mode");

static bool dfs_offload;
module_param(dfs_offload, bool, 0644);
MODULE_PARM_DESC(dfs_offload, "set 1 to enable DFS offload to firmware");

static struct dentry *qtnf_debugfs_dir;

bool qtnf_slave_radar_get(void)
{
	return slave_radar;
}

bool qtnf_dfs_offload_get(void)
{
	return dfs_offload;
}

struct qtnf_wmac *qtnf_core_get_mac(const struct qtnf_bus *bus, u8 macid)
{
	struct qtnf_wmac *mac = NULL;

	if (macid >= QTNF_MAX_MAC) {
		pr_err("invalid MAC index %u\n", macid);
		return NULL;
	}

	macid = array_index_nospec(macid, QTNF_MAX_MAC);
	mac = bus->mac[macid];

	if (unlikely(!mac)) {
		pr_err("MAC%u: not initialized\n", macid);
		return NULL;
	}

	return mac;
}

/* Netdev handler for open.
 */
static int qtnf_netdev_open(struct net_device *ndev)
{
	netif_carrier_off(ndev);
	qtnf_netdev_updown(ndev, 1);
	return 0;
}

/* Netdev handler for close.
 */
static int qtnf_netdev_close(struct net_device *ndev)
{
	netif_carrier_off(ndev);
	qtnf_virtual_intf_cleanup(ndev);
	qtnf_netdev_updown(ndev, 0);
	return 0;
}

static void qtnf_packet_send_hi_pri(struct sk_buff *skb)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(skb->dev);

	skb_queue_tail(&vif->high_pri_tx_queue, skb);
	queue_work(vif->mac->bus->hprio_workqueue, &vif->high_pri_tx_work);
}

/* Netdev handler for data transmission.
 */
static netdev_tx_t
qtnf_netdev_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	struct qtnf_vif *vif;
	struct qtnf_wmac *mac;

	vif = qtnf_netdev_get_priv(ndev);

	if (unlikely(skb->dev != ndev)) {
		pr_err_ratelimited("invalid skb->dev");
		dev_kfree_skb_any(skb);
		return 0;
	}

	if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) {
		pr_err_ratelimited("%s: VIF not initialized\n", ndev->name);
		dev_kfree_skb_any(skb);
		return 0;
	}

	mac = vif->mac;
	if (unlikely(!mac)) {
		pr_err_ratelimited("%s: NULL mac pointer", ndev->name);
		dev_kfree_skb_any(skb);
		return 0;
	}

	if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
		pr_err_ratelimited("%s: invalid skb len %d\n", ndev->name,
				   skb->len);
		dev_kfree_skb_any(skb);
		ndev->stats.tx_dropped++;
		return 0;
	}

	/* tx path is enabled: reset vif timeout */
	vif->cons_tx_timeout_cnt = 0;

	if (unlikely(skb->protocol == htons(ETH_P_PAE))) {
		qtnf_packet_send_hi_pri(skb);
		dev_sw_netstats_tx_add(ndev, 1, skb->len);
		return NETDEV_TX_OK;
	}

	return qtnf_bus_data_tx(mac->bus, skb, mac->macid, vif->vifid);
}

/* Netdev handler for transmission timeout.
 */
static void qtnf_netdev_tx_timeout(struct net_device *ndev, unsigned int txqueue)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
	struct qtnf_wmac *mac;
	struct qtnf_bus *bus;

	if (unlikely(!vif || !vif->mac || !vif->mac->bus))
		return;

	mac = vif->mac;
	bus = mac->bus;

	pr_warn("VIF%u.%u: Tx timeout- %lu\n", mac->macid, vif->vifid, jiffies);

	qtnf_bus_data_tx_timeout(bus, ndev);
	ndev->stats.tx_errors++;

	if (++vif->cons_tx_timeout_cnt > QTNF_TX_TIMEOUT_TRSHLD) {
		pr_err("Tx timeout threshold exceeded !\n");
		pr_err("schedule interface %s reset !\n", netdev_name(ndev));
		queue_work(bus->workqueue, &vif->reset_work);
	}
}

static int qtnf_netdev_set_mac_address(struct net_device *ndev, void *addr)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
	struct sockaddr *sa = addr;
	int ret;
	unsigned char old_addr[ETH_ALEN];

	memcpy(old_addr, sa->sa_data, sizeof(old_addr));

	ret = eth_mac_addr(ndev, sa);
	if (ret)
		return ret;

	qtnf_scan_done(vif->mac, true);

	ret = qtnf_cmd_send_change_intf_type(vif, vif->wdev.iftype,
					     vif->wdev.use_4addr,
					     sa->sa_data);

	if (ret)
		eth_hw_addr_set(ndev, old_addr);

	return ret;
}

static int qtnf_netdev_port_parent_id(struct net_device *ndev,
				      struct netdev_phys_item_id *ppid)
{
	const struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
	const struct qtnf_bus *bus = vif->mac->bus;

	ppid->id_len = sizeof(bus->hw_id);
	memcpy(&ppid->id, bus->hw_id, ppid->id_len);

	return 0;
}

static int qtnf_netdev_alloc_pcpu_stats(struct net_device *dev)
{
	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);

	return dev->tstats ? 0 : -ENOMEM;
}

static void qtnf_netdev_free_pcpu_stats(struct net_device *dev)
{
	free_percpu(dev->tstats);
}

/* Network device ops handlers */
const struct net_device_ops qtnf_netdev_ops = {
	.ndo_init = qtnf_netdev_alloc_pcpu_stats,
	.ndo_uninit = qtnf_netdev_free_pcpu_stats,
	.ndo_open = qtnf_netdev_open,
	.ndo_stop = qtnf_netdev_close,
	.ndo_start_xmit = qtnf_netdev_hard_start_xmit,
	.ndo_tx_timeout = qtnf_netdev_tx_timeout,
	.ndo_get_stats64 = dev_get_tstats64,
	.ndo_set_mac_address = qtnf_netdev_set_mac_address,
	.ndo_get_port_parent_id = qtnf_netdev_port_parent_id,
};

static int qtnf_mac_init_single_band(struct wiphy *wiphy,
				     struct qtnf_wmac *mac,
				     enum nl80211_band band)
{
	int ret;

	wiphy->bands[band] = kzalloc(sizeof(*wiphy->bands[band]), GFP_KERNEL);
	if (!wiphy->bands[band])
		return -ENOMEM;

	wiphy->bands[band]->band = band;

	ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]);
	if (ret) {
		pr_err("MAC%u: band %u: failed to get chans info: %d\n",
		       mac->macid, band, ret);
		return ret;
	}

	qtnf_band_init_rates(wiphy->bands[band]);

	return 0;
}

static int qtnf_mac_init_bands(struct qtnf_wmac *mac)
{
	struct wiphy *wiphy = priv_to_wiphy(mac);
	int ret = 0;

	if (mac->macinfo.bands_cap & QLINK_BAND_2GHZ) {
		ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_2GHZ);
		if (ret)
			goto out;
	}

	if (mac->macinfo.bands_cap & QLINK_BAND_5GHZ) {
		ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_5GHZ);
		if (ret)
			goto out;
	}

	if (mac->macinfo.bands_cap & QLINK_BAND_60GHZ)
		ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_60GHZ);

out:
	return ret;
}

struct qtnf_vif *qtnf_mac_get_free_vif(struct qtnf_wmac *mac)
{
	struct qtnf_vif *vif;
	int i;

	for (i = 0; i < QTNF_MAX_INTF; i++) {
		vif = &mac->iflist[i];
		if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
			return vif;
	}

	return NULL;
}

struct qtnf_vif *qtnf_mac_get_base_vif(struct qtnf_wmac *mac)
{
	struct qtnf_vif *vif;

	vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX];

	if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
		return NULL;

	return vif;
}

void qtnf_mac_iface_comb_free(struct qtnf_wmac *mac)
{
	struct ieee80211_iface_combination *comb;
	int i;

	if (mac->macinfo.if_comb) {
		for (i = 0; i < mac->macinfo.n_if_comb; i++) {
			comb = &mac->macinfo.if_comb[i];
			kfree(comb->limits);
			comb->limits = NULL;
		}

		kfree(mac->macinfo.if_comb);
		mac->macinfo.if_comb = NULL;
	}
}

void qtnf_mac_ext_caps_free(struct qtnf_wmac *mac)
{
	if (mac->macinfo.extended_capabilities_len) {
		kfree(mac->macinfo.extended_capabilities);
		mac->macinfo.extended_capabilities = NULL;

		kfree(mac->macinfo.extended_capabilities_mask);
		mac->macinfo.extended_capabilities_mask = NULL;

		mac->macinfo.extended_capabilities_len = 0;
	}
}

static void qtnf_vif_reset_handler(struct work_struct *work)
{
	struct qtnf_vif *vif = container_of(work, struct qtnf_vif, reset_work);

	rtnl_lock();

	if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) {
		rtnl_unlock();
		return;
	}

	/* stop tx completely */
	netif_tx_stop_all_queues(vif->netdev);
	if (netif_carrier_ok(vif->netdev))
		netif_carrier_off(vif->netdev);

	qtnf_cfg80211_vif_reset(vif);

	rtnl_unlock();
}

static void qtnf_mac_init_primary_intf(struct qtnf_wmac *mac)
{
	struct qtnf_vif *vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX];

	vif->wdev.iftype = NL80211_IFTYPE_STATION;
	vif->bss_priority = QTNF_DEF_BSS_PRIORITY;
	vif->wdev.wiphy = priv_to_wiphy(mac);
	INIT_WORK(&vif->reset_work, qtnf_vif_reset_handler);
	vif->cons_tx_timeout_cnt = 0;
}

static void qtnf_mac_scan_finish(struct qtnf_wmac *mac, bool aborted)
{
	struct cfg80211_scan_info info = {
		.aborted = aborted,
	};

	mutex_lock(&mac->mac_lock);

	if (mac->scan_req) {
		cfg80211_scan_done(mac->scan_req, &info);
		mac->scan_req = NULL;
	}

	mutex_unlock(&mac->mac_lock);
}

void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted)
{
	cancel_delayed_work_sync(&mac->scan_timeout);
	qtnf_mac_scan_finish(mac, aborted);
}

static void qtnf_mac_scan_timeout(struct work_struct *work)
{
	struct qtnf_wmac *mac =
		container_of(work, struct qtnf_wmac, scan_timeout.work);

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

static void qtnf_vif_send_data_high_pri(struct work_struct *work)
{
	struct qtnf_vif *vif =
		container_of(work, struct qtnf_vif, high_pri_tx_work);
	struct sk_buff *skb;

	if (!vif->netdev ||
	    vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
		return;

	while ((skb = skb_dequeue(&vif->high_pri_tx_queue))) {
		qtnf_cmd_send_frame(vif, 0, QLINK_FRAME_TX_FLAG_8023,
				    0, skb->data, skb->len);
		dev_kfree_skb_any(skb);
	}
}

static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
					     unsigned int macid)
{
	struct platform_device *pdev = NULL;
	struct qtnf_wmac *mac;
	struct qtnf_vif *vif;
	struct wiphy *wiphy;
	unsigned int i;

	if (bus->hw_info.num_mac > 1) {
		pdev = platform_device_register_data(bus->dev,
						     dev_name(bus->dev),
						     macid, NULL, 0);
		if (IS_ERR(pdev))
			return ERR_PTR(-EINVAL);
	}

	wiphy = qtnf_wiphy_allocate(bus, pdev);
	if (!wiphy) {
		if (pdev)
			platform_device_unregister(pdev);
		return ERR_PTR(-ENOMEM);
	}

	mac = wiphy_priv(wiphy);

	mac->macid = macid;
	mac->pdev = pdev;
	mac->bus = bus;
	mutex_init(&mac->mac_lock);
	INIT_DELAYED_WORK(&mac->scan_timeout, qtnf_mac_scan_timeout);

	for (i = 0; i < QTNF_MAX_INTF; i++) {
		vif = &mac->iflist[i];

		memset(vif, 0, sizeof(*vif));
		vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
		vif->mac = mac;
		vif->vifid = i;
		qtnf_sta_list_init(&vif->sta_list);
		INIT_WORK(&vif->high_pri_tx_work, qtnf_vif_send_data_high_pri);
		skb_queue_head_init(&vif->high_pri_tx_queue);
	}

	qtnf_mac_init_primary_intf(mac);
	bus->mac[macid] = mac;

	return mac;
}

static const struct ethtool_ops qtnf_ethtool_ops = {
	.get_drvinfo = cfg80211_get_drvinfo,
};

int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,
			 const char *name, unsigned char name_assign_type)
{
	struct wiphy *wiphy = priv_to_wiphy(mac);
	struct net_device *dev;
	void *qdev_vif;
	int ret;

	dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name,
			       name_assign_type, ether_setup, 1, 1);
	if (!dev)
		return -ENOMEM;

	vif->netdev = dev;

	dev->netdev_ops = &qtnf_netdev_ops;
	dev->needs_free_netdev = true;
	dev_net_set(dev, wiphy_net(wiphy));
	dev->ieee80211_ptr = &vif->wdev;
	eth_hw_addr_set(dev, vif->mac_addr);
	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
	dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT;
	dev->tx_queue_len = 100;
	dev->ethtool_ops = &qtnf_ethtool_ops;

	if (qtnf_hwcap_is_set(&mac->bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE))
		dev->needed_tailroom = sizeof(struct qtnf_frame_meta_info);

	qdev_vif = netdev_priv(dev);
	*((void **)qdev_vif) = vif;

	SET_NETDEV_DEV(dev, wiphy_dev(wiphy));

	ret = cfg80211_register_netdevice(dev);
	if (ret) {
		free_netdev(dev);
		vif->netdev = NULL;
	}

	return ret;
}

static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid)
{
	struct qtnf_wmac *mac;
	struct wiphy *wiphy;
	struct qtnf_vif *vif;
	unsigned int i;
	enum nl80211_band band;

	mac = bus->mac[macid];

	if (!mac)
		return;

	wiphy = priv_to_wiphy(mac);

	for (i = 0; i < QTNF_MAX_INTF; i++) {
		vif = &mac->iflist[i];
		rtnl_lock();
		if (vif->netdev &&
		    vif->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED) {
			qtnf_virtual_intf_cleanup(vif->netdev);
			qtnf_del_virtual_intf(wiphy, &vif->wdev);
		}
		rtnl_unlock();
		qtnf_sta_list_free(&vif->sta_list);
	}

	if (mac->wiphy_registered)
		wiphy_unregister(wiphy);

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

		kfree(wiphy->bands[band]->iftype_data);
		wiphy->bands[band]->n_iftype_data = 0;

		kfree(wiphy->bands[band]->channels);
		wiphy->bands[band]->n_channels = 0;

		kfree(wiphy->bands[band]);
		wiphy->bands[band] = NULL;
	}

	platform_device_unregister(mac->pdev);
	qtnf_mac_iface_comb_free(mac);
	qtnf_mac_ext_caps_free(mac);
	kfree(mac->macinfo.wowlan);
	kfree(mac->rd);
	mac->rd = NULL;
	wiphy_free(wiphy);
	bus->mac[macid] = NULL;
}

static int qtnf_core_mac_attach(struct qtnf_bus *bus, unsigned int macid)
{
	struct qtnf_wmac *mac;
	struct qtnf_vif *vif;
	int ret;

	if (!(bus->hw_info.mac_bitmap & BIT(macid))) {
		pr_info("MAC%u is not active in FW\n", macid);
		return 0;
	}

	mac = qtnf_core_mac_alloc(bus, macid);
	if (IS_ERR(mac)) {
		pr_err("MAC%u allocation failed\n", macid);
		return PTR_ERR(mac);
	}

	vif = qtnf_mac_get_base_vif(mac);
	if (!vif) {
		pr_err("MAC%u: primary VIF is not ready\n", macid);
		ret = -EFAULT;
		goto error;
	}

	ret = qtnf_cmd_send_add_intf(vif, vif->wdev.iftype,
				     vif->wdev.use_4addr, vif->mac_addr);
	if (ret) {
		pr_err("MAC%u: failed to add VIF\n", macid);
		goto error;
	}

	ret = qtnf_cmd_get_mac_info(mac);
	if (ret) {
		pr_err("MAC%u: failed to get MAC info\n", macid);
		goto error_del_vif;
	}

	/* Use MAC address of the first active radio as a unique device ID */
	if (is_zero_ether_addr(mac->bus->hw_id))
		ether_addr_copy(mac->bus->hw_id, mac->macaddr);

	ret = qtnf_mac_init_bands(mac);
	if (ret) {
		pr_err("MAC%u: failed to init bands\n", macid);
		goto error_del_vif;
	}

	ret = qtnf_wiphy_register(&bus->hw_info, mac);
	if (ret) {
		pr_err("MAC%u: wiphy registration failed\n", macid);
		goto error_del_vif;
	}

	mac->wiphy_registered = 1;

	rtnl_lock();
	wiphy_lock(priv_to_wiphy(mac));
	ret = qtnf_core_net_attach(mac, vif, "wlan%d", NET_NAME_ENUM);
	wiphy_unlock(priv_to_wiphy(mac));
	rtnl_unlock();

	if (ret) {
		pr_err("MAC%u: failed to attach netdev\n", macid);
		goto error_del_vif;
	}

	if (qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE)) {
		ret = qtnf_cmd_netdev_changeupper(vif, vif->netdev->ifindex);
		if (ret)
			goto error;
	}

	pr_debug("MAC%u initialized\n", macid);

	return 0;

error_del_vif:
	qtnf_cmd_send_del_intf(vif);
	vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
error:
	qtnf_core_mac_detach(bus, macid);
	return ret;
}

bool qtnf_netdev_is_qtn(const struct net_device *ndev)
{
	return ndev->netdev_ops == &qtnf_netdev_ops;
}

static int qtnf_check_br_ports(struct net_device *dev,
			       struct netdev_nested_priv *priv)
{
	struct net_device *ndev = (struct net_device *)priv->data;

	if (dev != ndev && netdev_port_same_parent_id(dev, ndev))
		return -ENOTSUPP;

	return 0;
}

static int qtnf_core_netdevice_event(struct notifier_block *nb,
				     unsigned long event, void *ptr)
{
	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
	const struct netdev_notifier_changeupper_info *info;
	struct netdev_nested_priv priv = {
		.data = (void *)ndev,
	};
	struct net_device *brdev;
	struct qtnf_vif *vif;
	struct qtnf_bus *bus;
	int br_domain;
	int ret = 0;

	if (!qtnf_netdev_is_qtn(ndev))
		return NOTIFY_DONE;

	if (!net_eq(dev_net(ndev), &init_net))
		return NOTIFY_OK;

	vif = qtnf_netdev_get_priv(ndev);
	bus = vif->mac->bus;

	switch (event) {
	case NETDEV_CHANGEUPPER:
		info = ptr;
		brdev = info->upper_dev;

		if (!netif_is_bridge_master(brdev))
			break;

		pr_debug("[VIF%u.%u] change bridge: %s %s\n",
			 vif->mac->macid, vif->vifid, netdev_name(brdev),
			 info->linking ? "add" : "del");

		if (IS_ENABLED(CONFIG_NET_SWITCHDEV) &&
		    qtnf_hwcap_is_set(&bus->hw_info,
				      QLINK_HW_CAPAB_HW_BRIDGE)) {
			if (info->linking)
				br_domain = brdev->ifindex;
			else
				br_domain = ndev->ifindex;

			ret = qtnf_cmd_netdev_changeupper(vif, br_domain);
		} else {
			ret = netdev_walk_all_lower_dev(brdev,
							qtnf_check_br_ports,
							&priv);
		}

		break;
	default:
		break;
	}

	return notifier_from_errno(ret);
}

int qtnf_core_attach(struct qtnf_bus *bus)
{
	unsigned int i;
	int ret;

	qtnf_trans_init(bus);
	qtnf_bus_data_rx_start(bus);

	bus->workqueue = alloc_ordered_workqueue("QTNF_BUS", 0);
	if (!bus->workqueue) {
		pr_err("failed to alloc main workqueue\n");
		ret = -ENOMEM;
		goto error;
	}

	bus->hprio_workqueue = alloc_workqueue("QTNF_HPRI", WQ_HIGHPRI, 0);
	if (!bus->hprio_workqueue) {
		pr_err("failed to alloc high prio workqueue\n");
		ret = -ENOMEM;
		goto error;
	}

	INIT_WORK(&bus->event_work, qtnf_event_work_handler);

	ret = qtnf_cmd_send_init_fw(bus);
	if (ret) {
		pr_err("failed to init FW: %d\n", ret);
		goto error;
	}

	if (QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver) !=
	    QLINK_PROTO_VER_MAJOR) {
		pr_err("qlink driver vs FW version mismatch: %u vs %u\n",
		       QLINK_PROTO_VER_MAJOR,
		       QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver));
		ret = -EPROTONOSUPPORT;
		goto error;
	}

	bus->fw_state = QTNF_FW_STATE_ACTIVE;
	ret = qtnf_cmd_get_hw_info(bus);
	if (ret) {
		pr_err("failed to get HW info: %d\n", ret);
		goto error;
	}

	if (qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE) &&
	    bus->bus_ops->data_tx_use_meta_set)
		bus->bus_ops->data_tx_use_meta_set(bus, true);

	if (bus->hw_info.num_mac > QTNF_MAX_MAC) {
		pr_err("no support for number of MACs=%u\n",
		       bus->hw_info.num_mac);
		ret = -ERANGE;
		goto error;
	}

	for (i = 0; i < bus->hw_info.num_mac; i++) {
		ret = qtnf_core_mac_attach(bus, i);

		if (ret) {
			pr_err("MAC%u: attach failed: %d\n", i, ret);
			goto error;
		}
	}

	bus->netdev_nb.notifier_call = qtnf_core_netdevice_event;
	ret = register_netdevice_notifier(&bus->netdev_nb);
	if (ret) {
		pr_err("failed to register netdev notifier: %d\n", ret);
		goto error;
	}

	bus->fw_state = QTNF_FW_STATE_RUNNING;
	return 0;

error:
	qtnf_core_detach(bus);
	return ret;
}
EXPORT_SYMBOL_GPL(qtnf_core_attach);

void qtnf_core_detach(struct qtnf_bus *bus)
{
	unsigned int macid;

	unregister_netdevice_notifier(&bus->netdev_nb);
	qtnf_bus_data_rx_stop(bus);

	for (macid = 0; macid < QTNF_MAX_MAC; macid++)
		qtnf_core_mac_detach(bus, macid);

	if (qtnf_fw_is_up(bus))
		qtnf_cmd_send_deinit_fw(bus);

	bus->fw_state = QTNF_FW_STATE_DETACHED;

	if (bus->workqueue) {
		destroy_workqueue(bus->workqueue);
		bus->workqueue = NULL;
	}

	if (bus->hprio_workqueue) {
		destroy_workqueue(bus->hprio_workqueue);
		bus->hprio_workqueue = NULL;
	}

	qtnf_trans_free(bus);
}
EXPORT_SYMBOL_GPL(qtnf_core_detach);

static inline int qtnf_is_frame_meta_magic_valid(struct qtnf_frame_meta_info *m)
{
	return m->magic_s == HBM_FRAME_META_MAGIC_PATTERN_S &&
		m->magic_e == HBM_FRAME_META_MAGIC_PATTERN_E;
}

struct net_device *qtnf_classify_skb(struct qtnf_bus *bus, struct sk_buff *skb)
{
	struct qtnf_frame_meta_info *meta;
	struct net_device *ndev = NULL;
	struct qtnf_wmac *mac;
	struct qtnf_vif *vif;

	if (unlikely(bus->fw_state != QTNF_FW_STATE_RUNNING))
		return NULL;

	meta = (struct qtnf_frame_meta_info *)
		(skb_tail_pointer(skb) - sizeof(*meta));

	if (unlikely(!qtnf_is_frame_meta_magic_valid(meta))) {
		pr_err_ratelimited("invalid magic 0x%x:0x%x\n",
				   meta->magic_s, meta->magic_e);
		goto out;
	}

	if (unlikely(meta->macid >= QTNF_MAX_MAC)) {
		pr_err_ratelimited("invalid mac(%u)\n", meta->macid);
		goto out;
	}

	if (unlikely(meta->ifidx >= QTNF_MAX_INTF)) {
		pr_err_ratelimited("invalid vif(%u)\n", meta->ifidx);
		goto out;
	}

	mac = bus->mac[meta->macid];

	if (unlikely(!mac)) {
		pr_err_ratelimited("mac(%d) does not exist\n", meta->macid);
		goto out;
	}

	vif = &mac->iflist[meta->ifidx];

	if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) {
		pr_err_ratelimited("vif(%u) does not exists\n", meta->ifidx);
		goto out;
	}

	ndev = vif->netdev;

	if (unlikely(!ndev)) {
		pr_err_ratelimited("netdev for wlan%u.%u does not exists\n",
				   meta->macid, meta->ifidx);
		goto out;
	}

	__skb_trim(skb, skb->len - sizeof(*meta));
	/* Firmware always handles packets that require flooding */
	qtnfmac_switch_mark_skb_flooded(skb);

out:
	return ndev;
}
EXPORT_SYMBOL_GPL(qtnf_classify_skb);

void qtnf_wake_all_queues(struct net_device *ndev)
{
	struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
	struct qtnf_wmac *mac;
	struct qtnf_bus *bus;
	int macid;
	int i;

	if (unlikely(!vif || !vif->mac || !vif->mac->bus))
		return;

	bus = vif->mac->bus;

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

		mac = bus->mac[macid];
		for (i = 0; i < QTNF_MAX_INTF; i++) {
			vif = &mac->iflist[i];
			if (vif->netdev && netif_queue_stopped(vif->netdev))
				netif_tx_wake_all_queues(vif->netdev);
		}
	}
}
EXPORT_SYMBOL_GPL(qtnf_wake_all_queues);

struct dentry *qtnf_get_debugfs_dir(void)
{
	return qtnf_debugfs_dir;
}
EXPORT_SYMBOL_GPL(qtnf_get_debugfs_dir);

static int __init qtnf_core_register(void)
{
	qtnf_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);

	if (IS_ERR(qtnf_debugfs_dir))
		qtnf_debugfs_dir = NULL;

	return 0;
}

static void __exit qtnf_core_exit(void)
{
	debugfs_remove(qtnf_debugfs_dir);
}

module_init(qtnf_core_register);
module_exit(qtnf_core_exit);

MODULE_AUTHOR("Quantenna Communications");
MODULE_DESCRIPTION("Quantenna 802.11 wireless LAN FullMAC driver.");
MODULE_LICENSE("GPL");
