Remove NIX bits from the Proc ctl command.
[akaros.git] / kern / drivers / dev / ether.c
index 2637485..af71126 100644 (file)
 #include <smp.h>
 #include <ip.h>
 
-#include <vfs.h>
-#include <kfs.h>
-#include <slab.h>
-#include <kmalloc.h>
-#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
-#include <pmap.h>
-#include <smp.h>
-#include <ip.h>
-
 enum {
        Type8021Q = 0x8100,                     /* value of type field for 802.1[pQ] tags */
 };
@@ -241,7 +227,7 @@ static int etherwstat(struct chan *chan, uint8_t * dp, int n)
 
 static void etherrtrace(struct netfile *f, struct etherpkt *pkt, int len)
 {
-       int i, n;
+       uint64_t i, n;
        struct block *bp;
 
        if (qwindow(f->in) <= 0)
@@ -250,21 +236,38 @@ static void etherrtrace(struct netfile *f, struct etherpkt *pkt, int len)
                n = 58;
        else
                n = len;
-       bp = iallocb(64);
+       bp = iallocb(68);
        if (bp == NULL)
                return;
        memmove(bp->wp, pkt->d, n);
+       /* we're storing 8 bytes here (64 bit); old 9ns was 32 bit for msec */
        i = milliseconds();
        bp->wp[58] = len >> 8;
        bp->wp[59] = len;
-       bp->wp[60] = i >> 24;
-       bp->wp[61] = i >> 16;
-       bp->wp[62] = i >> 8;
-       bp->wp[63] = i;
-       bp->wp += 64;
+       bp->wp[60] = i >> 56;
+       bp->wp[61] = i >> 48;
+       bp->wp[62] = i >> 40;
+       bp->wp[63] = i >> 32;
+       bp->wp[64] = i >> 24;
+       bp->wp[65] = i >> 16;
+       bp->wp[66] = i >> 8;
+       bp->wp[67] = i;
+       bp->wp += 68;
        qpass(f->in, bp);
 }
 
+#ifdef CONFIG_RISCV
+#warning "Potentially unaligned ethernet addrs!"
+#endif
+
+static inline int eaddrcmp(uint8_t *x, uint8_t *y)
+{
+       uint16_t *a = (uint16_t *)x;
+       uint16_t *b = (uint16_t *)y;
+
+       return (a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]);
+}
+
 struct block *etheriq(struct ether *ether, struct block *bp, int fromwire)
 {
        struct etherpkt *pkt;
@@ -299,7 +302,7 @@ struct block *etheriq(struct ether *ether, struct block *bp, int fromwire)
 
        multi = pkt->d[0] & 1;
        /* check for valid multcast addresses */
-       if (multi && memcmp(pkt->d, ether->netif.bcast, sizeof(pkt->d)) != 0
+       if (multi && eaddrcmp(pkt->d, ether->netif.bcast) != 0
                && ether->netif.prom == 0) {
                if (!activemulti(&ether->netif, pkt->d, sizeof(pkt->d))) {
                        if (fromwire) {
@@ -311,8 +314,8 @@ struct block *etheriq(struct ether *ether, struct block *bp, int fromwire)
        }
 
        /* is it for me? */
-       tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
-       fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
+       tome = eaddrcmp(pkt->d, ether->ea) == 0;
+       fromme = eaddrcmp(pkt->s, ether->ea) == 0;
 
        /*
         * Multiplex the packet to all the connections which want it.
@@ -362,6 +365,8 @@ static int etheroq(struct ether *ether, struct block *bp)
 
        ether->netif.outpackets++;
 
+       if (!(ether->netif.feat & NETF_SG))
+               bp = linearizeblock(bp);
        /*
         * Check if the packet has to be placed back onto the input queue,
         * i.e. if it's a loopback or broadcast packet or the interface is
@@ -373,8 +378,8 @@ static int etheroq(struct ether *ether, struct block *bp)
         */
        pkt = (struct etherpkt *)bp->rp;
        len = BLEN(bp);
-       loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
-       if (loopback || memcmp(pkt->d, ether->netif.bcast, sizeof(pkt->d)) == 0
+       loopback = eaddrcmp(pkt->d, ether->ea) == 0;
+       if (loopback || eaddrcmp(pkt->d, ether->netif.bcast) == 0
                || ether->netif.prom) {
                disable_irqsave(&irq_state);
                etheriq(ether, bp, 0);
@@ -390,6 +395,11 @@ static int etheroq(struct ether *ether, struct block *bp)
                        hnputs(bp->rp + 2 * Eaddrlen + 2, ether->vlanid & 0xFFF);       /* prio:3 0:1 vid:12 */
                        ether = ether->ctlr;
                }
+
+               if ((ether->netif.feat & NETF_PADMIN) == 0 && BLEN(bp) < ether->minmtu)
+                       bp = adjustblock(bp, ether->minmtu);
+
+               ptclcsum_finalize(bp, ether->netif.feat);
                qbwrite(ether->oq, bp);
                if (ether->transmit != NULL)
                        ether->transmit(ether);
@@ -439,8 +449,6 @@ static long etherwrite(struct chan *chan, void *buf, long n, int64_t unused)
 
        if (n > ether->maxmtu)
                error(Etoobig);
-       if (n < ether->minmtu)
-               error(Etoosmall);
        bp = allocb(n);
        if (waserror()) {
                freeb(bp);
@@ -481,14 +489,10 @@ static long etherbwrite(struct chan *chan, struct block *bp, uint32_t unused)
                runlock(&ether->rwlock);
                nexterror();
        }
-       if (n > ether->maxmtu) {
+       if (n > ether->maxmtu && (bp->flag & Btso) == 0) {
                freeb(bp);
                error(Etoobig);
        }
-       if (n < ether->minmtu) {
-               freeb(bp);
-               error(Etoosmall);
-       }
        n = etheroq(ether, bp);
        poperror();
        runlock(&ether->rwlock);
@@ -636,7 +640,7 @@ int parseether(uint8_t * to, char *from)
 static void etherreset(void)
 {
        struct ether *ether;
-       int i, n, ctlrno;
+       int i, n, ctlrno, qsize;
        char name[KNAMELEN], buf[128];
 
        for (ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++) {
@@ -701,15 +705,23 @@ static void etherreset(void)
                        snprintf(buf + i, sizeof(buf) - i, "\n");
                        printk(buf);
 
-                       if (ether->netif.mbps == 100) {
-                               netifinit(&ether->netif, name, Ntypes, 256 * 1024);
-                               if (ether->oq == 0)
-                                       ether->oq = qopen(256 * 1024, Qmsg, 0, 0);
-                       } else {
-                               netifinit(&ether->netif, name, Ntypes, 64 * 1024);
-                               if (ether->oq == 0)
-                                       ether->oq = qopen(64 * 1024, Qmsg, 0, 0);
+                       switch (ether->netif.mbps) {
+
+                       case 1 ... 99:
+                               qsize = 64 * 1024;
+                               break;
+                       case 100 ... 999:
+                               qsize = 256 * 1024;
+                               break;
+                       case 1000 ... 9999:
+                               qsize = 1024 * 1024;
+                               break;
+                       default:
+                               qsize = 8 * 1024 * 1024;
                        }
+                       netifinit(&ether->netif, name, Ntypes, qsize);
+                       if (ether->oq == 0)
+                               ether->oq = qopen(qsize, Qmsg, 0, 0);
                        if (ether->oq == 0)
                                panic("etherreset %s", name);
                        ether->netif.alen = Eaddrlen;