From 2aa727ff0909f0c1a4be6bde77e3589d024e079b Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 17 Sep 2016 15:58:11 +0200 Subject: etherzynq: implement promisc mode and multicast filter support --- sys/src/9/zynq/etherzynq.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'sys/src') diff --git a/sys/src/9/zynq/etherzynq.c b/sys/src/9/zynq/etherzynq.c index c24ded981..48b1d7c4b 100644 --- a/sys/src/9/zynq/etherzynq.c +++ b/sys/src/9/zynq/etherzynq.c @@ -62,6 +62,9 @@ enum { /* 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 @@ ethirq(Ureg *, void *arg) 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<r[HASH_TOP] |= 1<<(x-32); + c->r[NET_CFG] |= MCASTHASHEN; +} + static int ethinit(Ether *edev) { @@ -362,6 +407,8 @@ etherpnp(Ether *edev) edev->interrupt = ethirq; edev->transmit = ethtx; edev->attach = ethattach; + edev->promiscuous = ethprom; + edev->multicast = ethmcast; edev->arg = edev; edev->mbps = 1000; -- cgit v1.2.3