/*
 * aQuantia Corporation Network Driver
 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 */

/* File aq_main.c: Main file for aQuantia Linux driver. */

#include "aq_main.h"
#include "aq_nic.h"
#include "aq_pci_func.h"
#include "aq_ethtool.h"
#include "hw_atl/hw_atl_a0.h"
#include "hw_atl/hw_atl_b0.h"

#include <linux/netdevice.h>
#include <linux/module.h>

static const struct pci_device_id aq_pci_tbl[] = {
	{ PCI_VDEVICE(AQUANTIA, HW_ATL_DEVICE_ID_0001), },
	{ PCI_VDEVICE(AQUANTIA, HW_ATL_DEVICE_ID_D100), },
	{ PCI_VDEVICE(AQUANTIA, HW_ATL_DEVICE_ID_D107), },
	{ PCI_VDEVICE(AQUANTIA, HW_ATL_DEVICE_ID_D108), },
	{ PCI_VDEVICE(AQUANTIA, HW_ATL_DEVICE_ID_D109), },
	{}
};

MODULE_DEVICE_TABLE(pci, aq_pci_tbl);

MODULE_LICENSE("GPL v2");
MODULE_VERSION(AQ_CFG_DRV_VERSION);
MODULE_AUTHOR(AQ_CFG_DRV_AUTHOR);
MODULE_DESCRIPTION(AQ_CFG_DRV_DESC);

static struct aq_hw_ops *aq_pci_probe_get_hw_ops_by_id(struct pci_dev *pdev)
{
	struct aq_hw_ops *ops = NULL;

	ops = hw_atl_a0_get_ops_by_id(pdev);
	if (!ops)
		ops = hw_atl_b0_get_ops_by_id(pdev);

	return ops;
}

static int aq_ndev_open(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = NULL;
	int err = 0;

	aq_nic = aq_nic_alloc_hot(ndev);
	if (!aq_nic) {
		err = -ENOMEM;
		goto err_exit;
	}
	err = aq_nic_init(aq_nic);
	if (err < 0)
		goto err_exit;
	err = aq_nic_start(aq_nic);
	if (err < 0)
		goto err_exit;

err_exit:
	if (err < 0)
		aq_nic_deinit(aq_nic);
	return err;
}

static int aq_ndev_close(struct net_device *ndev)
{
	int err = 0;
	struct aq_nic_s *aq_nic = netdev_priv(ndev);

	err = aq_nic_stop(aq_nic);
	if (err < 0)
		goto err_exit;
	aq_nic_deinit(aq_nic);
	aq_nic_free_hot_resources(aq_nic);

err_exit:
	return err;
}

static int aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);

	return aq_nic_xmit(aq_nic, skb);
}

static int aq_ndev_change_mtu(struct net_device *ndev, int new_mtu)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	int err = aq_nic_set_mtu(aq_nic, new_mtu + ETH_HLEN);

	if (err < 0)
		goto err_exit;
	ndev->mtu = new_mtu;

err_exit:
	return err;
}

static int aq_ndev_set_features(struct net_device *ndev,
				netdev_features_t features)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic);
	bool is_lro = false;

	if (aq_cfg->hw_features & NETIF_F_LRO) {
		is_lro = features & NETIF_F_LRO;

		if (aq_cfg->is_lro != is_lro) {
			aq_cfg->is_lro = is_lro;

			if (netif_running(ndev)) {
				aq_ndev_close(ndev);
				aq_ndev_open(ndev);
			}
		}
	}

	return 0;
}

static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	int err = 0;

	err = eth_mac_addr(ndev, addr);
	if (err < 0)
		goto err_exit;
	err = aq_nic_set_mac(aq_nic, ndev);
	if (err < 0)
		goto err_exit;

err_exit:
	return err;
}

static void aq_ndev_set_multicast_settings(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	int err = 0;

	err = aq_nic_set_packet_filter(aq_nic, ndev->flags);
	if (err < 0)
		goto err_exit;

	if (netdev_mc_count(ndev)) {
		err = aq_nic_set_multicast_list(aq_nic, ndev);
		if (err < 0)
			goto err_exit;
	}

err_exit:;
}

static const struct net_device_ops aq_ndev_ops = {
	.ndo_open = aq_ndev_open,
	.ndo_stop = aq_ndev_close,
	.ndo_start_xmit = aq_ndev_start_xmit,
	.ndo_set_rx_mode = aq_ndev_set_multicast_settings,
	.ndo_change_mtu = aq_ndev_change_mtu,
	.ndo_set_mac_address = aq_ndev_set_mac_address,
	.ndo_set_features = aq_ndev_set_features
};

static int aq_pci_probe(struct pci_dev *pdev,
			const struct pci_device_id *pci_id)
{
	struct aq_hw_ops *aq_hw_ops = NULL;
	struct aq_pci_func_s *aq_pci_func = NULL;
	int err = 0;

	err = pci_enable_device(pdev);
	if (err < 0)
		goto err_exit;
	aq_hw_ops = aq_pci_probe_get_hw_ops_by_id(pdev);
	aq_pci_func = aq_pci_func_alloc(aq_hw_ops, pdev,
					&aq_ndev_ops, &aq_ethtool_ops);
	if (!aq_pci_func) {
		err = -ENOMEM;
		goto err_exit;
	}
	err = aq_pci_func_init(aq_pci_func);
	if (err < 0)
		goto err_exit;

err_exit:
	if (err < 0) {
		if (aq_pci_func)
			aq_pci_func_free(aq_pci_func);
	}
	return err;
}

static void aq_pci_remove(struct pci_dev *pdev)
{
	struct aq_pci_func_s *aq_pci_func = pci_get_drvdata(pdev);

	aq_pci_func_deinit(aq_pci_func);
	aq_pci_func_free(aq_pci_func);
}

static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg)
{
	struct aq_pci_func_s *aq_pci_func = pci_get_drvdata(pdev);

	return aq_pci_func_change_pm_state(aq_pci_func, &pm_msg);
}

static int aq_pci_resume(struct pci_dev *pdev)
{
	struct aq_pci_func_s *aq_pci_func = pci_get_drvdata(pdev);
	pm_message_t pm_msg = PMSG_RESTORE;

	return aq_pci_func_change_pm_state(aq_pci_func, &pm_msg);
}

static struct pci_driver aq_pci_ops = {
	.name = AQ_CFG_DRV_NAME,
	.id_table = aq_pci_tbl,
	.probe = aq_pci_probe,
	.remove = aq_pci_remove,
	.suspend = aq_pci_suspend,
	.resume = aq_pci_resume,
};

module_pci_driver(aq_pci_ops);
