mirror of https://github.com/xemu-project/xemu.git
net/cadence_gem: Implement RX descriptor match mode flags
The various Rx packet address matching mode flags were not being set in the rx descriptor. Implement. Reported-by: Deepika Dhamija <deepika@xilinx.com> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Message-id: 6002a24a6a8ceaa11d3009ab5392840d1c084b28.1386136219.git.peter.crosthwaite@xilinx.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
06c2fe951d
commit
63af1e0cff
|
@ -222,8 +222,13 @@
|
||||||
#define PHY_REG_INT_ST_ENERGY 0x0010
|
#define PHY_REG_INT_ST_ENERGY 0x0010
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
#define GEM_RX_REJECT 1
|
#define GEM_RX_REJECT (-1)
|
||||||
#define GEM_RX_ACCEPT 0
|
#define GEM_RX_PROMISCUOUS_ACCEPT (-2)
|
||||||
|
#define GEM_RX_BROADCAST_ACCEPT (-3)
|
||||||
|
#define GEM_RX_MULTICAST_HASH_ACCEPT (-4)
|
||||||
|
#define GEM_RX_UNICAST_HASH_ACCEPT (-5)
|
||||||
|
|
||||||
|
#define GEM_RX_SAR_ACCEPT 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
@ -236,6 +241,12 @@
|
||||||
#define DESC_0_RX_WRAP 0x00000002
|
#define DESC_0_RX_WRAP 0x00000002
|
||||||
#define DESC_0_RX_OWNERSHIP 0x00000001
|
#define DESC_0_RX_OWNERSHIP 0x00000001
|
||||||
|
|
||||||
|
#define R_DESC_1_RX_SAR_SHIFT 25
|
||||||
|
#define R_DESC_1_RX_SAR_LENGTH 2
|
||||||
|
#define R_DESC_1_RX_UNICAST_HASH (1 << 29)
|
||||||
|
#define R_DESC_1_RX_MULTICAST_HASH (1 << 30)
|
||||||
|
#define R_DESC_1_RX_BROADCAST (1 << 31)
|
||||||
|
|
||||||
#define DESC_1_RX_SOF 0x00004000
|
#define DESC_1_RX_SOF 0x00004000
|
||||||
#define DESC_1_RX_EOF 0x00008000
|
#define DESC_1_RX_EOF 0x00008000
|
||||||
|
|
||||||
|
@ -315,6 +326,27 @@ static inline void rx_desc_set_length(unsigned *desc, unsigned len)
|
||||||
desc[1] |= len;
|
desc[1] |= len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void rx_desc_set_broadcast(unsigned *desc)
|
||||||
|
{
|
||||||
|
desc[1] |= R_DESC_1_RX_BROADCAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rx_desc_set_unicast_hash(unsigned *desc)
|
||||||
|
{
|
||||||
|
desc[1] |= R_DESC_1_RX_UNICAST_HASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rx_desc_set_multicast_hash(unsigned *desc)
|
||||||
|
{
|
||||||
|
desc[1] |= R_DESC_1_RX_MULTICAST_HASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rx_desc_set_sar(unsigned *desc, int sar_idx)
|
||||||
|
{
|
||||||
|
desc[1] = deposit32(desc[1], R_DESC_1_RX_SAR_SHIFT, R_DESC_1_RX_SAR_LENGTH,
|
||||||
|
sar_idx);
|
||||||
|
}
|
||||||
|
|
||||||
#define TYPE_CADENCE_GEM "cadence_gem"
|
#define TYPE_CADENCE_GEM "cadence_gem"
|
||||||
#define GEM(obj) OBJECT_CHECK(GemState, (obj), TYPE_CADENCE_GEM)
|
#define GEM(obj) OBJECT_CHECK(GemState, (obj), TYPE_CADENCE_GEM)
|
||||||
|
|
||||||
|
@ -529,7 +561,10 @@ static unsigned calc_mac_hash(const uint8_t *mac)
|
||||||
* Accept or reject this destination address?
|
* Accept or reject this destination address?
|
||||||
* Returns:
|
* Returns:
|
||||||
* GEM_RX_REJECT: reject
|
* GEM_RX_REJECT: reject
|
||||||
* GEM_RX_ACCEPT: accept
|
* >= 0: Specific address accept (which matched SAR is returned)
|
||||||
|
* others for various other modes of accept:
|
||||||
|
* GEM_RM_PROMISCUOUS_ACCEPT, GEM_RX_BROADCAST_ACCEPT,
|
||||||
|
* GEM_RX_MULTICAST_HASH_ACCEPT or GEM_RX_UNICAST_HASH_ACCEPT
|
||||||
*/
|
*/
|
||||||
static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
|
static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
|
||||||
{
|
{
|
||||||
|
@ -538,7 +573,7 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
|
||||||
|
|
||||||
/* Promiscuous mode? */
|
/* Promiscuous mode? */
|
||||||
if (s->regs[GEM_NWCFG] & GEM_NWCFG_PROMISC) {
|
if (s->regs[GEM_NWCFG] & GEM_NWCFG_PROMISC) {
|
||||||
return GEM_RX_ACCEPT;
|
return GEM_RX_PROMISCUOUS_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memcmp(packet, broadcast_addr, 6)) {
|
if (!memcmp(packet, broadcast_addr, 6)) {
|
||||||
|
@ -546,7 +581,7 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
|
||||||
if (s->regs[GEM_NWCFG] & GEM_NWCFG_BCAST_REJ) {
|
if (s->regs[GEM_NWCFG] & GEM_NWCFG_BCAST_REJ) {
|
||||||
return GEM_RX_REJECT;
|
return GEM_RX_REJECT;
|
||||||
}
|
}
|
||||||
return GEM_RX_ACCEPT;
|
return GEM_RX_BROADCAST_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept packets -w- hash match? */
|
/* Accept packets -w- hash match? */
|
||||||
|
@ -557,24 +592,24 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
|
||||||
hash_index = calc_mac_hash(packet);
|
hash_index = calc_mac_hash(packet);
|
||||||
if (hash_index < 32) {
|
if (hash_index < 32) {
|
||||||
if (s->regs[GEM_HASHLO] & (1<<hash_index)) {
|
if (s->regs[GEM_HASHLO] & (1<<hash_index)) {
|
||||||
return GEM_RX_ACCEPT;
|
return packet[0] == 0x01 ? GEM_RX_MULTICAST_HASH_ACCEPT :
|
||||||
|
GEM_RX_UNICAST_HASH_ACCEPT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hash_index -= 32;
|
hash_index -= 32;
|
||||||
if (s->regs[GEM_HASHHI] & (1<<hash_index)) {
|
if (s->regs[GEM_HASHHI] & (1<<hash_index)) {
|
||||||
return GEM_RX_ACCEPT;
|
return packet[0] == 0x01 ? GEM_RX_MULTICAST_HASH_ACCEPT :
|
||||||
|
GEM_RX_UNICAST_HASH_ACCEPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check all 4 specific addresses */
|
/* Check all 4 specific addresses */
|
||||||
gem_spaddr = (uint8_t *)&(s->regs[GEM_SPADDR1LO]);
|
gem_spaddr = (uint8_t *)&(s->regs[GEM_SPADDR1LO]);
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 3; i >= 0; i--) {
|
||||||
if (!memcmp(packet, gem_spaddr, 6)) {
|
if (!memcmp(packet, gem_spaddr + 8 * i, 6)) {
|
||||||
return GEM_RX_ACCEPT;
|
return GEM_RX_SAR_ACCEPT + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
gem_spaddr += 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No address match; reject the packet */
|
/* No address match; reject the packet */
|
||||||
|
@ -611,11 +646,13 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||||
uint8_t rxbuf[2048];
|
uint8_t rxbuf[2048];
|
||||||
uint8_t *rxbuf_ptr;
|
uint8_t *rxbuf_ptr;
|
||||||
bool first_desc = true;
|
bool first_desc = true;
|
||||||
|
int maf;
|
||||||
|
|
||||||
s = qemu_get_nic_opaque(nc);
|
s = qemu_get_nic_opaque(nc);
|
||||||
|
|
||||||
/* Is this destination MAC address "for us" ? */
|
/* Is this destination MAC address "for us" ? */
|
||||||
if (gem_mac_address_filter(s, buf) == GEM_RX_REJECT) {
|
maf = gem_mac_address_filter(s, buf);
|
||||||
|
if (maf == GEM_RX_REJECT) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,6 +743,25 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||||
rx_desc_set_length(s->rx_desc, size);
|
rx_desc_set_length(s->rx_desc, size);
|
||||||
}
|
}
|
||||||
rx_desc_set_ownership(s->rx_desc);
|
rx_desc_set_ownership(s->rx_desc);
|
||||||
|
|
||||||
|
switch (maf) {
|
||||||
|
case GEM_RX_PROMISCUOUS_ACCEPT:
|
||||||
|
break;
|
||||||
|
case GEM_RX_BROADCAST_ACCEPT:
|
||||||
|
rx_desc_set_broadcast(s->rx_desc);
|
||||||
|
break;
|
||||||
|
case GEM_RX_UNICAST_HASH_ACCEPT:
|
||||||
|
rx_desc_set_unicast_hash(s->rx_desc);
|
||||||
|
break;
|
||||||
|
case GEM_RX_MULTICAST_HASH_ACCEPT:
|
||||||
|
rx_desc_set_multicast_hash(s->rx_desc);
|
||||||
|
break;
|
||||||
|
case GEM_RX_REJECT:
|
||||||
|
abort();
|
||||||
|
default: /* SAR */
|
||||||
|
rx_desc_set_sar(s->rx_desc, maf);
|
||||||
|
}
|
||||||
|
|
||||||
/* Descriptor write-back. */
|
/* Descriptor write-back. */
|
||||||
cpu_physical_memory_write(s->rx_desc_addr,
|
cpu_physical_memory_write(s->rx_desc_addr,
|
||||||
(uint8_t *)s->rx_desc, sizeof(s->rx_desc));
|
(uint8_t *)s->rx_desc, sizeof(s->rx_desc));
|
||||||
|
|
Loading…
Reference in New Issue