File: Bug_549397-fix-decoding-of-MII-vendor-ids.patch

package info (click to toggle)
net-tools 2.10-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,888 kB
  • sloc: ansic: 14,668; makefile: 370; sh: 153
file content (55 lines) | stat: -rw-r--r-- 1,804 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Description: Fix decoding of MII vendor ids by mii-tool.
Bug-Debian: https://bugs.debian.org/549397
Author: Ben Hutchings <ben@decadent.org.uk>

--- a/mii-tool.c
+++ b/mii-tool.c
@@ -232,6 +232,14 @@
     return buf;
 }
 
+static unsigned char bitreverse_byte(unsigned char byte)
+{
+    byte = (byte << 4) | (byte >> 4);
+    byte = (byte & 0x33) << 2 | (byte & 0xcc) >> 2;
+    byte = (byte & 0x55) << 1 | (byte & 0xaa) >> 1;
+    return byte;
+}
+
 int show_basic_mii(int sock, int phy_id)
 {
     char buf[200];
@@ -335,11 +343,31 @@
 		break;
 	if (i < NMII)
 	    printf("%s rev %d\n", mii_id[i].name, mii_val[3]&0x0f);
-	else
-	    printf("vendor %02x:%02x:%02x, model %d rev %d\n",
+	else {
+	    /* Each OUI consists of 24 bits a-z of which a and b are
+	     * always assigned as zero.  The bit assignments in these
+	     * registers are specified as:
+	     *     2.15-0   c-r
+	     *     3.15-10  s-x
+	     * This is the opposite of the bit order within each byte
+	     * for the written representation specified in section
+	     * 9.5.2 of IEEE 802-2001.  However, some vendors mirror
+	     * the written representation, using the bit assignments:
+	     *     2.15-10  f-a (?)
+	     *     2.9-2    p-i
+	     *     2.1-0    x-w
+	     *     3.15-10  v-q
+	     * Therefore we decode the registers under both
+	     * interpretations.
+	     */
+	    printf("vendor %02x:%02x:%02x or %02x:%02x:%02x, model %d rev %d\n",
+		   bitreverse_byte(mii_val[2]>>10),
+		   bitreverse_byte(mii_val[2]>>2),
+		   bitreverse_byte((mii_val[2]<<6)|(mii_val[3]>>10)),
 		   mii_val[2]>>10, (mii_val[2]>>2)&0xff,
 		   ((mii_val[2]<<6)|(mii_val[3]>>10))&0xff,
 		   (mii_val[3]>>4)&0x3f, mii_val[3]&0x0f);
+	}
 	printf("  basic mode:   ");
 	if (bmcr & BMCR_RESET)
 	    printf("software reset, ");