31 |
#define DEBUG_UNKNOWN 0 |
#define DEBUG_UNKNOWN 0 |
32 |
#define DEBUG_MII 0 |
#define DEBUG_MII 0 |
33 |
#define DEBUG_MEM 0 |
#define DEBUG_MEM 0 |
34 |
#define DEBUG_REG 1 |
#define DEBUG_REG 0 |
35 |
#define DEBUG_TRANSMIT 0 |
#define DEBUG_TRANSMIT 0 |
36 |
#define DEBUG_RECEIVE 0 |
#define DEBUG_RECEIVE 0 |
37 |
#define DEBUG_FORWARD 0 |
#define DEBUG_FORWARD 0 |
2058 |
return(TRUE); |
return(TRUE); |
2059 |
} |
} |
2060 |
|
|
2061 |
|
/* Determine if the specified MAC address matches a BPDU */ |
2062 |
|
static inline int bcm5600_is_bpdu(n_eth_addr_t *m) |
2063 |
|
{ |
2064 |
|
/* PVST+ */ |
2065 |
|
if (!memcmp(m,"\x01\x00\x0c\xcc\xcc\xcd",6)) |
2066 |
|
return(TRUE); |
2067 |
|
|
2068 |
|
/* Classical 802.1D */ |
2069 |
|
if (!memcmp(m,"\x01\x80\xc2\x00\x00",5) && !(m->eth_addr_byte[5] & 0xF0)) |
2070 |
|
return(TRUE); |
2071 |
|
|
2072 |
|
return(FALSE); |
2073 |
|
} |
2074 |
|
|
2075 |
/* Handle a received packet */ |
/* Handle a received packet */ |
2076 |
static int bcm5600_handle_rx_pkt(struct nm_16esw_data *d,struct bcm5600_pkt *p) |
static int bcm5600_handle_rx_pkt(struct nm_16esw_data *d,struct bcm5600_pkt *p) |
2077 |
{ |
{ |
2091 |
/* Analyze the Ethernet header */ |
/* Analyze the Ethernet header */ |
2092 |
eth_hdr = (n_eth_dot1q_hdr_t *)p->pkt; |
eth_hdr = (n_eth_dot1q_hdr_t *)p->pkt; |
2093 |
|
|
2094 |
|
/* Determine VLAN */ |
2095 |
|
if (ntohs(eth_hdr->type) != N_ETH_PROTO_DOT1Q) { |
2096 |
|
p->orig_vlan = -1; |
2097 |
|
p->real_vlan = port_entry[0] & BCM5600_PTABLE_VLAN_TAG_MASK; |
2098 |
|
|
2099 |
|
/* TODO: 802.1p/CoS remarking */ |
2100 |
|
if (port_entry[4] & BCM5600_PTABLE_RPE_FLAG) { |
2101 |
|
} |
2102 |
|
} else { |
2103 |
|
p->orig_vlan = p->real_vlan = ntohs(eth_hdr->vlan_id) & 0xFFF; |
2104 |
|
} |
2105 |
|
|
2106 |
|
/* Check that this VLAN exists */ |
2107 |
|
if (!(p->vlan_entry = bcm5600_vtable_get_entry_by_vlan(d,p->real_vlan))) |
2108 |
|
return(FALSE); |
2109 |
|
|
2110 |
/* Check for the reserved addresses (BPDU for spanning-tree) */ |
/* Check for the reserved addresses (BPDU for spanning-tree) */ |
2111 |
if (!memcmp(ð_hdr->daddr,"\x01\x80\xc2\x00\x00",5) || |
if (bcm5600_is_bpdu(ð_hdr->daddr)) { |
|
!memcmp(ð_hdr->daddr,"\x01\x00\x0c\xcc\xcc\xcd",6)) |
|
|
{ |
|
2112 |
#if DEBUG_RECEIVE |
#if DEBUG_RECEIVE |
2113 |
BCM_LOG(d,"Received a BPDU packet:\n"); |
BCM_LOG(d,"Received a BPDU packet:\n"); |
2114 |
mem_dump(d->vm->log_fd,p->pkt,p->pkt_len); |
mem_dump(d->vm->log_fd,p->pkt,p->pkt_len); |
2115 |
#endif |
#endif |
|
p->orig_vlan = 0; |
|
2116 |
p->egress_bitmap |= 1 << d->cpu_port; |
p->egress_bitmap |= 1 << d->cpu_port; |
2117 |
return(bcm5600_forward_pkt(d,p)); |
return(bcm5600_forward_pkt(d,p)); |
2118 |
} |
} |
2119 |
|
|
2120 |
|
/* Check that this port is a member of this VLAN */ |
2121 |
|
if (!(p->vlan_entry[1] & (1 << p->ingress_port))) |
2122 |
|
return(FALSE); |
2123 |
|
|
2124 |
/* Discard packet ? */ |
/* Discard packet ? */ |
2125 |
discard = port_entry[0] & BCM5600_PTABLE_PRT_DIS_MASK; |
discard = port_entry[0] & BCM5600_PTABLE_PRT_DIS_MASK; |
2126 |
discard >>= BCM5600_PTABLE_PRT_DIS_SHIFT; |
discard >>= BCM5600_PTABLE_PRT_DIS_SHIFT; |
2144 |
if (port_entry[1] & BCM5600_PTABLE_MI_FLAG) |
if (port_entry[1] & BCM5600_PTABLE_MI_FLAG) |
2145 |
bcm5600_mirror_pkt(d,p,0); |
bcm5600_mirror_pkt(d,p,0); |
2146 |
|
|
|
/* Determine VLAN */ |
|
|
if (ntohs(eth_hdr->type) != N_ETH_PROTO_DOT1Q) { |
|
|
p->orig_vlan = -1; |
|
|
p->real_vlan = port_entry[0] & BCM5600_PTABLE_VLAN_TAG_MASK; |
|
|
|
|
|
if (!(p->vlan_entry = bcm5600_vtable_get_entry_by_vlan(d,p->real_vlan))) |
|
|
return(FALSE); |
|
|
|
|
|
/* TODO: 802.1p/CoS remarking */ |
|
|
if (port_entry[4] & BCM5600_PTABLE_RPE_FLAG) { |
|
|
} |
|
|
} else { |
|
|
p->orig_vlan = p->real_vlan = ntohs(eth_hdr->vlan_id) & 0xFFF; |
|
|
|
|
|
/* Check that this VLAN exists */ |
|
|
if (!(p->vlan_entry = bcm5600_vtable_get_entry_by_vlan(d,p->real_vlan))) |
|
|
return(FALSE); |
|
|
|
|
|
/* Check that this port is a member of this VLAN */ |
|
|
if (!(p->vlan_entry[1] & (1 << p->ingress_port))) |
|
|
return(FALSE); |
|
|
} |
|
|
|
|
2147 |
#if DEBUG_RECEIVE |
#if DEBUG_RECEIVE |
2148 |
BCM_LOG(d,"%s: received a packet on VLAN %u\n", |
BCM_LOG(d,"%s: received a packet on VLAN %u\n", |
2149 |
d->ports[p->ingress_port].name,p->real_vlan); |
d->ports[p->ingress_port].name,p->real_vlan); |