Skip to content
Permalink
Browse files
net: dsa: add basic vlan functions
vlan-separation still does not work, all ports are mapped to eth0

i have now the following functions only with return 0:

- rtk_vlan_reset
- rtk_vlan_init
- rtk_vlan_portPvid_set
  • Loading branch information
frank-w committed Nov 14, 2021
1 parent e9ec03c commit eb3332b0b1280a1197e074de26e379a7fd5ae886
Show file tree
Hide file tree
Showing 2 changed files with 485 additions and 84 deletions.
@@ -614,6 +614,331 @@ static int rtl8367s_hw_reset(void)
return 0;
}

static void _rtl8367c_Vlan4kStUser2Smi(rtl8367c_user_vlan4kentry *pUserVlan4kEntry, rtk_uint16 *pSmiVlan4kEntry)
{
pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->mbr & 0x00FF);
pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->untag & 0x00FF) << 8;

pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->fid_msti & 0x000F);
pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpen & 0x0001) << 4;
pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpri & 0x0007) << 5;
pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->envlanpol & 0x0001) << 8;
pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->meteridx & 0x001F) << 9;
pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->ivl_svl & 0x0001) << 14;

pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->mbr & 0x0700) >> 8);
pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->untag & 0x0700) >> 8) << 3;
pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->meteridx & 0x0020) >> 5) << 6;
}

static void _rtl8367c_VlanMCStUser2Smi(rtl8367c_vlanconfiguser *pVlanCg, rtk_uint16 *pSmiVlanCfg)
{
pSmiVlanCfg[0] |= pVlanCg->mbr & 0x07FF;

pSmiVlanCfg[1] |= pVlanCg->fid_msti & 0x000F;

pSmiVlanCfg[2] |= pVlanCg->vbpen & 0x0001;
pSmiVlanCfg[2] |= (pVlanCg->vbpri & 0x0007) << 1;
pSmiVlanCfg[2] |= (pVlanCg->envlanpol & 0x0001) << 4;
pSmiVlanCfg[2] |= (pVlanCg->meteridx & 0x003F) << 5;

pSmiVlanCfg[3] |= pVlanCg->evid & 0x1FFF;
}

ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry )
{
rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN];
rtk_uint32 page_idx;
rtk_uint16 *tableAddr;
ret_t retVal;
rtk_uint32 regData;

if(pVlan4kEntry->vid > RTL8367C_VIDMAX)
return RT_ERR_VLAN_VID;

if(pVlan4kEntry->mbr > RTL8367C_PORTMASK)
return RT_ERR_PORT_MASK;

if(pVlan4kEntry->untag > RTL8367C_PORTMASK)
return RT_ERR_PORT_MASK;

if(pVlan4kEntry->fid_msti > RTL8367C_FIDMAX)
return RT_ERR_L2_FID;

if(pVlan4kEntry->meteridx > RTL8367C_METERMAX)
return RT_ERR_FILTER_METER_ID;

if(pVlan4kEntry->vbpri > RTL8367C_PRIMAX)
return RT_ERR_QOS_INT_PRIORITY;

memset(vlan_4k_entry, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_4KTABLE_LEN);
_rtl8367c_Vlan4kStUser2Smi(pVlan4kEntry, vlan_4k_entry);

/* Prepare Data */
tableAddr = vlan_4k_entry;
for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++)
{
regData = *tableAddr;
retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + page_idx, regData);
if(retVal != RT_ERR_OK)
return retVal;

tableAddr++;
}

/* Write Address (VLAN_ID) */
regData = pVlan4kEntry->vid;
retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData);
if(retVal != RT_ERR_OK)
return retVal;

/* Write Command */
retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_CVLAN));
if(retVal != RT_ERR_OK)
return retVal;

return RT_ERR_OK;
}

ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg)
{
ret_t retVal;
rtk_uint32 regAddr;
rtk_uint32 regData;
rtk_uint16 *tableAddr;
rtk_uint32 page_idx;
rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN];

/* Error Checking */
if(index > RTL8367C_CVIDXMAX)
return RT_ERR_VLAN_ENTRY_NOT_FOUND;

if(pVlanCg->evid > RTL8367C_EVIDMAX)
return RT_ERR_INPUT;


if(pVlanCg->mbr > RTL8367C_PORTMASK)
return RT_ERR_PORT_MASK;

if(pVlanCg->fid_msti > RTL8367C_FIDMAX)
return RT_ERR_L2_FID;

if(pVlanCg->meteridx > RTL8367C_METERMAX)
return RT_ERR_FILTER_METER_ID;

if(pVlanCg->vbpri > RTL8367C_PRIMAX)
return RT_ERR_QOS_INT_PRIORITY;

memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN);
_rtl8367c_VlanMCStUser2Smi(pVlanCg, smi_vlancfg);
tableAddr = smi_vlancfg;

for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */
{
regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx;
regData = *tableAddr;

retVal = rtl8367c_setAsicReg(regAddr, regData);
if(retVal != RT_ERR_OK)
return retVal;

tableAddr++;
}

return RT_ERR_OK;
}



rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg)
{
rtk_api_ret_t retVal;
rtk_uint32 phyMbrPmask;
rtk_uint32 phyUntagPmask;
rtl8367c_user_vlan4kentry vlan4K;
rtl8367c_vlanconfiguser vlanMC;
rtk_uint32 idx;
rtk_uint32 empty_index = 0xffff;
rtk_uint32 update_evid = 0;

/* Check initialization state */
RTK_CHK_INIT_STATE();

/* vid must be 0~8191 */
if (vid > RTL8367C_EVIDMAX)
return RT_ERR_VLAN_VID;

/* Null pointer check */
if(NULL == pVlanCfg)
return RT_ERR_NULL_POINTER;

/* Check port mask valid */
RTK_CHK_PORTMASK_VALID(&(pVlanCfg->mbr));

if (vid <= RTL8367C_VIDMAX)
{
/* Check untag port mask valid */
RTK_CHK_PORTMASK_VALID(&(pVlanCfg->untag));
}

/* IVL_EN */
if(pVlanCfg->ivl_en >= RTK_ENABLE_END)
return RT_ERR_ENABLE;

/* fid must be 0~15 */
if(pVlanCfg->fid_msti > RTL8367C_FIDMAX)
return RT_ERR_L2_FID;

/* Policing */
if(pVlanCfg->envlanpol >= RTK_ENABLE_END)
return RT_ERR_ENABLE;

/* Meter ID */
if(pVlanCfg->meteridx > RTK_MAX_METER_ID)
return RT_ERR_INPUT;

/* VLAN based priority */
if(pVlanCfg->vbpen >= RTK_ENABLE_END)
return RT_ERR_ENABLE;

/* Priority */
if(pVlanCfg->vbpri > RTL8367C_PRIMAX)
return RT_ERR_INPUT;

/* Get physical port mask */
if(rtk_switch_portmask_L2P_get(&(pVlanCfg->mbr), &phyMbrPmask) != RT_ERR_OK)
return RT_ERR_FAILED;

if(rtk_switch_portmask_L2P_get(&(pVlanCfg->untag), &phyUntagPmask) != RT_ERR_OK)
return RT_ERR_FAILED;

if (vid <= RTL8367C_VIDMAX)
{
/* update 4K table */
memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry));
vlan4K.vid = vid;

vlan4K.mbr = (phyMbrPmask & 0xFFFF);
vlan4K.untag = (phyUntagPmask & 0xFFFF);

vlan4K.ivl_svl = pVlanCfg->ivl_en;
vlan4K.fid_msti = pVlanCfg->fid_msti;
vlan4K.envlanpol = pVlanCfg->envlanpol;
vlan4K.meteridx = pVlanCfg->meteridx;
vlan4K.vbpen = pVlanCfg->vbpen;
vlan4K.vbpri = pVlanCfg->vbpri;

if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK)
return retVal;

/* Update Member configuration if exist */
for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++)
{
if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN)
{
if(vlan_mbrCfgVid[idx] == vid)
{
/* Found! Update */
if(phyMbrPmask == 0x00)
{
/* Member port = 0x00, delete this VLAN from Member Configuration */
memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser));
if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK)
return retVal;

/* Clear Database */
vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED;
vlan_mbrCfgVid[idx] = 0;
}
else
{
/* Normal VLAN config, update to member configuration */
vlanMC.evid = vid;
vlanMC.mbr = vlan4K.mbr;
vlanMC.fid_msti = vlan4K.fid_msti;
vlanMC.meteridx = vlan4K.meteridx;
vlanMC.envlanpol= vlan4K.envlanpol;
vlanMC.vbpen = vlan4K.vbpen;
vlanMC.vbpri = vlan4K.vbpri;
if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK)
return retVal;
}

break;
}
}
}
}
else
{
/* vid > 4095 */
for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++)
{
if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN)
{
if(vlan_mbrCfgVid[idx] == vid)
{
/* Found! Update */
if(phyMbrPmask == 0x00)
{
/* Member port = 0x00, delete this VLAN from Member Configuration */
memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser));
if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK)
return retVal;

/* Clear Database */
vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED;
vlan_mbrCfgVid[idx] = 0;
}
else
{
/* Normal VLAN config, update to member configuration */
vlanMC.evid = vid;
vlanMC.mbr = phyMbrPmask;
vlanMC.fid_msti = pVlanCfg->fid_msti;
vlanMC.meteridx = pVlanCfg->meteridx;
vlanMC.envlanpol= pVlanCfg->envlanpol;
vlanMC.vbpen = pVlanCfg->vbpen;
vlanMC.vbpri = pVlanCfg->vbpri;
if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK)
return retVal;

break;
}

update_evid = 1;
}
}

if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED)
{
if(0xffff == empty_index)
empty_index = idx;
}
}

/* doesn't find out same EVID entry and there is empty index in member configuration */
if( (phyMbrPmask != 0x00) && (update_evid == 0) && (empty_index != 0xFFFF) )
{
vlanMC.evid = vid;
vlanMC.mbr = phyMbrPmask;
vlanMC.fid_msti = pVlanCfg->fid_msti;
vlanMC.meteridx = pVlanCfg->meteridx;
vlanMC.envlanpol= pVlanCfg->envlanpol;
vlanMC.vbpen = pVlanCfg->vbpen;
vlanMC.vbpri = pVlanCfg->vbpri;
if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_index, &vlanMC)) != RT_ERR_OK)
return retVal;

vlan_mbrCfgUsage[empty_index] = MBRCFG_USED_BY_VLAN;
vlan_mbrCfgVid[empty_index] = vid;

}
}

return RT_ERR_OK;
}

static int rtl8367s_vlan_config(int want_at_p0)
{
rtk_vlan_cfg_t vlan1, vlan2;
@@ -1273,8 +1598,6 @@ ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *p
return RT_ERR_OK;
}

//rtl8367c_setAsicPortExtMode

rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability)
{
rtk_api_ret_t retVal;

0 comments on commit eb3332b

Please sign in to comment.