/*
 * Copyright 2011 Cisco Systems, Inc.  All rights reserved.
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include <linux/pci.h>
#include <linux/etherdevice.h>

#include "vnic_dev.h"
#include "vnic_vic.h"
#include "enic_res.h"
#include "enic.h"
#include "enic_dev.h"

int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_fw_info(enic->vdev, fw_info);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_stats_dump(enic->vdev, vstats);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_add_station_addr(struct enic *enic)
{
	int err;

	if (!is_valid_ether_addr(enic->netdev->dev_addr))
		return -EADDRNOTAVAIL;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_del_station_addr(struct enic *enic)
{
	int err;

	if (!is_valid_ether_addr(enic->netdev->dev_addr))
		return -EADDRNOTAVAIL;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_packet_filter(struct enic *enic, int directed, int multicast,
	int broadcast, int promisc, int allmulti)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_packet_filter(enic->vdev, directed,
		multicast, broadcast, promisc, allmulti);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_add_addr(struct enic *enic, u8 *addr)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_add_addr(enic->vdev, addr);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_del_addr(struct enic *enic, u8 *addr)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_del_addr(enic->vdev, addr);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_notify_unset(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_notify_unset(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_hang_notify(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_hang_notify(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
		IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_enable(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_enable_wait(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_disable(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_disable(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_intr_coal_timer_info(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_intr_coal_timer_info(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_vnic_dev_deinit(struct enic *enic)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_deinit(enic->vdev);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_init_prov2(enic->vdev,
		(u8 *)vp, vic_provinfo_size(vp));
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_deinit_done(struct enic *enic, int *status)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_deinit_done(enic->vdev, status);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

/* rtnl lock is held */
void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
{
	struct enic *enic = netdev_priv(netdev);

	spin_lock(&enic->devcmd_lock);
	enic_add_vlan(enic, vid);
	spin_unlock(&enic->devcmd_lock);
}

/* rtnl lock is held */
void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{
	struct enic *enic = netdev_priv(netdev);

	spin_lock(&enic->devcmd_lock);
	enic_del_vlan(enic, vid);
	spin_unlock(&enic->devcmd_lock);
}

int enic_dev_enable2(struct enic *enic, int active)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_enable2(enic->vdev, active);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_enable2_done(struct enic *enic, int *status)
{
	int err;

	spin_lock(&enic->devcmd_lock);
	err = vnic_dev_enable2_done(enic->vdev, status);
	spin_unlock(&enic->devcmd_lock);

	return err;
}

int enic_dev_status_to_errno(int devcmd_status)
{
	switch (devcmd_status) {
	case ERR_SUCCESS:
		return 0;
	case ERR_EINVAL:
		return -EINVAL;
	case ERR_EFAULT:
		return -EFAULT;
	case ERR_EPERM:
		return -EPERM;
	case ERR_EBUSY:
		return -EBUSY;
	case ERR_ECMDUNKNOWN:
	case ERR_ENOTSUPPORTED:
		return -EOPNOTSUPP;
	case ERR_EBADSTATE:
		return -EINVAL;
	case ERR_ENOMEM:
		return -ENOMEM;
	case ERR_ETIMEDOUT:
		return -ETIMEDOUT;
	case ERR_ELINKDOWN:
		return -ENETDOWN;
	case ERR_EINPROGRESS:
		return -EINPROGRESS;
	case ERR_EMAXRES:
	default:
		return (devcmd_status < 0) ? devcmd_status : -1;
	}
}
