net: Split hw_features out from feat
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 13 Nov 2017 19:20:57 +0000 (14:20 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Nov 2017 15:46:56 +0000 (10:46 -0500)
hw_features is what is possible; feat is what is turned on *or* other Plan
9 characteristics.  Notably, NETF_PADMIN is more of a signal that the NIC
will pad to the mintu.  It's not something the hardware will turn on or
off.

By #defining hw_features to feat, we were possibly turning on things that
shouldn't be on by default.  Likewise, an = (instead of |=) could clobber
values of feat.  It was all quite nasty.

Note that the name 'feat' is an ABI to some extent.  etherbind() looks for
that string when it decides which features get added to the Ipifc.  If we
have dynamic features and want them to actually take affect to IP stacks
bound to a NIC, then we'll need to propagate those changes to Ipifc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/linux_compat.h
kern/include/net/ip.h
kern/src/net/netif.c

index 9f30332..72eb44a 100644 (file)
@@ -524,11 +524,6 @@ static void free_netdev(struct ether *dev)
 /* u64 on linux, but a u32 on plan 9.  the typedef is probably a good idea */
 typedef unsigned int netdev_features_t;
 
-/* Linux has features, hw_features, and a couple others.  Plan 9 just has
- * features.  This #define should work for merging hw and regular features.  We
- * spatched away the hw_enc and vlan feats. */
-#define hw_features feat
-
 /* Attempted conversions for plan 9 features.  For some things, like rx
  * checksums, the driver flags the block (e.g. Budpck) to say if a receive
  * checksum was already done.  There is no flag for saying the device can do
index 844ea70..7d83e4d 100644 (file)
@@ -1077,7 +1077,8 @@ struct netif {
        int alen;                                       /* address length */
        int mbps;                                       /* megabits per sec */
        int link;                                       /* link status */
-       unsigned int feat;                              /* dev features */
+       unsigned int feat;                      /* dev features turned on */
+       unsigned int hw_features;       /* dev features available */
        uint8_t addr[Nmaxaddr];
        uint8_t bcast[Nmaxaddr];
        struct netaddr *maddr;          /* known multicast addresses */
index 9b27181..058713e 100644 (file)
@@ -262,6 +262,28 @@ struct chan *netifopen(struct ether *nif, struct chan *c, int omode)
        return c;
 }
 
+/* Helper for building the features for netifread */
+static int feature_appender(int features, char *p, int sofar)
+{
+       if (features & NETF_IPCK)
+               sofar += snprintf(p + sofar, READSTR - sofar, "ipck ");
+       if (features & NETF_UDPCK)
+               sofar += snprintf(p + sofar, READSTR - sofar, "udpck ");
+       if (features & NETF_TCPCK)
+               sofar += snprintf(p + sofar, READSTR - sofar, "tcpck ");
+       if (features & NETF_PADMIN)
+               sofar += snprintf(p + sofar, READSTR - sofar, "padmin ");
+       if (features & NETF_SG)
+               sofar += snprintf(p + sofar, READSTR - sofar, "sg ");
+       if (features & NETF_TSO)
+               sofar += snprintf(p + sofar, READSTR - sofar, "tso ");
+       if (features & NETF_LRO)
+               sofar += snprintf(p + sofar, READSTR - sofar, "lro ");
+       if (features & NETF_RXCSUM)
+               sofar += snprintf(p + sofar, READSTR - sofar, "rxcsum ");
+       return sofar;
+}
+
 long
 netifread(struct ether *nif, struct chan *c, void *a, long n,
          uint32_t offset)
@@ -303,24 +325,15 @@ netifread(struct ether *nif, struct chan *c, void *a, long n,
                        for (i = 0; i < nif->alen; i++)
                                j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
                        j += snprintf(p + j, READSTR - j, "\n");
+
                        j += snprintf(p + j, READSTR - j, "feat: ");
-                       if (nif->feat & NETF_IPCK)
-                               j += snprintf(p + j, READSTR - j, "ipck ");
-                       if (nif->feat & NETF_UDPCK)
-                               j += snprintf(p + j, READSTR - j, "udpck ");
-                       if (nif->feat & NETF_TCPCK)
-                               j += snprintf(p + j, READSTR - j, "tcpck ");
-                       if (nif->feat & NETF_PADMIN)
-                               j += snprintf(p + j, READSTR - j, "padmin ");
-                       if (nif->feat & NETF_SG)
-                               j += snprintf(p + j, READSTR - j, "sg ");
-                       if (nif->feat & NETF_TSO)
-                               j += snprintf(p + j, READSTR - j, "tso ");
-                       if (nif->feat & NETF_LRO)
-                               j += snprintf(p + j, READSTR - j, "lro ");
-                       if (nif->feat & NETF_RXCSUM)
-                               j += snprintf(p + j, READSTR - j, "rxcsum ");
-                       snprintf(p + j, READSTR - j, "\n");
+                       j = feature_appender(nif->feat, p, j);
+                       j += snprintf(p + j, READSTR - j, "\n");
+
+                       j += snprintf(p + j, READSTR - j, "hw_features: ");
+                       j = feature_appender(nif->hw_features, p, j);
+                       j += snprintf(p + j, READSTR - j, "\n");
+
                        n = readstr(offset, a, n, p);
                        kfree(p);
                        return n;