Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

zynq ethernet



Is anyone using ethernet on zynq ?

I couldn't get IPv6 to work at all without most of the following
patches as there seems to be something wrong with multicast handling.

I'm just making it accept all multicast packets for now until I debug
the hashing code.

Most of these changes should probably be made to the at91 emac driver
too.

I would split this up a bit before committing anything.

Robert Swindells

Index: cemacreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/cadence/cemacreg.h,v
retrieving revision 1.1
diff -u -r1.1 cemacreg.h
--- cemacreg.h	23 Jan 2015 12:34:09 -0000	1.1
+++ cemacreg.h	21 Jul 2015 23:13:55 -0000
@@ -109,6 +109,8 @@
 #define	GEM_SA3H	0x009C
 #define	GEM_SA4L	0x0090
 #define	GEM_SA4H	0x0094
+#define	GEM_SCOL	0x0138
+#define	GEM_MCOL	0x013C
 #define	GEM_DCFG2	0x0284
 #define	GEM_DCFG3	0x0288
 #define	GEM_DCFG4	0x028C
Index: if_cemac.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cadence/if_cemac.c,v
retrieving revision 1.2
diff -u -r1.2 if_cemac.c
--- if_cemac.c	20 May 2015 09:17:18 -0000	1.2
+++ if_cemac.c	21 Jul 2015 23:13:55 -0000
@@ -100,7 +100,7 @@
 	} while(0)
 
 #define RX_QLEN 64
-#define	TX_QLEN	2		/* I'm very sorry but that's where we can get */
+#define	TX_QLEN	64		/* I'm very sorry but that's where we can get */
 
 struct cemac_qmeta {
 	struct mbuf 	*m;
@@ -355,6 +355,7 @@
 				sc->RDSC[bi].Addr =
 					sc->rxq[bi].m_dmamap->dm_segs[0].ds_addr
 					| (bi == (RX_QLEN-1) ? ETH_RDSC_F_WRAP : 0);
+				ifp->if_ipackets++;
 			} else {
 				/* Drop packets until we can get replacement
 				 * empty mbufs for the RXDQ.
@@ -689,7 +690,10 @@
 	struct ifnet * ifp = &sc->sc_ethercom.ec_if;
 	int s;
 
-	ifp->if_collisions += CEMAC_READ(ETH_SCOL) + CEMAC_READ(ETH_MCOL);
+	if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM))
+		ifp->if_collisions += CEMAC_READ(GEM_SCOL) + CEMAC_READ(GEM_MCOL);
+	else
+		ifp->if_collisions += CEMAC_READ(ETH_SCOL) + CEMAC_READ(ETH_MCOL);
 	/* These misses are ok, they will happen if the RAM/CPU can't keep up */
 	if (!ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) {
 		uint32_t misses = CEMAC_READ(ETH_DRFC);
@@ -945,7 +949,7 @@
 			 * ranges is for IP multicast routing, for which the
 			 * range is big enough to require all bits set.)
 			 */
-			cfg |= ETH_CFG_CAF;
+			cfg |= ETH_CFG_MTI;
 			hashes[0] = 0xffffffffUL;
 			hashes[1] = 0xffffffffUL;
 			ifp->if_flags |= IFF_ALLMULTI;
@@ -965,8 +969,12 @@
 
 			/* Just want the 6 most-significant bits. */
 			h = h >> 26;
-
+#if 0
 			hashes[h / 32] |=  (1 << (h % 32));
+#else
+			hashes[0] = 0xffffffffUL;
+			hashes[1] = 0xffffffffUL;
+#endif
 			cfg |= ETH_CFG_MTI;
 		}
 		ETHER_NEXT_MULTI(step, enm);
@@ -982,7 +990,7 @@
 	    | (sc->sc_enaddr[0]));
 	CEMAC_GEM_WRITE(SA1H, (sc->sc_enaddr[5] << 8)
 	    | (sc->sc_enaddr[4]));
-	if (nma > 1) {
+	if (nma > 0) {
 		DPRINTFN(1,("%s: en1 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
 			ias[0][0], ias[0][1], ias[0][2],
 			ias[0][3], ias[0][4], ias[0][5]));
@@ -992,7 +1000,7 @@
 		CEMAC_WRITE(ETH_SA2H, (ias[0][4] << 8)
 		    | (ias[0][5]));
 	}
-	if (nma > 2) {
+	if (nma > 1) {
 		DPRINTFN(1,("%s: en2 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
 			ias[1][0], ias[1][1], ias[1][2],
 			ias[1][3], ias[1][4], ias[1][5]));
@@ -1002,14 +1010,14 @@
 		CEMAC_WRITE(ETH_SA3H, (ias[1][4] << 8)
 		    | (ias[1][5]));
 	}
-	if (nma > 3) {
+	if (nma > 2) {
 		DPRINTFN(1,("%s: en3 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
 			ias[2][0], ias[2][1], ias[2][2],
 			ias[2][3], ias[2][4], ias[2][5]));
-		CEMAC_WRITE(ETH_SA3L, (ias[2][3] << 24)
+		CEMAC_WRITE(ETH_SA4L, (ias[2][3] << 24)
 		    | (ias[2][2] << 16) | (ias[2][1] << 8)
 		    | (ias[2][0]));
-		CEMAC_WRITE(ETH_SA3H, (ias[2][4] << 8)
+		CEMAC_WRITE(ETH_SA4H, (ias[2][4] << 8)
 		    | (ias[2][5]));
 	}
 	CEMAC_GEM_WRITE(HSH, hashes[0]);


Home | Main Index | Thread Index | Old Index