#include "lm5710.h"
#include "lm_dcbx_mp.h"
#define MAX_NUM_OF_ACTIVE_ETH_CONS_PER_COS(_pdev) LM_SB_CNT(_pdev)
#define ETH_CHAIN_COS0_START_OFFSET(_pdev) (0)
#define ETH_CHAIN_COS1_START_OFFSET(_pdev) (ETH_CHAIN_COS0_START_OFFSET(_pdev) + LM_SB_CNT(_pdev) + MAX_NON_RSS_CHAINS)
#define ETH_CHAIN_COS2_START_OFFSET(_pdev) (ETH_CHAIN_COS1_START_OFFSET(_pdev) + LM_SB_CNT(_pdev))
#define ETH_IS_CHAIN_IN_COS0_RANGE(_pdev, _chain) ( lm_mp_eth_is_chain_in_cosx_range(_pdev, _chain, ETH_CHAIN_COS0_START_OFFSET(_pdev)))
#define ETH_IS_CHAIN_IN_COS1_RANGE(_pdev, _chain) ( lm_mp_eth_is_chain_in_cosx_range(_pdev, _chain, ETH_CHAIN_COS1_START_OFFSET(_pdev)))
#define ETH_IS_CHAIN_IN_COS2_RANGE(_pdev, _chain) ( lm_mp_eth_is_chain_in_cosx_range(_pdev, _chain, ETH_CHAIN_COS2_START_OFFSET(_pdev)))
#define ETH_CID_COSX_END_OFFSET(_pdev, _val) (_val + MAX_NUM_OF_ACTIVE_ETH_CONS_PER_COS(pdev))
STATIC u8_t
lm_mp_eth_is_chain_in_cosx_range(
IN lm_device_t *pdev,
IN const u32_t chain,
IN const u32_t cos_start_offset)
{
if((cos_start_offset <= chain) &&
(chain < ETH_CID_COSX_END_OFFSET(pdev, cos_start_offset)))
{
return TRUE;
}
else
{
return FALSE;
}
}
u8_t
lm_mp_cos_from_chain(IN struct _lm_device_t *pdev,
IN const u32_t chain)
{
u8_t cos = ETH_MP_MAX_COS_SUPPORTED;
if (ETH_IS_CHAIN_IN_COS0_RANGE(pdev, chain) )
{
cos = 0;
}
else if (ETH_IS_CHAIN_IN_COS1_RANGE(pdev, chain) )
{
cos = 1;
}
else if (ETH_IS_CHAIN_IN_COS2_RANGE(pdev, chain) )
{
cos = 2;
}
else
{
DbgMessage(pdev, INFORMi|INFORMl2sp, " lm_mp_cos_from_chain: ");
}
return cos;
}
lm_chain_type_t
lm_mp_get_chain_type(IN struct _lm_device_t *pdev,
IN const u32_t chain)
{
const u8_t cos = lm_mp_cos_from_chain(pdev, chain);
if (0 == cos)
{
return lm_chain_type_cos_reg;
}
else if (cos < ETH_MP_MAX_COS_SUPPORTED)
{
return lm_chain_type_cos_tx_only;
}
else
{
return lm_chain_type_not_cos;
}
}
STATIC u8_t
lm_mp_get_eth_chain_cosx_start_offset(IN struct _lm_device_t *pdev,
IN const u8_t cos)
{
u8_t cosx_start_offset = 0;
switch(cos)
{
case 0:
cosx_start_offset = ETH_CHAIN_COS0_START_OFFSET(pdev);
break;
case 1:
cosx_start_offset = ETH_CHAIN_COS1_START_OFFSET(pdev);
break;
case 2:
cosx_start_offset = ETH_CHAIN_COS2_START_OFFSET(pdev);
break;
default:
DbgBreakMsg("invalid cos");
cosx_start_offset = ETH_CHAIN_COS0_START_OFFSET(pdev);
}
return cosx_start_offset;
}
u32_t
lm_mp_get_reg_chain_from_chain(IN struct _lm_device_t *pdev,
IN u32_t chain)
{
const u8_t cos = lm_mp_cos_from_chain(pdev, chain);
u8_t cosx_start_offset = 0;
if( cos >= ETH_MP_MAX_COS_SUPPORTED)
{
return chain;
}
cosx_start_offset =
lm_mp_get_eth_chain_cosx_start_offset(pdev,cos);
chain -= cosx_start_offset;
return chain;
}
u8_t
lm_mp_get_cos_chain_from_reg_chain(
IN struct _lm_device_t *pdev,
INOUT u8_t chain,
INOUT const u8_t cos)
{
u8_t cosx_start_offset = 0;
if( cos >= ETH_MP_MAX_COS_SUPPORTED)
{
return chain;
}
cosx_start_offset =
lm_mp_get_eth_chain_cosx_start_offset(pdev,cos);
chain += cosx_start_offset;
return chain;
}
u8_t
lm_mp_max_cos_chain_used(
IN struct _lm_device_t *pdev)
{
const u8_t max_num_cos = lm_dcbx_cos_max_num(pdev);
const u8_t cosx_start_offset =
lm_mp_get_eth_chain_cosx_start_offset(pdev, max_num_cos -1);
const u8_t max_chain_used = ETH_CID_COSX_END_OFFSET(pdev, cosx_start_offset);
DbgBreakIf(FALSE == MM_DCB_MP_L2_IS_ENABLE(pdev));
DbgBreakIf(1 == max_num_cos);
return max_chain_used;
}