提交 63af1e0c 编写于 作者: P Peter Crosthwaite 提交者: Peter Maydell

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: NDeepika Dhamija <deepika@xilinx.com>
Signed-off-by: NPeter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 6002a24a6a8ceaa11d3009ab5392840d1c084b28.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 06c2fe95
...@@ -222,8 +222,13 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册