Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/ti/cpsw/if_cpsw.c
Show First 20 Lines • Show All 2,419 Lines • ▼ Show 20 Lines | case ALE_TYPE_VLAN_ADDR: | ||||
printf("port: %u ", ALE_PORTS(ale_entry)); | printf("port: %u ", ALE_PORTS(ale_entry)); | ||||
printf("\n"); | printf("\n"); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
printf("\n"); | printf("\n"); | ||||
} | } | ||||
static u_int | |||||
cpswp_set_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) | |||||
{ | |||||
struct cpswp_softc *sc = arg; | |||||
uint32_t portmask; | |||||
if (sc->swsc->dualemac) | |||||
portmask = 1 << (sc->unit + 1) | 1 << 0; | |||||
else | |||||
portmask = 7; | |||||
cpsw_ale_mc_entry_set(sc->swsc, portmask, sc->vlan, LLADDR(sdl)); | |||||
return (1); | |||||
} | |||||
static int | static int | ||||
cpswp_ale_update_addresses(struct cpswp_softc *sc, int purge) | cpswp_ale_update_addresses(struct cpswp_softc *sc, int purge) | ||||
{ | { | ||||
uint8_t *mac; | uint8_t *mac; | ||||
uint32_t ale_entry[3], ale_type, portmask; | uint32_t ale_entry[3], ale_type, portmask; | ||||
struct ifmultiaddr *ifma; | |||||
if (sc->swsc->dualemac) { | if (sc->swsc->dualemac) { | ||||
ale_type = ALE_TYPE_VLAN_ADDR << 28 | sc->vlan << 16; | ale_type = ALE_TYPE_VLAN_ADDR << 28 | sc->vlan << 16; | ||||
portmask = 1 << (sc->unit + 1) | 1 << 0; | portmask = 1 << (sc->unit + 1) | 1 << 0; | ||||
} else { | } else { | ||||
ale_type = ALE_TYPE_ADDR << 28; | ale_type = ALE_TYPE_ADDR << 28; | ||||
portmask = 7; | portmask = 7; | ||||
} | } | ||||
/* | /* | ||||
* Route incoming packets for our MAC address to Port 0 (host). | * Route incoming packets for our MAC address to Port 0 (host). | ||||
* For simplicity, keep this entry at table index 0 for port 1 and | * For simplicity, keep this entry at table index 0 for port 1 and | ||||
* at index 2 for port 2 in the ALE. | * at index 2 for port 2 in the ALE. | ||||
*/ | */ | ||||
if_addr_rlock(sc->ifp); | |||||
mac = LLADDR((struct sockaddr_dl *)sc->ifp->if_addr->ifa_addr); | mac = LLADDR((struct sockaddr_dl *)sc->ifp->if_addr->ifa_addr); | ||||
ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; | ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; | ||||
ale_entry[1] = ale_type | mac[0] << 8 | mac[1]; /* addr entry + mac */ | ale_entry[1] = ale_type | mac[0] << 8 | mac[1]; /* addr entry + mac */ | ||||
ale_entry[2] = 0; /* port = 0 */ | ale_entry[2] = 0; /* port = 0 */ | ||||
cpsw_ale_write_entry(sc->swsc, 0 + 2 * sc->unit, ale_entry); | cpsw_ale_write_entry(sc->swsc, 0 + 2 * sc->unit, ale_entry); | ||||
/* Set outgoing MAC Address for slave port. */ | /* Set outgoing MAC Address for slave port. */ | ||||
cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_HI(sc->unit + 1), | cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_HI(sc->unit + 1), | ||||
mac[3] << 24 | mac[2] << 16 | mac[1] << 8 | mac[0]); | mac[3] << 24 | mac[2] << 16 | mac[1] << 8 | mac[0]); | ||||
cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_LO(sc->unit + 1), | cpsw_write_4(sc->swsc, CPSW_PORT_P_SA_LO(sc->unit + 1), | ||||
mac[5] << 8 | mac[4]); | mac[5] << 8 | mac[4]); | ||||
if_addr_runlock(sc->ifp); | |||||
/* Keep the broadcast address at table entry 1 (or 3). */ | /* Keep the broadcast address at table entry 1 (or 3). */ | ||||
ale_entry[0] = 0xffffffff; /* Lower 32 bits of MAC */ | ale_entry[0] = 0xffffffff; /* Lower 32 bits of MAC */ | ||||
/* ALE_MCAST_FWD, Addr type, upper 16 bits of Mac */ | /* ALE_MCAST_FWD, Addr type, upper 16 bits of Mac */ | ||||
ale_entry[1] = ALE_MCAST_FWD | ale_type | 0xffff; | ale_entry[1] = ALE_MCAST_FWD | ale_type | 0xffff; | ||||
ale_entry[2] = portmask << 2; | ale_entry[2] = portmask << 2; | ||||
cpsw_ale_write_entry(sc->swsc, 1 + 2 * sc->unit, ale_entry); | cpsw_ale_write_entry(sc->swsc, 1 + 2 * sc->unit, ale_entry); | ||||
/* SIOCDELMULTI doesn't specify the particular address | /* SIOCDELMULTI doesn't specify the particular address | ||||
being removed, so we have to remove all and rebuild. */ | being removed, so we have to remove all and rebuild. */ | ||||
if (purge) | if (purge) | ||||
cpsw_ale_remove_all_mc_entries(sc->swsc); | cpsw_ale_remove_all_mc_entries(sc->swsc); | ||||
/* Set other multicast addrs desired. */ | /* Set other multicast addrs desired. */ | ||||
if_maddr_rlock(sc->ifp); | if_foreach_llmaddr(sc->ifp, cpswp_set_maddr, sc); | ||||
CK_STAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { | |||||
if (ifma->ifma_addr->sa_family != AF_LINK) | |||||
continue; | |||||
cpsw_ale_mc_entry_set(sc->swsc, portmask, sc->vlan, | |||||
LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); | |||||
} | |||||
if_maddr_runlock(sc->ifp); | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
cpsw_ale_update_vlan_table(struct cpsw_softc *sc, int vlan, int ports, | cpsw_ale_update_vlan_table(struct cpsw_softc *sc, int vlan, int ports, | ||||
int untag, int mcregflood, int mcunregflood) | int untag, int mcregflood, int mcunregflood) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 507 Lines • Show Last 20 Lines |