diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-09-17 15:58:11 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-09-17 15:58:11 +0200 |
commit | 2aa727ff0909f0c1a4be6bde77e3589d024e079b (patch) | |
tree | 1969b584201d64099adac462ff59b9f8c8ddae32 /sys/src/9/zynq/etherzynq.c | |
parent | cb9a5a19b0a992d222dcb07c6a368c710a44bb28 (diff) |
etherzynq: implement promisc mode and multicast filter support
Diffstat (limited to 'sys/src/9/zynq/etherzynq.c')
-rw-r--r-- | sys/src/9/zynq/etherzynq.c | 47 |
1 files changed, 47 insertions, 0 deletions
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<<x; + else + c->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; |