/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "sw.h"
#include "mp_portctrl_reg.h"
#include "mp_portctrl.h"
#include "adpt.h"
#include "adpt_mp.h"
#include "adpt_mp_portctrl.h"
#include "adpt_mp_uniphy.h"
#include "hsl_port_prop.h"
#include "hsl_phy.h"
#include "ssdk_dts.h"
#include "ssdk_clk.h"

static a_uint32_t port_lpi_status[SW_MAX_NR_DEV] = {0};

static sw_error_t
_adpt_mp_gcc_mac_clock_set(a_uint32_t dev_id,
	a_uint32_t port_id, a_bool_t enable)
{
	sw_error_t rv = 0;

	qca_gcc_mac_port_clock_set(dev_id, port_id, enable);

	return rv;
}

static a_bool_t
_adpt_mp_port_phy_connected (a_uint32_t dev_id, fal_port_t port_id)
{
	a_bool_t force_port = 0;

	ADPT_DEV_ID_CHECK(dev_id);

	/* force port which connect s17c or other device chip*/
	force_port = ssdk_port_feature_get(dev_id, port_id, PHY_F_FORCE);
	if (force_port == A_TRUE) {
		SSDK_DEBUG("port_id %d is a force port!\n", port_id);
		return A_FALSE;
	} else {
		return A_TRUE;
	}
}

static sw_error_t
_adpt_mp_port_gcc_speed_clock_set(
	a_uint32_t dev_id,
	a_uint32_t port_id,
	fal_port_speed_t phy_speed)
{
	sw_error_t rv = 0;

	switch (phy_speed) {
		case FAL_SPEED_10:
			ssdk_port_speed_clock_set(dev_id,
					port_id, SGMII_SPEED_10M_CLK);
			break;
		case FAL_SPEED_100:
			ssdk_port_speed_clock_set(dev_id,
					port_id, SGMII_SPEED_100M_CLK);
			break;
		case FAL_SPEED_1000:
			ssdk_port_speed_clock_set(dev_id,
					port_id, SGMII_SPEED_1000M_CLK);
			break;
		case FAL_SPEED_2500:
			ssdk_port_speed_clock_set(dev_id,
					port_id, SGMII_PLUS_SPEED_2500M_CLK);
			break;
		default:
			break;
               }

	return rv;
}

static sw_error_t
adpt_mp_port_reset_set(a_uint32_t dev_id, a_uint32_t port_id)
{
	sw_error_t rv = 0;
	a_uint32_t phy_addr;
	hsl_phy_ops_t *phy_drv;

	ADPT_DEV_ID_CHECK(dev_id);

	if (port_id == SSDK_PHYSICAL_PORT1) {
		/*internal gephy reset*/
		SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get(dev_id,
				port_id));
		if (NULL == phy_drv->phy_function_reset)
			return SW_NOT_SUPPORTED;
		rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_addr);
		SW_RTN_ON_ERROR (rv);
		rv = phy_drv->phy_function_reset(dev_id, phy_addr, PHY_FIFO_RESET);
		SW_RTN_ON_ERROR (rv);
	} else if (port_id == SSDK_PHYSICAL_PORT2) {
		rv = adpt_mp_uniphy_adapter_port_reset(dev_id, port_id);
	} else {
		return SW_NOT_SUPPORTED;
	}

	return rv;
}

static sw_error_t
adpt_mp_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id,
		a_bool_t enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_configuration_u configuration;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	memset(&configuration, 0, sizeof(configuration));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	configuration.bf.tx_enable = enable;
	rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration);

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id,
		a_bool_t *enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_configuration_u configuration;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);

	memset(&configuration, 0, sizeof(configuration));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	*enable = configuration.bf.tx_enable;

	return rv;
}
#endif

static sw_error_t
adpt_mp_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id,
		a_bool_t enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_configuration_u configuration;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	memset(&configuration, 0, sizeof(configuration));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	configuration.bf.rx_enable = enable;
	rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration);

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id,
		a_bool_t *enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_configuration_u configuration;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);

	memset(&configuration, 0, sizeof(configuration));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	*enable = configuration.bf.rx_enable;

	return rv;
}
#endif

static sw_error_t
adpt_mp_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_flow_ctrl_u mac_flow_ctrl;
	struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id);
	union mac_operation_mode_ctrl_u mac_operation_mode_ctrl;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(priv);

	memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl));
	memset(&mac_operation_mode_ctrl, 0, sizeof(mac_operation_mode_ctrl));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl);
	SW_RTN_ON_ERROR(rv);

	rv = mp_mac_operation_mode_ctrl_get(dev_id, gmac_id,
			&mac_operation_mode_ctrl);
	SW_RTN_ON_ERROR(rv);

	if (A_TRUE == enable) {
		mac_flow_ctrl.bf.flowctrl_tx_enable = 1;
		mac_flow_ctrl.bf.pause_time = GMAC_PAUSE_TIME;
		mac_flow_ctrl.bf.disable_zero_quanta_pause =
			GMAC_PAUSE_ZERO_QUANTA_ENABLE;
		mac_operation_mode_ctrl.bf.enable_hw_flowctrl =
			GMAC_HW_FLOWCTRL_ENABLE;
		mac_operation_mode_ctrl.bf.disable_flushing_receiving_frame =
			GMAC_FLUSH_RECEIVED_FRAMES_DISABLE;
		/*activate flowctrl when 6KB FIFO is available*/
		mac_operation_mode_ctrl.val &= ~(GMAC_ACTIVATE_FLOWCTRL_MASK);
		mac_operation_mode_ctrl.val |= GMAC_ACTIVATE_FLOWCTRL_WITH_6KB;
		/*dactivate flowctrl when 7KB FIFO is available*/
		mac_operation_mode_ctrl.val &= ~(GMAC_DACTIVATE_FLOWCTRL_MASK);
		mac_operation_mode_ctrl.val |= GMAC_DACTIVATE_FLOWCTRL_WITH_7KB;
	} else {
		mac_flow_ctrl.bf.flowctrl_tx_enable = 0;
		mac_operation_mode_ctrl.bf.enable_hw_flowctrl =
			GMAC_HW_FLOWCTRL_DISABLE;
	}

	rv = mp_mac_operation_mode_ctrl_set(dev_id, gmac_id,
			&mac_operation_mode_ctrl);
	SW_RTN_ON_ERROR(rv);

	rv = mp_mac_flowctrl_set(dev_id, gmac_id, &mac_flow_ctrl);
	SW_RTN_ON_ERROR(rv);

	priv->port_old_tx_flowctrl[port_id - 1] = enable;

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t * enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_flow_ctrl_u mac_flow_ctrl;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);

	memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl);
	SW_RTN_ON_ERROR(rv);

	if (mac_flow_ctrl.bf.flowctrl_tx_enable) {
		*enable = A_TRUE;
	} else {
		*enable = A_FALSE;
	}

	return rv;
}
#endif

static sw_error_t
adpt_mp_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_flow_ctrl_u mac_flow_ctrl;
	struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id);

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(priv);

	memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl);
	SW_RTN_ON_ERROR(rv);

	if (A_TRUE == enable) {
		mac_flow_ctrl.bf.flowctrl_rx_enable = 1;
	} else {
		mac_flow_ctrl.bf.flowctrl_rx_enable = 0;
	}

	rv = mp_mac_flowctrl_set(dev_id, gmac_id, &mac_flow_ctrl);

	priv->port_old_rx_flowctrl[port_id - 1] = enable;

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t * enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_flow_ctrl_u mac_flow_ctrl;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);

	memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl);
	SW_RTN_ON_ERROR(rv);

	if (mac_flow_ctrl.bf.flowctrl_rx_enable) {
		*enable = A_TRUE;
	} else {
		*enable = A_FALSE;
	}

	return rv;
}
#endif

static sw_error_t
adpt_mp_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t enable)
{
	sw_error_t rv = SW_OK;
	struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id);

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(priv);

	rv = adpt_mp_port_txfc_status_set(dev_id, port_id, enable);
	SW_RTN_ON_ERROR(rv);

	rv = adpt_mp_port_rxfc_status_set(dev_id, port_id, enable);
	SW_RTN_ON_ERROR(rv);

	priv->port_old_tx_flowctrl[port_id - 1] = enable;
	priv->port_old_rx_flowctrl[port_id - 1] = enable;

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t * enable)
{
	sw_error_t rv = SW_OK;
	a_bool_t txfc_enable, rxfc_enable;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);

	rv = adpt_mp_port_txfc_status_get(dev_id, port_id,  &txfc_enable);
	SW_RTN_ON_ERROR(rv);
	rv = adpt_mp_port_rxfc_status_get(dev_id, port_id,  &rxfc_enable);
	SW_RTN_ON_ERROR(rv);

	*enable = txfc_enable & rxfc_enable;

	return rv;
}
#endif

static sw_error_t
adpt_mp_port_flowctrl_forcemode_set(a_uint32_t dev_id,
	fal_port_t port_id, a_bool_t enable)
{
	sw_error_t rv = SW_OK;
	struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id);

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(priv);

	priv->port_tx_flowctrl_forcemode[port_id - 1] = enable;
	priv->port_rx_flowctrl_forcemode[port_id - 1] = enable;

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_flowctrl_forcemode_get(a_uint32_t dev_id,
	fal_port_t port_id, a_bool_t *enable)
{
	sw_error_t rv = SW_OK;
	struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id);


	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);
	ADPT_NULL_POINT_CHECK(priv);

	*enable = (priv->port_tx_flowctrl_forcemode[port_id - 1] &
		priv->port_rx_flowctrl_forcemode[port_id - 1]);

	return rv;
}
#endif

static sw_error_t
adpt_mp_port_mac_status_get(a_uint32_t dev_id, a_uint32_t port_id,
	struct port_phy_status *port_mac_status)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_configuration_u configuration;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(port_mac_status);

	memset(&configuration, 0, sizeof(configuration));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	if (configuration.bf.port_select == GMAC_SPEED_1000M) {
		port_mac_status->speed = FAL_SPEED_1000;
	} else {
		if (configuration.bf.mii_speed == GMAC_SPEED_100M) {
			port_mac_status->speed = FAL_SPEED_100;
		} else {
			port_mac_status->speed = FAL_SPEED_10;
		}
	}

	if (configuration.bf.duplex == GMAC_FULL_DUPLEX) {
		port_mac_status->duplex = FAL_FULL_DUPLEX;
	} else {
		port_mac_status->duplex = FAL_HALF_DUPLEX;
	}

	return rv;

}

static sw_error_t
adpt_mp_port_mac_speed_set(a_uint32_t dev_id, a_uint32_t port_id,
	fal_port_speed_t speed)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_configuration_u configuration;
	a_bool_t force_port;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	memset(&configuration, 0, sizeof(configuration));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	if ((FAL_SPEED_1000 == speed) || (FAL_SPEED_2500 == speed)) {
		 configuration.bf.port_select = GMAC_SPEED_1000M;
	} else if (FAL_SPEED_100 == speed) {
		configuration.bf.port_select = (~GMAC_SPEED_1000M) & 0x1;
		configuration.bf.mii_speed = GMAC_SPEED_100M;
	} else if (FAL_SPEED_10== speed) {
		configuration.bf.port_select = (~GMAC_SPEED_1000M) & 0x1;
		configuration.bf.mii_speed = GMAC_SPEED_10M;
	}

	rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	force_port = ssdk_port_feature_get(dev_id, port_id, PHY_F_FORCE);
	/* enable force port configuration */
	if (force_port == A_TRUE) {
		rv = _adpt_mp_port_gcc_speed_clock_set(dev_id,
			port_id, speed);
		SW_RTN_ON_ERROR(rv);
		rv = adpt_mp_gcc_uniphy_port_clock_set(dev_id,
			port_id, A_TRUE);
		SW_RTN_ON_ERROR(rv);
		rv = _adpt_mp_gcc_mac_clock_set(dev_id,
			port_id, A_TRUE);
		SW_RTN_ON_ERROR(rv);
		rv = adpt_mp_port_reset_set(dev_id, port_id);
		SW_RTN_ON_ERROR(rv);
	}
	return rv;

}

static sw_error_t
adpt_mp_port_mac_duplex_set(a_uint32_t dev_id, a_uint32_t port_id,
	fal_port_duplex_t duplex)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_configuration_u configuration;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	memset(&configuration, 0, sizeof(configuration));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	if (FAL_FULL_DUPLEX == duplex) {
		configuration.bf.duplex = GMAC_FULL_DUPLEX;
	} else {
		configuration.bf.duplex = GMAC_HALF_DUPLEX;
	}

	rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration);

	return rv;
}

static sw_error_t
adpt_mp_port_promisc_mode_set(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_frame_filter_u mac_frame_filter;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	memset(&mac_frame_filter, 0, sizeof(mac_frame_filter));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_frame_filter_get(dev_id, gmac_id, &mac_frame_filter);
	SW_RTN_ON_ERROR(rv);

	mac_frame_filter.bf.promiscuous_mode = enable;

	rv = mp_mac_frame_filter_set(dev_id, gmac_id, &mac_frame_filter);

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_promisc_mode_get(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t *enable)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_frame_filter_u mac_frame_filter;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);

	memset(&mac_frame_filter, 0, sizeof(mac_frame_filter));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_frame_filter_get(dev_id, gmac_id, &mac_frame_filter);
	SW_RTN_ON_ERROR(rv);

	*enable = mac_frame_filter.bf.promiscuous_mode;

	return rv;
}
#endif

static sw_error_t
adpt_mp_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id,
	a_uint32_t max_frame)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_max_frame_ctrl_u mac_max_frame_ctrl;
	union mac_configuration_u configuration;
	union mac_operation_mode_ctrl_u mac_operation_mode_ctrl;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	if (max_frame > PORT_MAX_FRAME_SIZE - 8) {
		return SW_OUT_OF_RANGE;
	}

	memset(&configuration, 0, sizeof(configuration));
	memset(&mac_max_frame_ctrl, 0, sizeof(mac_max_frame_ctrl));
	memset(&mac_operation_mode_ctrl, 0, sizeof(mac_operation_mode_ctrl));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_max_frame_ctrl_get(dev_id, gmac_id, &mac_max_frame_ctrl);
	SW_RTN_ON_ERROR(rv);
	rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	configuration.bf.jabber_disable = GMAC_JD_ENABLE;
	configuration.bf.watchdog_disable = GMAC_WD_DISABLE;
	configuration.bf.jumbo_frame_enable = GMAC_JUMBO_FRAME_ENABLE;
	configuration.bf.frame_burst_enable = GMAC_FRAME_BURST_ENABLE;
	rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration);
	SW_RTN_ON_ERROR(rv);

	mac_max_frame_ctrl.bf.max_frame_ctrl_enable = GMAC_MAX_FRAME_CTRL_ENABLE;
	/* default max_frame 1518 byte doesn't include vlan tag */
	mac_max_frame_ctrl.bf.max_frame_ctrl = max_frame + 8;
	rv = mp_mac_max_frame_ctrl_set(dev_id, gmac_id, &mac_max_frame_ctrl);

	rv = mp_mac_operation_mode_ctrl_get(dev_id, gmac_id,
			&mac_operation_mode_ctrl);
	mac_operation_mode_ctrl.bf.receive_store_and_foward =
		GMAC_RX_STORE_FORWAD_ENABLE;
	mac_operation_mode_ctrl.bf.transmit_store_and_foward =
		GMAC_TX_STORE_FORWAD_ENABLE;
	mac_operation_mode_ctrl.bf.forward_error_frame =
		GMAC_FORWARD_ERROR_FRAME_DISABLE;
	mac_operation_mode_ctrl.bf.drop_gaint_frame =
		GMAC_DROP_GAINT_FRAME_DISABLE;
	rv = mp_mac_operation_mode_ctrl_set(dev_id, gmac_id,
			&mac_operation_mode_ctrl);

	return rv;
}

static sw_error_t
adpt_mp_port_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id,
	a_uint32_t *max_frame)
{
	sw_error_t rv = SW_OK;
	a_uint32_t gmac_id = 0;
	union mac_max_frame_ctrl_u mac_max_frame_ctrl;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(max_frame);

	memset(&mac_max_frame_ctrl, 0, sizeof(mac_max_frame_ctrl));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_max_frame_ctrl_get(dev_id, gmac_id, &mac_max_frame_ctrl);
	SW_RTN_ON_ERROR(rv);

	*max_frame = mac_max_frame_ctrl.bf.max_frame_ctrl;

	return rv;
}

static sw_error_t
adpt_mp_port_mac_eee_enable_set(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t enable)
{
	sw_error_t rv = 0;
	a_uint32_t gmac_id = 0;
	union mac_lpi_ctrl_status_u mac_lpi_ctrl_status;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status);
	SW_RTN_ON_ERROR(rv);
	mac_lpi_ctrl_status.bf.lpi_enable = enable;

	rv = mp_mac_lpi_ctrl_status_set(dev_id, gmac_id, &mac_lpi_ctrl_status);

	return rv;
}

#ifndef IN_PORTCONTROL_MINI
static sw_error_t
adpt_mp_port_mac_eee_enable_get(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t *enable)
{
	sw_error_t rv = 0;
	a_uint32_t gmac_id = 0;
	union mac_lpi_ctrl_status_u mac_lpi_ctrl_status;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(enable);

	memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status);
	SW_RTN_ON_ERROR(rv);

	*enable = mac_lpi_ctrl_status.bf.lpi_enable;

	return rv;

}
#endif

static sw_error_t
adpt_mp_port_interface_eee_cfg_set(a_uint32_t dev_id, fal_port_t port_id,
	fal_port_eee_cfg_t *port_eee_cfg)
{
	sw_error_t rv = 0;
	union mac_lpi_timer_ctrl_u mac_lpi_timer_ctrl;
	union mac_lpi_ctrl_status_u mac_lpi_ctrl_status;

	a_uint32_t phy_addr = 0, gmac_id = 0;
	a_uint32_t adv;
	hsl_phy_ops_t *phy_drv;
	struct qca_phy_priv *priv;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);

	memset(&mac_lpi_timer_ctrl, 0, sizeof(mac_lpi_timer_ctrl));
	memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	priv = ssdk_phy_priv_data_get(dev_id);
	SW_RTN_ON_NULL(priv);

	if (port_eee_cfg->enable) {
		adv = port_eee_cfg->advertisement;
	} else {
		adv = 0;
	}

	if (port_eee_cfg->lpi_tx_enable) {
		port_lpi_status[dev_id] |= BIT(port_id-1);
	} else {
		port_lpi_status[dev_id] &= ~BIT(port_id-1);
	}

	SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get(dev_id, port_id));
	if (NULL == phy_drv->phy_eee_adv_set) {
		return SW_NOT_SUPPORTED;
	}

	rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_addr);
	SW_RTN_ON_ERROR (rv);

	rv = phy_drv->phy_eee_adv_set(dev_id, phy_addr, adv);
	SW_RTN_ON_ERROR (rv);

	rv = mp_mac_lpi_timer_ctrl_get(dev_id, gmac_id, &mac_lpi_timer_ctrl);
	SW_RTN_ON_ERROR (rv);
	mac_lpi_timer_ctrl.bf.lpi_tw_timer = port_eee_cfg->lpi_wakeup_timer;
	rv = mp_mac_lpi_timer_ctrl_set(dev_id, gmac_id, &mac_lpi_timer_ctrl);
	SW_RTN_ON_ERROR (rv);

	rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status);
	SW_RTN_ON_ERROR (rv);
	mac_lpi_ctrl_status.bf.lpi_tx_auto_enable = GMAC_LPI_AUTO_MODE;
	mac_lpi_ctrl_status.bf.link_status = GMAC_LPI_LINK_UP;
	mac_lpi_ctrl_status.bf.lpi_enable = port_eee_cfg->lpi_tx_enable;
	rv = mp_mac_lpi_ctrl_status_set(dev_id, gmac_id, &mac_lpi_ctrl_status);
	SW_RTN_ON_ERROR (rv);

	if (port_lpi_status[dev_id] & PORT_LPI_ENABLE_STATUS) {
		if (!(port_lpi_status[dev_id] & PORT_LPI_TASK_RUNNING)) {
			if (!(port_lpi_status[dev_id] & PORT_LPI_TASK_START)) {
				qca_mac_sw_sync_work_start(priv);
				port_lpi_status[dev_id] |= PORT_LPI_TASK_START;
			} else {
				qca_mac_sw_sync_work_resume(priv);
			}
			port_lpi_status[dev_id] |= PORT_LPI_TASK_RUNNING;
		}
	} else {
		qca_mac_sw_sync_work_stop(priv);
		port_lpi_status[dev_id] &= ~PORT_LPI_TASK_RUNNING;
	}

	return rv;
}
static sw_error_t
adpt_mp_port_interface_eee_cfg_get(a_uint32_t dev_id, fal_port_t port_id,
	fal_port_eee_cfg_t *port_eee_cfg)
{
	sw_error_t rv = 0;
	union mac_lpi_timer_ctrl_u mac_lpi_timer_ctrl;
	union mac_lpi_ctrl_status_u mac_lpi_ctrl_status;
	a_uint32_t phy_addr = 0, gmac_id = 0;
	a_uint32_t adv, lp_adv, cap, status;
	hsl_phy_ops_t *phy_drv;

	ADPT_DEV_ID_CHECK(dev_id);
	MP_PORT_ID_CHECK(port_id);
	ADPT_NULL_POINT_CHECK(port_eee_cfg);

	memset(&mac_lpi_timer_ctrl, 0, sizeof(mac_lpi_timer_ctrl));
	memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status));
	memset(port_eee_cfg, 0, sizeof(*port_eee_cfg));
	gmac_id = MP_PORT_TO_GMAC_ID(port_id);

	SW_RTN_ON_NULL(phy_drv =hsl_phy_api_ops_get (dev_id, port_id));
	if ((NULL == phy_drv->phy_eee_adv_get) ||
		(NULL == phy_drv->phy_eee_partner_adv_get) ||
		(NULL == phy_drv->phy_eee_cap_get) ||
		(NULL == phy_drv->phy_eee_status_get)) {
		return SW_NOT_SUPPORTED;
	}
	rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_addr);
	SW_RTN_ON_ERROR (rv);
	rv = phy_drv->phy_eee_adv_get(dev_id, phy_addr, &adv);
	SW_RTN_ON_ERROR (rv);
	port_eee_cfg->advertisement = adv;
	rv = phy_drv->phy_eee_partner_adv_get(dev_id, phy_addr, &lp_adv);
	SW_RTN_ON_ERROR (rv);
	port_eee_cfg->link_partner_advertisement = lp_adv;
	rv = phy_drv->phy_eee_cap_get(dev_id, phy_addr, &cap);
	SW_RTN_ON_ERROR (rv);
	port_eee_cfg->capability = cap;
	rv = phy_drv->phy_eee_status_get(dev_id, phy_addr, &status);
	SW_RTN_ON_ERROR (rv);
	port_eee_cfg->eee_status = status;

	if (port_eee_cfg->advertisement) {
		port_eee_cfg->enable = A_TRUE;
	} else {
		port_eee_cfg->enable = A_FALSE;
	}
	rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status);
	SW_RTN_ON_ERROR (rv);
	port_eee_cfg->lpi_tx_enable = mac_lpi_ctrl_status.bf.lpi_enable;

	rv = mp_mac_lpi_timer_ctrl_get(dev_id, gmac_id, &mac_lpi_timer_ctrl);
	SW_RTN_ON_ERROR (rv);
	port_eee_cfg->lpi_wakeup_timer = mac_lpi_timer_ctrl.bf.lpi_tw_timer;

	return rv;
}

static sw_error_t
adpt_mp_port_interface_mode_status_get(a_uint32_t dev_id,
	a_uint32_t port_id, fal_port_interface_mode_t * mode)
{
	sw_error_t rv = SW_OK;
	a_uint32_t phy_id = 0;
	hsl_phy_ops_t *phy_drv;

	ADPT_DEV_ID_CHECK(dev_id);
	ADPT_NULL_POINT_CHECK(mode);

	SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get(dev_id, port_id));
	SW_RTN_ON_NULL(phy_drv->phy_interface_mode_status_get);

	rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id);
	SW_RTN_ON_ERROR (rv);

	rv = phy_drv->phy_interface_mode_status_get(dev_id, phy_id,mode);

	return rv;
}

static sw_error_t
adpt_mp_port_interface_mode_switch(a_uint32_t dev_id, a_uint32_t port_id)
{
	sw_error_t rv = SW_OK;
	fal_port_interface_mode_t port_mode_new = PORT_INTERFACE_MODE_MAX;
	a_uint32_t uniphy_mode_old = PORT_WRAPPER_MAX;
	a_uint32_t uniphy_mode_new = PORT_WRAPPER_MAX;
	a_bool_t force_port;

	force_port = ssdk_port_feature_get(dev_id, port_id, PHY_F_FORCE);
	if ((port_id == SSDK_PHYSICAL_PORT1) || (force_port == A_TRUE)) {
		return SW_OK;
	}
	rv = adpt_mp_port_interface_mode_status_get(dev_id,
		port_id, &port_mode_new);
	SW_RTN_ON_ERROR(rv);

	if (port_mode_new == PHY_SGMII_BASET) {
		uniphy_mode_new = PORT_WRAPPER_SGMII_CHANNEL0;
	} else if (port_mode_new == PORT_SGMII_PLUS) {
		uniphy_mode_new = PORT_WRAPPER_SGMII_PLUS;
	} else {
		return SW_NOT_SUPPORTED;
	}
	uniphy_mode_old = ssdk_dt_global_get_mac_mode(dev_id,
		SSDK_UNIPHY_INSTANCE0);
	if (uniphy_mode_new != uniphy_mode_old) {
		rv = adpt_mp_uniphy_mode_configure(dev_id,
			SSDK_UNIPHY_INSTANCE0, uniphy_mode_new);
		SW_RTN_ON_ERROR(rv);
		ssdk_dt_global_set_mac_mode(dev_id,
			SSDK_UNIPHY_INSTANCE0, uniphy_mode_new);
	}

	return rv;
}

static sw_error_t
_adpt_mp_port_phy_status_get(a_uint32_t dev_id, a_uint32_t port_id,
	struct port_phy_status *phy_status)
{
	sw_error_t rv = 0;
	a_uint32_t phy_addr;
	hsl_phy_ops_t *phy_drv;

	ADPT_DEV_ID_CHECK(dev_id);
	ADPT_NULL_POINT_CHECK(phy_status);

	SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id));
	SW_RTN_ON_NULL (phy_drv->phy_get_status);

	rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_addr);
	SW_RTN_ON_ERROR (rv);
	rv = phy_drv->phy_get_status (dev_id, phy_addr, phy_status);
	SW_RTN_ON_ERROR (rv);

	return rv;
}

static sw_error_t
_adpt_mp_port_link_down_update(struct qca_phy_priv *priv,
	a_uint32_t port_id)
{
	sw_error_t rv = 0;

	/* disable rx mac, gcc uniphy port and gcc mac port status */
	rv = adpt_mp_port_rxmac_status_set(priv->device_id, port_id, A_FALSE);
	SW_RTN_ON_ERROR (rv);
	rv = adpt_mp_gcc_uniphy_port_clock_set(priv->device_id, port_id, A_FALSE);
	SW_RTN_ON_ERROR (rv);
	_adpt_mp_gcc_mac_clock_set(priv->device_id, port_id, A_FALSE);
	SW_RTN_ON_ERROR (rv);

	/* switch interface mode if necessary under link down*/
	rv = adpt_mp_port_interface_mode_switch(priv->device_id, port_id);
	SW_RTN_ON_ERROR (rv);
	SSDK_DEBUG("MP port %d interface mode switch under link down!\n",
			port_id);
	return rv;
}

static a_bool_t
_adpt_mp_port_status_change(struct qca_phy_priv *priv, a_uint32_t port_id,
	struct port_phy_status phy_status)
{
	if ((a_uint32_t)phy_status.speed != priv->port_old_speed[port_id - 1])
		return A_TRUE;
	if ((a_uint32_t)phy_status.duplex != priv->port_old_duplex[port_id - 1])
		return A_TRUE;
	if (phy_status.tx_flowctrl != priv->port_old_tx_flowctrl[port_id - 1])
		return A_TRUE;
	if (phy_status.rx_flowctrl != priv->port_old_rx_flowctrl[port_id - 1])
		return A_TRUE;
	return A_FALSE;
}

sw_error_t
adpt_mp_port_link_up_change_update(struct qca_phy_priv *priv,
	a_uint32_t port_id, struct port_phy_status phy_status)
{
	sw_error_t rv = 0;

	if ((a_uint32_t)phy_status.speed !=
		priv->port_old_speed[port_id - 1]) {

		/* configure gcc speed clock frequency */
		rv = _adpt_mp_port_gcc_speed_clock_set(priv->device_id,
			port_id, phy_status.speed);
		SW_RTN_ON_ERROR (rv);

		/* config mac speed */
		rv = adpt_mp_port_mac_speed_set(priv->device_id,
			port_id, phy_status.speed);
		SW_RTN_ON_ERROR (rv);

		priv->port_old_speed[port_id - 1] =
			(a_uint32_t)phy_status.speed;

		SSDK_DEBUG("Port %d up and speed is %d\n", port_id,
			priv->port_old_speed[port_id - 1]);
	}
	/* link up duplex change configuration */
	if ((a_uint32_t)phy_status.duplex !=
		priv->port_old_duplex[port_id - 1]) {

		rv = adpt_mp_port_mac_duplex_set(priv->device_id,
			port_id, phy_status.duplex);

		priv->port_old_duplex[port_id - 1] =
			(a_uint32_t)phy_status.duplex;
		SW_RTN_ON_ERROR (rv);

		SSDK_DEBUG("Port %d up and duplex is %d\n", port_id,
			priv->port_old_duplex[port_id - 1]);
	}
	/* tx flowctrl configuration*/
	if (priv->port_tx_flowctrl_forcemode[port_id - 1] != A_TRUE) {
		if (phy_status.duplex == FAL_HALF_DUPLEX) {
			phy_status.tx_flowctrl = A_TRUE;
		}
		if (phy_status.tx_flowctrl !=
			priv->port_old_tx_flowctrl[port_id - 1]) {
			rv = adpt_mp_port_txfc_status_set(priv->device_id,
				port_id, phy_status.tx_flowctrl);
			SW_RTN_ON_ERROR (rv);
			priv->port_old_tx_flowctrl[port_id - 1] =
				phy_status.tx_flowctrl;

			SSDK_DEBUG("Port %d up and tx flowctrl is %d\n",
				port_id,
				priv->port_old_tx_flowctrl[port_id - 1]);
		}
	}
	/*rx flowctrl configuration*/
	if (priv->port_rx_flowctrl_forcemode[port_id - 1] != A_TRUE) {
		if (phy_status.duplex == FAL_HALF_DUPLEX) {
			phy_status.rx_flowctrl = A_TRUE;
		}
		if (phy_status.rx_flowctrl !=
			priv->port_old_rx_flowctrl[port_id - 1]) {
			rv = adpt_mp_port_rxfc_status_set(priv->device_id,
				port_id, phy_status.rx_flowctrl);
			SW_RTN_ON_ERROR (rv);
			priv->port_old_rx_flowctrl[port_id - 1] =
				phy_status.rx_flowctrl;

			SSDK_DEBUG("Port %d up and rx flowctrl is %d\n",
				port_id,
				priv->port_old_rx_flowctrl[port_id-1]);
		}
	}

	return rv;
}

sw_error_t
adpt_mp_port_link_up_update(struct qca_phy_priv *priv,
	a_uint32_t port_id, struct port_phy_status phy_status)
{
	sw_error_t rv = 0;
	a_bool_t change;

	/* port phy status change check*/
	change = _adpt_mp_port_status_change(priv, port_id,
			phy_status);

	rv = adpt_mp_port_txmac_status_set(priv->device_id, port_id,
				A_FALSE);
	SW_RTN_ON_ERROR (rv);

	/* switch interface mode if necessary under link up */
	rv = adpt_mp_port_interface_mode_switch(priv->device_id, port_id);
	SW_RTN_ON_ERROR (rv);
	SSDK_DEBUG("MP port %d interface mode switch under link up!\n",
			port_id);
	/* link up status change*/
	if (change == A_TRUE) {
		rv = adpt_mp_port_link_up_change_update(priv,
			port_id, phy_status);
		SW_RTN_ON_ERROR (rv);
	}

	rv = adpt_mp_gcc_uniphy_port_clock_set(priv->device_id,
			port_id, A_TRUE);
	SW_RTN_ON_ERROR (rv);
	rv =_adpt_mp_gcc_mac_clock_set(priv->device_id,
			port_id, A_TRUE);
	SW_RTN_ON_ERROR (rv);

	msleep(50);

	rv = adpt_mp_port_reset_set(priv->device_id, port_id);
	SW_RTN_ON_ERROR (rv);
	rv = adpt_mp_port_txmac_status_set(priv->device_id,
			port_id, A_TRUE);
	SW_RTN_ON_ERROR (rv);
	rv = adpt_mp_port_rxmac_status_set(priv->device_id,
		port_id, A_TRUE);
	SW_RTN_ON_ERROR (rv);

	return rv;
}

sw_error_t
adpt_mp_port_netdev_change_notify(struct qca_phy_priv *priv,
	a_uint32_t port_id)
{
	sw_error_t rv = 0;
	struct port_phy_status phy_status = {0};
	a_uint32_t portbmp[SW_MAX_NR_DEV] = {0};

	portbmp[priv->device_id] = qca_ssdk_port_bmp_get(priv->device_id);

	if(!(portbmp[priv->device_id] & (0x1 << port_id))) {
		SSDK_ERROR("netdev change notify with incorrect port %d\n",
			port_id);
		return SW_BAD_VALUE;
	}

	rv = _adpt_mp_port_phy_status_get(priv->device_id, port_id,
		&phy_status);
	if (rv != SW_OK) {
		SSDK_ERROR("failed to get port %d status return value is %d\n",
			port_id, rv);
		return rv;
	}
	/* link status from up to down*/
	if ((phy_status.link_status == PORT_LINK_DOWN) &&
		(priv->port_old_link[port_id - 1] == PORT_LINK_UP)) {
		SSDK_DEBUG("MP port %d change to link down status\n", port_id);
		/* link down configuration*/
		rv = _adpt_mp_port_link_down_update(priv, port_id);
		SW_RTN_ON_ERROR (rv);
		priv->port_old_link[port_id - 1] = phy_status.link_status ;
	}
	/* link status from down to up */
	if ((phy_status.link_status == PORT_LINK_UP) &&
		(priv->port_old_link[port_id - 1] == PORT_LINK_DOWN)) {
		SSDK_DEBUG("Port %d change to link up status\n", port_id);
		rv = adpt_mp_port_link_up_update(priv, port_id, phy_status);
		SW_RTN_ON_ERROR (rv);
		priv->port_old_link[port_id - 1] = phy_status.link_status;
	}
	SSDK_DEBUG("MP port %d link is %d speed is %d duplex is %d"
		" tx_flowctrl is %d rx_flowctrl is %d\n",
	port_id, priv->port_old_link[port_id - 1],
	priv->port_old_speed[port_id - 1],
	priv->port_old_duplex[port_id - 1],
	priv->port_old_tx_flowctrl[port_id - 1],
	priv->port_old_rx_flowctrl[port_id - 1]);

	return rv;
}

static sw_error_t
adpt_mp_port_lpi_polling_task(struct qca_phy_priv *priv)
{
	a_uint32_t port_id;
	a_uint32_t portbmp[SW_MAX_NR_DEV] = {0};
	sw_error_t rv = SW_OK;

	portbmp[priv->device_id] = qca_ssdk_port_bmp_get(priv->device_id);

	for (port_id = SSDK_PHYSICAL_PORT1; port_id < SW_MAX_NR_PORT; port_id ++) {

		if(!(portbmp[priv->device_id] & BIT(port_id)))
			continue;
		if (port_lpi_status[priv->device_id] & BIT(port_id-1)) {
			rv = adpt_mp_port_mac_eee_enable_set(priv->device_id,
				port_id, A_TRUE);
			SW_RTN_ON_ERROR(rv);
		}
	}
	return SW_OK;
}

static sw_error_t
adpt_mp_port_speed_get(a_uint32_t dev_id, fal_port_t port_id,
	fal_port_speed_t * pspeed)
{
	sw_error_t rv = 0;
	a_uint32_t phy_id = 0;
	hsl_phy_ops_t *phy_drv;
	struct port_phy_status port_mac_status = {0};

	ADPT_DEV_ID_CHECK(dev_id);
	ADPT_NULL_POINT_CHECK(pspeed);

	if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) {
		return SW_BAD_PARAM;
	}

	/* for those ports without PHY device should be s17c port */
	if (A_FALSE == _adpt_mp_port_phy_connected (dev_id, port_id)) {
		rv = adpt_mp_port_mac_status_get(dev_id, port_id, &port_mac_status);
		SW_RTN_ON_ERROR (rv);
		*pspeed= port_mac_status.speed;
	} else {
		SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id,
				port_id));
		if (NULL == phy_drv->phy_speed_get) {
			return SW_NOT_SUPPORTED;
		}

		rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
		SW_RTN_ON_ERROR (rv);
		rv = phy_drv->phy_speed_get (dev_id, phy_id, pspeed);
		SW_RTN_ON_ERROR (rv);
	}

	return rv;
}

static sw_error_t
adpt_mp_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id,
	fal_port_duplex_t * pduplex)
{
	sw_error_t rv = 0;
	a_uint32_t phy_id = 0;
	hsl_phy_ops_t *phy_drv;
	struct port_phy_status port_mac_status = {0};

	ADPT_DEV_ID_CHECK(dev_id);
	ADPT_NULL_POINT_CHECK(pduplex);

	if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) {
		return SW_BAD_PARAM;
	}

	/* for those ports without PHY device should be s17c port */
	if (A_FALSE == _adpt_mp_port_phy_connected (dev_id, port_id)) {
		rv = adpt_mp_port_mac_status_get(dev_id, port_id, &port_mac_status);
		SW_RTN_ON_ERROR (rv);
		*pduplex = port_mac_status.duplex;
	} else {
		SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id,
				port_id));
		if (NULL == phy_drv->phy_duplex_get) {
			return SW_NOT_SUPPORTED;
		}

		rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
		SW_RTN_ON_ERROR (rv);
		rv = phy_drv->phy_duplex_get (dev_id, phy_id, pduplex);
		SW_RTN_ON_ERROR (rv);
	}

	return rv;
}

static sw_error_t
adpt_mp_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id,
	a_bool_t * status)
{
	sw_error_t rv = 0;
	a_uint32_t phy_id = 0;
	hsl_phy_ops_t *phy_drv;

	ADPT_DEV_ID_CHECK(dev_id);
	ADPT_NULL_POINT_CHECK(status);

	if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) {
		return SW_BAD_PARAM;
	}

	/* for those ports without PHY device should be s17c port */
	if (A_FALSE == _adpt_mp_port_phy_connected (dev_id, port_id)) {
		*status = A_TRUE;
	} else {
		SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id,
				port_id));
		if (NULL == phy_drv->phy_link_status_get) {
			return SW_NOT_SUPPORTED;
		}

		rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id);
		SW_RTN_ON_ERROR (rv);

		*status = phy_drv->phy_link_status_get (dev_id, phy_id);
	}

	return SW_OK;

}

sw_error_t 
adpt_mp_portctrl_init(a_uint32_t dev_id)
{
	adpt_api_t *p_adpt_api = NULL;

	p_adpt_api = adpt_api_ptr_get(dev_id);

	if(p_adpt_api == NULL)
	{
		return SW_FAIL;
	}
#ifndef IN_PORTCONTROL_MINI
	p_adpt_api->adpt_port_txmac_status_get = adpt_mp_port_txmac_status_get;
	p_adpt_api->adpt_port_rxmac_status_get = adpt_mp_port_rxmac_status_get;
	p_adpt_api->adpt_port_rxfc_status_get = adpt_mp_port_rxfc_status_get;
	p_adpt_api->adpt_port_txfc_status_get = adpt_mp_port_txfc_status_get;
	p_adpt_api->adpt_port_flowctrl_get = adpt_mp_port_flowctrl_get;
	p_adpt_api->adpt_port_flowctrl_forcemode_get =
		adpt_mp_port_flowctrl_forcemode_get;
	p_adpt_api->adpt_port_promisc_mode_get = adpt_mp_port_promisc_mode_get;
	p_adpt_api->adpt_port_interface_3az_status_get = adpt_mp_port_mac_eee_enable_get;
#endif
	p_adpt_api->adpt_port_txmac_status_set = adpt_mp_port_txmac_status_set;
	p_adpt_api->adpt_port_rxmac_status_set = adpt_mp_port_rxmac_status_set;
	p_adpt_api->adpt_port_rxfc_status_set = adpt_mp_port_rxfc_status_set;
	p_adpt_api->adpt_port_txfc_status_set = adpt_mp_port_txfc_status_set;
	p_adpt_api->adpt_port_flowctrl_set = adpt_mp_port_flowctrl_set;
	p_adpt_api->adpt_port_flowctrl_forcemode_set =
		adpt_mp_port_flowctrl_forcemode_set;
	p_adpt_api->adpt_port_max_frame_size_set = adpt_mp_port_max_frame_size_set;
	p_adpt_api->adpt_port_max_frame_size_get = adpt_mp_port_max_frame_size_get;
	p_adpt_api->adpt_port_promisc_mode_set = adpt_mp_port_promisc_mode_set;
	p_adpt_api->adpt_port_mac_speed_set = adpt_mp_port_mac_speed_set;
	p_adpt_api->adpt_port_speed_get = adpt_mp_port_speed_get;
	p_adpt_api->adpt_port_mac_duplex_set = adpt_mp_port_mac_duplex_set;
	p_adpt_api->adpt_port_duplex_get = adpt_mp_port_duplex_get;
	p_adpt_api->adpt_port_link_status_get = adpt_mp_port_link_status_get;
	p_adpt_api->adpt_port_interface_3az_status_set = adpt_mp_port_mac_eee_enable_set;
	p_adpt_api->adpt_port_interface_eee_cfg_set = adpt_mp_port_interface_eee_cfg_set;
	p_adpt_api->adpt_port_interface_eee_cfg_get = adpt_mp_port_interface_eee_cfg_get;
	p_adpt_api->adpt_port_netdev_notify_set = adpt_mp_port_netdev_change_notify;
	p_adpt_api->adpt_port_polling_sw_sync_set = adpt_mp_port_lpi_polling_task;

	return SW_OK;
}
/**
 * @}
 */
