]> git.lizzy.rs Git - plan9front.git/commitdiff
etherzynq: implement promisc mode and multicast filter support
authorcinap_lenrek <cinap_lenrek@felloff.net>
Sat, 17 Sep 2016 13:58:11 +0000 (15:58 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Sat, 17 Sep 2016 13:58:11 +0000 (15:58 +0200)
sys/src/9/zynq/etherzynq.c

index c24ded981b2a1123a378e45458daa25102fb2224..48b1d7c4bb1f6e6520bf1b256d022c3c59392a86 100644 (file)
@@ -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;