/*
 * Copyright (C) 1999 - 2010 Intel Corporation.
 * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
 *
 * This code was derived from the Intel e1000e Linux driver.
 *
 * 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; version 2 of the License.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
 */
#include "pch_gbe.h"
#include "pch_gbe_phy.h"

/* bus type values */
#define pch_gbe_bus_type_unknown	0
#define pch_gbe_bus_type_pci		1
#define pch_gbe_bus_type_pcix		2
#define pch_gbe_bus_type_pci_express	3
#define pch_gbe_bus_type_reserved	4

/* bus speed values */
#define pch_gbe_bus_speed_unknown	0
#define pch_gbe_bus_speed_33		1
#define pch_gbe_bus_speed_66		2
#define pch_gbe_bus_speed_100		3
#define pch_gbe_bus_speed_120		4
#define pch_gbe_bus_speed_133		5
#define pch_gbe_bus_speed_2500		6
#define pch_gbe_bus_speed_reserved	7

/* bus width values */
#define pch_gbe_bus_width_unknown	0
#define pch_gbe_bus_width_pcie_x1	1
#define pch_gbe_bus_width_pcie_x2	2
#define pch_gbe_bus_width_pcie_x4	4
#define pch_gbe_bus_width_32		5
#define pch_gbe_bus_width_64		6
#define pch_gbe_bus_width_reserved	7

/**
 * pch_gbe_plat_get_bus_info - Obtain bus information for adapter
 * @hw:	Pointer to the HW structure
 */
static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw)
{
	hw->bus.type  = pch_gbe_bus_type_pci_express;
	hw->bus.speed = pch_gbe_bus_speed_2500;
	hw->bus.width = pch_gbe_bus_width_pcie_x1;
}

/**
 * pch_gbe_plat_init_hw - Initialize hardware
 * @hw:	Pointer to the HW structure
 * Returns
 *	0:		Successfully
 *	Negative value:	Failed-EBUSY
 */
static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw)
{
	s32 ret_val;

	ret_val = pch_gbe_phy_get_id(hw);
	if (ret_val) {
		pr_err("pch_gbe_phy_get_id error\n");
		return ret_val;
	}
	pch_gbe_phy_init_setting(hw);
	/* Setup Mac interface option RGMII */
#ifdef PCH_GBE_MAC_IFOP_RGMII
	pch_gbe_phy_set_rgmii(hw);
#endif
	return ret_val;
}

static const struct pch_gbe_functions pch_gbe_ops = {
	.get_bus_info      = pch_gbe_plat_get_bus_info,
	.init_hw           = pch_gbe_plat_init_hw,
	.read_phy_reg      = pch_gbe_phy_read_reg_miic,
	.write_phy_reg     = pch_gbe_phy_write_reg_miic,
	.reset_phy         = pch_gbe_phy_hw_reset,
	.sw_reset_phy      = pch_gbe_phy_sw_reset,
	.power_up_phy      = pch_gbe_phy_power_up,
	.power_down_phy    = pch_gbe_phy_power_down,
	.read_mac_addr     = pch_gbe_mac_read_mac_addr
};

/**
 * pch_gbe_plat_init_function_pointers - Init func ptrs
 * @hw:	Pointer to the HW structure
 */
static void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw)
{
	/* Set PHY parameter */
	hw->phy.reset_delay_us     = PCH_GBE_PHY_RESET_DELAY_US;
	/* Set function pointers */
	hw->func = &pch_gbe_ops;
}

/**
 * pch_gbe_hal_setup_init_funcs - Initializes function pointers
 * @hw:	Pointer to the HW structure
 * Returns
 *	0:	Successfully
 *	ENOSYS:	Function is not registered
 */
inline s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
{
	if (!hw->reg) {
		pr_err("ERROR: Registers not mapped\n");
		return -ENOSYS;
	}
	pch_gbe_plat_init_function_pointers(hw);
	return 0;
}

/**
 * pch_gbe_hal_get_bus_info - Obtain bus information for adapter
 * @hw:	Pointer to the HW structure
 */
inline void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
{
	if (!hw->func->get_bus_info)
		pr_err("ERROR: configuration\n");
	else
		hw->func->get_bus_info(hw);
}

/**
 * pch_gbe_hal_init_hw - Initialize hardware
 * @hw:	Pointer to the HW structure
 * Returns
 *	0:	Successfully
 *	ENOSYS:	Function is not registered
 */
inline s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
{
	if (!hw->func->init_hw) {
		pr_err("ERROR: configuration\n");
		return -ENOSYS;
	}
	return hw->func->init_hw(hw);
}

/**
 * pch_gbe_hal_read_phy_reg - Reads PHY register
 * @hw:	    Pointer to the HW structure
 * @offset: The register to read
 * @data:   The buffer to store the 16-bit read.
 * Returns
 *	0:	Successfully
 *	Negative value:	Failed
 */
inline s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset,
					u16 *data)
{
	if (!hw->func->read_phy_reg)
		return 0;
	return hw->func->read_phy_reg(hw, offset, data);
}

/**
 * pch_gbe_hal_write_phy_reg - Writes PHY register
 * @hw:	    Pointer to the HW structure
 * @offset: The register to read
 * @data:   The value to write.
 * Returns
 *	0:	Successfully
 *	Negative value:	Failed
 */
inline s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset,
					u16 data)
{
	if (!hw->func->write_phy_reg)
		return 0;
	return hw->func->write_phy_reg(hw, offset, data);
}

/**
 * pch_gbe_hal_phy_hw_reset - Hard PHY reset
 * @hw:	    Pointer to the HW structure
 */
inline void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
{
	if (!hw->func->reset_phy)
		pr_err("ERROR: configuration\n");
	else
		hw->func->reset_phy(hw);
}

/**
 * pch_gbe_hal_phy_sw_reset - Soft PHY reset
 * @hw:	    Pointer to the HW structure
 */
inline void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
{
	if (!hw->func->sw_reset_phy)
		pr_err("ERROR: configuration\n");
	else
		hw->func->sw_reset_phy(hw);
}

/**
 * pch_gbe_hal_read_mac_addr - Reads MAC address
 * @hw:	Pointer to the HW structure
 * Returns
 *	0:	Successfully
 *	ENOSYS:	Function is not registered
 */
inline s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
{
	if (!hw->func->read_mac_addr) {
		pr_err("ERROR: configuration\n");
		return -ENOSYS;
	}
	return hw->func->read_mac_addr(hw);
}

/**
 * pch_gbe_hal_power_up_phy - Power up PHY
 * @hw:	Pointer to the HW structure
 */
inline void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
{
	if (hw->func->power_up_phy)
		hw->func->power_up_phy(hw);
}

/**
 * pch_gbe_hal_power_down_phy - Power down PHY
 * @hw:	Pointer to the HW structure
 */
inline void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
{
	if (hw->func->power_down_phy)
		hw->func->power_down_phy(hw);
}
