static void asic_delete_mcast_mask(const u8 *mcast_mac, u16 port_efid, u16 port_fid) { #if defined(CONFIG_RTL8367_API_8370) rtl8370_luttb l2t; memset(&l2t, 0, sizeof(l2t)); memcpy(l2t.mac.octet, mcast_mac, ETHER_ADDR_LEN); l2t.efid = port_efid; l2t.fid = port_fid; rtl8370_setAsicL2LookupTb(&l2t); #else rtl8367b_luttb l2t; memset(&l2t, 0, sizeof(l2t)); memcpy(l2t.mac.octet, mcast_mac, ETHER_ADDR_LEN); l2t.efid = port_efid; l2t.cvid_fid = port_fid; // ivl = 0, mean fid rtl8367b_setAsicL2LookupTb(&l2t); #endif }
static void asic_enum_mcast_table(int clear_all) { rtk_api_ret_t retVal; int index = 0; u32 addr_id = 0; #if defined(CONFIG_RTL8367_API_8370) rtl8370_luttb l2t; for (addr_id = 0; addr_id < RTK_MAX_NUM_OF_LEARN_LIMIT; addr_id++) { if (!test_bit(addr_id, g_l2t_cache)) continue; memset(&l2t, 0, sizeof(l2t)); l2t.address = addr_id; retVal = rtl8370_getAsicL2LookupTb(LUTREADMETHOD_ADDRESS, &l2t); if (retVal != RT_ERR_OK) continue; if (!(l2t.mac.octet[0] & 0x01)) continue; if (clear_all) { l2t.ipmul = 0; l2t.block = 0; l2t.static_bit = 0; l2t.portmask = 0; rtl8370_setAsicL2LookupTb(&l2t); } else { index++; printk("%4d. %02X-%02X-%02X-%02X-%02X-%02X, portmask: 0x%04X, efid: %d, fid: %4d\n", index, l2t.mac.octet[0], l2t.mac.octet[1], l2t.mac.octet[2], l2t.mac.octet[3], l2t.mac.octet[4], l2t.mac.octet[5], l2t.portmask, l2t.efid, l2t.fid ); } } if (clear_all) { bitmap_zero(g_l2t_cache, RTK_MAX_NUM_OF_LEARN_LIMIT); } #else rtl8367b_luttb l2t; while (addr_id <= RTK_MAX_LUT_ADDR_ID) { memset(&l2t, 0, sizeof(l2t)); l2t.address = addr_id; retVal = rtl8367b_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L2MC, &l2t); if (retVal != RT_ERR_OK) break; if (l2t.address < addr_id) break; addr_id = l2t.address + 1; if (clear_all) { l2t.l3lookup = 0; l2t.nosalearn = 0; l2t.sa_block = 0; l2t.mbr = 0; rtl8367b_setAsicL2LookupTb(&l2t); } else { index++; printk("%4d. %02X-%02X-%02X-%02X-%02X-%02X, addr_id: %d, portmask: 0x%04X, efid: %d, cvid: %4d, ivl: %d\n", index, l2t.mac.octet[0], l2t.mac.octet[1], l2t.mac.octet[2], l2t.mac.octet[3], l2t.mac.octet[4], l2t.mac.octet[5], l2t.address, l2t.mbr, l2t.efid, l2t.cvid_fid, l2t.ivl_svl ); } } #endif }
static rtk_api_ret_t asic_update_mcast_mask(const u8 *mcast_mac, u16 port_efid, u16 port_cvid_fid, u32 port_id, int is_leave) { rtk_api_ret_t retVal; u16 portmask_old; u16 port_dst_msk = (1u << port_id); u16 uports_static = MASK_LAN_PORT_CPU | (u16)g_igmp_static_ports; #if defined(CONFIG_RTL8367_API_8370) rtl8370_luttb l2t; memset(&l2t, 0, sizeof(l2t)); memcpy(l2t.mac.octet, mcast_mac, ETHER_ADDR_LEN); l2t.efid = port_efid; l2t.fid = port_cvid_fid; // svl, mean fid retVal = rtl8370_getAsicL2LookupTb(LUTREADMETHOD_MAC, &l2t); if (retVal == RT_ERR_OK) { if (l2t.address < RTK_MAX_NUM_OF_LEARN_LIMIT) { if (l2t.portmask) set_bit(l2t.address, g_l2t_cache); else clear_bit(l2t.address, g_l2t_cache); } } else l2t.portmask = 0; // entry not exist, reset mask to 0 portmask_old = l2t.portmask; l2t.ipmul = 0; l2t.static_bit = 1; l2t.portmask |= uports_static; if (!is_leave) { l2t.portmask |= port_dst_msk; } else { l2t.portmask &= ~port_dst_msk; /* try to remove static entry */ if (!(l2t.portmask & ~uports_static) && is_leave > 1) { l2t.static_bit = 0; l2t.portmask = 0; } } if (l2t.portmask == portmask_old) return RT_ERR_OK; retVal = rtl8370_setAsicL2LookupTb(&l2t); if (retVal == RT_ERR_OK) { if (l2t.address < RTK_MAX_NUM_OF_LEARN_LIMIT) { if (l2t.portmask) set_bit(l2t.address, g_l2t_cache); else clear_bit(l2t.address, g_l2t_cache); } } return retVal; #else rtl8367b_luttb l2t; memset(&l2t, 0, sizeof(l2t)); memcpy(l2t.mac.octet, mcast_mac, ETHER_ADDR_LEN); l2t.efid = port_efid; l2t.ivl_svl = 1; l2t.cvid_fid = port_cvid_fid; // ivl, mean cvid retVal = rtl8367b_getAsicL2LookupTb(LUTREADMETHOD_MAC, &l2t); if (retVal != RT_ERR_OK) l2t.mbr = 0; // entry not exist, reset mask to 0 portmask_old = l2t.mbr; l2t.l3lookup = 0; l2t.nosalearn = 1; l2t.mbr |= uports_static; if (!is_leave) { l2t.mbr |= port_dst_msk; } else { l2t.mbr &= ~port_dst_msk; /* try to remove static entry */ if (!(l2t.mbr & ~uports_static) && is_leave > 1) { l2t.nosalearn = 0; l2t.mbr = 0; } } if (l2t.mbr == portmask_old) return RT_ERR_OK; return rtl8367b_setAsicL2LookupTb(&l2t); #endif }
static rtk_api_ret_t asic_update_mcast_mask(const u8 *mcast_mac, u16 port_efid, u16 port_fid, u32 port_id, int is_leave) { rtk_api_ret_t retVal; u16 portmask_old; u16 port_cpu_msk = (1u << LAN_PORT_CPU); u16 port_dst_msk = (1u << port_id); #if defined(CONFIG_RTL8367_API_8370) rtl8370_luttb l2t; memset(&l2t, 0, sizeof(l2t)); memcpy(l2t.mac.octet, mcast_mac, ETHER_ADDR_LEN); l2t.efid = port_efid; l2t.fid = port_fid; retVal = rtl8370_getAsicL2LookupTb(LUTREADMETHOD_MAC, &l2t); if (retVal == RT_ERR_OK) { if (l2t.address < RTK_MAX_NUM_OF_LEARN_LIMIT) g_l2t_cache[l2t.address] = 1; } else l2t.portmask = 0; // entry not exist, reset mask to 0 l2t.efid = port_efid; l2t.fid = port_fid; l2t.ipmul = 0; l2t.static_bit = 1; portmask_old = l2t.portmask; l2t.portmask |= port_cpu_msk; if (!is_leave) l2t.portmask |= port_dst_msk; else l2t.portmask &= ~port_dst_msk; if (l2t.portmask == portmask_old) return RT_ERR_OK; retVal = rtl8370_setAsicL2LookupTb(&l2t); if (retVal == RT_ERR_OK) { if (l2t.address < RTK_MAX_NUM_OF_LEARN_LIMIT) g_l2t_cache[l2t.address] = 1; } return retVal; #else rtl8367b_luttb l2t; memset(&l2t, 0, sizeof(l2t)); memcpy(l2t.mac.octet, mcast_mac, ETHER_ADDR_LEN); l2t.efid = port_efid; l2t.cvid_fid = port_fid; // ivl = 0, mean fid retVal = rtl8367b_getAsicL2LookupTb(LUTREADMETHOD_MAC, &l2t); if (retVal != RT_ERR_OK) l2t.mbr = 0; // entry not exist, reset mask to 0 l2t.efid = port_efid; l2t.ivl_svl = 0; l2t.cvid_fid = port_fid; l2t.l3lookup = 0; l2t.nosalearn = 1; portmask_old = l2t.mbr; l2t.mbr |= port_cpu_msk; if (!is_leave) l2t.mbr |= port_dst_msk; else l2t.mbr &= ~port_dst_msk; if (l2t.mbr == portmask_old) return RT_ERR_OK; return rtl8367b_setAsicL2LookupTb(&l2t); #endif }