shithub: riscv

Download patch

ref: 2aa727ff0909f0c1a4be6bde77e3589d024e079b
parent: cb9a5a19b0a992d222dcb07c6a368c710a44bb28
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Sep 17 11:58:11 EDT 2016

etherzynq: implement promisc mode and multicast filter support

--- a/sys/src/9/zynq/etherzynq.c
+++ b/sys/src/9/zynq/etherzynq.c
@@ -62,6 +62,9 @@
 	/* NET_CFG */
 	SPEED = 1<<0,
 	FDEN = 1<<1,
+	COPYALLEN = 1<<4,
+	MCASTHASHEN = 1<<6,
+	UCASTHASHEN = 1<<7,
 	RX1536EN = 1<<8,
 	GIGE_EN = 1<<10,
 	RXCHKSUMEN = 1<<24,
@@ -290,6 +293,48 @@
 		print("eth: RX overrun, shouldn't happen\n");
 }
 
+static void
+ethprom(void *arg, int on)
+{
+	Ether *edev;
+	Ctlr *c;
+
+	edev = arg;
+	c = edev->ctlr;
+	if(on)
+		c->r[NET_CFG] |= COPYALLEN;
+	else
+		c->r[NET_CFG] &= ~COPYALLEN;
+}
+
+static void
+ethmcast(void *arg, uchar *ea, int on)
+{
+	Ether *edev;
+	Ctlr *c;
+	u64int a;
+	uchar x;
+
+	edev = arg;
+	c = edev->ctlr;
+	if(edev->nmaddr == 0){
+		c->r[NET_CFG] &= ~MCASTHASHEN;
+		c->r[HASH_BOT] = 0;
+		c->r[HASH_TOP] = 0;
+	}
+	if(!on)
+		return;
+	a = (u64int)ea[0]     | (u64int)ea[1]<<8  | (u64int)ea[2]<<16 |
+	    (u64int)ea[3]<<24 | (u64int)ea[4]<<32 | (u64int)ea[5]<<40;
+	x = a ^ (a>>6) ^ (a>>12) ^ (a>>18) ^ (a>>24) ^ (a>>30) ^ (a>>36) ^ (a>>42);
+	x &= 63;
+	if(x < 32)
+		c->r[HASH_BOT] |= 1<<x;
+	else
+		c->r[HASH_TOP] |= 1<<(x-32);
+	c->r[NET_CFG] |= MCASTHASHEN;
+}
+
 static int
 ethinit(Ether *edev)
 {
@@ -362,6 +407,8 @@
 	edev->interrupt = ethirq;
 	edev->transmit = ethtx;
 	edev->attach = ethattach;
+	edev->promiscuous = ethprom;
+	edev->multicast = ethmcast;
 	edev->arg = edev;
 	edev->mbps = 1000;