NetBSD-Bugs archive

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

port-arm/49622: Minor enhancements to if_cpsw



>Number:         49622
>Category:       port-arm
>Synopsis:       Minor enhancements to if_cpsw
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-arm-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Feb 01 10:10:00 +0000 2015
>Originator:     Robert Sprowson
>Release:        
>Organization:
>Environment:
>Description:
These changes fix a couple of bugs and add clarity in a couple of places in the source. They are patches relative to revision 1.6 of src/sys/arch/arm/omap/if_cpsw.c and 1.2 of src/sys/arch/arm/omap/if_cpswreg.h details as follows.

if_cpswreg.h
~~~~~~~~~~~~
Add definitions of number of host ports (1) and ethernet ports (2) so they can be used as loop counters in the driver.
Add the other registers in CPSW_SL_.
Add the other flag bits in CPDMA_BD_.
Correct 2x spelling mistakes.

if_cpsw.c
~~~~~~~~~
Line 599:
Parenthesis added for clarity.
Line 818:
Use bit definitions from the header to build the register poke.
Also, remove the 'BYPASS' bit (4), otherwise all the careful setup of the ALE is futile - the BYPASS bit is described in the AM3358 datasheet as "When in bypass mode, all CPGMAC_SL received packets are forwarded only to the host port (port 0)" so effectively it's a promiscuous enable. This was confirmed by injecting some packets via a crossover cable with known non-matching EUI48 destination and observing they arrive on the interface (obviously with a switch in the way these would have been masked).
Line 921:
Make use of the MDIO defines from the header.
Line 959:
During cpsw_stop the MISC interrupts were being left enabled, looks like a copy & paste from cpsw_init.
General:
Couple of typos, swap to using host/ethernet port limits from the header file, some const's.

>How-To-Repeat:

>Fix:
--- if_cpsw_1_6.c	2014-10-31 17:12:48 +0000
+++ if_cpsw_new.c	2015-02-01 09:41:48 +0000
@@ -599,9 +599,9 @@
 			if (seg == 0)
 				dw[3] |= CPDMA_BD_SOP | CPDMA_BD_OWNER |
 				    MAX(mlen, CPSW_PAD_LEN);
 
-			if (seg == dm->dm_nsegs - 1 && !pad)
+			if ((seg == dm->dm_nsegs - 1) && !pad)
 				dw[3] |= CPDMA_BD_EOP;
 
 			cpsw_set_txdesc(sc, sc->sc_txnext, &bd);
 			txfree--;
@@ -818,13 +818,13 @@
 	/* Reset SS */
 	cpsw_write_4(sc, CPSW_SS_SOFT_RESET, 1);
 	while(cpsw_read_4(sc, CPSW_SS_SOFT_RESET) & 1);
 
-	/* Clear table (30) and enable ALE(31) and set passthrough (4) */
-	cpsw_write_4(sc, CPSW_ALE_CONTROL, (3 << 30) | 0x10);
+	/* Clear table and enable ALE */
+	cpsw_write_4(sc, CPSW_ALE_CONTROL, ALECTL_ENABLE_ALE | ALECTL_CLEAR_TABLE);
 
 	/* Reset and init Sliver port 1 and 2 */
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < CPSW_ETH_PORTS; i++) {
 		uint32_t macctl;
 
 		/* Reset */
 		cpsw_write_4(sc, CPSW_SL_SOFT_RESET(i), 1);
@@ -921,9 +921,9 @@
 	cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, CPSW_INTROFF_MISC);
 
 	/* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */
 	/* TODO Calculate MDCLK=CLK/(CLKDIV+1) */
-	cpsw_write_4(sc, MDIOCONTROL, (1<<30) | (1<<18) | 0xFF);
+	cpsw_write_4(sc, MDIOCONTROL, MDIOCTL_ENABLE | MDIOCTL_FAULTENB | MDIOCTL_CLKDIV(0xff));
 
 	mii_mediachg(mii);
 
 	/* Write channel 0 RX HDP */
@@ -959,9 +959,9 @@
 	cpsw_write_4(sc, CPSW_CPDMA_TX_INTMASK_CLEAR, 1);
 	cpsw_write_4(sc, CPSW_CPDMA_RX_INTMASK_CLEAR, 1);
 	cpsw_write_4(sc, CPSW_WR_C_TX_EN(0), 0x0);
 	cpsw_write_4(sc, CPSW_WR_C_RX_EN(0), 0x0);
-	cpsw_write_4(sc, CPSW_WR_C_MISC_EN(0), 0x1F);
+	cpsw_write_4(sc, CPSW_WR_C_MISC_EN(0), 0x0);
 
 	cpsw_write_4(sc, CPSW_CPDMA_TX_TEARDOWN, 0);
 	cpsw_write_4(sc, CPSW_CPDMA_RX_TEARDOWN, 0);
 	i = 0;
@@ -982,9 +982,9 @@
 	/* Reset SS */
 	cpsw_write_4(sc, CPSW_SS_SOFT_RESET, 1);
 	while(cpsw_read_4(sc, CPSW_SS_SOFT_RESET) & 1);
 
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < CPSW_ETH_PORTS; i++) {
 		cpsw_write_4(sc, CPSW_SL_SOFT_RESET(i), 1);
 		while(cpsw_read_4(sc, CPSW_SL_SOFT_RESET(i)) & 1);
 	}
 
@@ -1148,8 +1148,9 @@
 
 	tx0_cp = cpsw_read_4(sc, CPSW_CPDMA_TX_CP(0));
 
 	if (tx0_cp == 0xfffffffc) {
+		/* Teardown, ack it */
 		cpsw_write_4(sc, CPSW_CPDMA_TX_CP(0), 0xfffffffc);
 		cpsw_write_4(sc, CPSW_CPDMA_TX_HDP(0), 0);
 		sc->sc_txrun = false;
 		return 0;
@@ -1310,9 +1311,9 @@
 	ale_entry[1] = 0x0000ffff;
 }
 
 static void
-cpsw_ale_entry_set(uint32_t *ale_entry, ale_entry_filed_t field, uint32_t val)
+cpsw_ale_entry_set(uint32_t *ale_entry, ale_entry_field_t field, uint32_t val)
 {
 	/* Entry type[61:60] is addr entry(1), Mcast fwd state[63:62] is fw(3)*/
 	switch (field) {
 	case ALE_ENTRY_TYPE:
@@ -1367,9 +1368,9 @@
 	ale_entry[2] = cpsw_read_4(sc, CPSW_ALE_TBLW2);
 }
 
 static void
-cpsw_ale_write_entry(struct cpsw_softc *sc, uint16_t idx, uint32_t *ale_entry)
+cpsw_ale_write_entry(struct cpsw_softc *sc, uint16_t idx, const uint32_t *ale_entry)
 {
 	cpsw_write_4(sc, CPSW_ALE_TBLW0, ale_entry[0]);
 	cpsw_write_4(sc, CPSW_ALE_TBLW1, ale_entry[1]);
 	cpsw_write_4(sc, CPSW_ALE_TBLW2, ale_entry[2]);
@@ -1450,9 +1451,9 @@
 	cpsw_ale_entry_set(ale_entry, ALE_PORT_NUMBER, 0);
 	cpsw_ale_write_entry(sc, 0, ale_entry);
 
 	/* Set outgoing MAC Address for Ports 1 and 2. */
-	for (i = 1; i < 3; ++i)
+	for (i = 1; i < (CPSW_ETH_PORTS + CPSW_CPPI_PORTS); ++i)
 		cpsw_ale_set_outgoing_mac(sc, i, mac);
 
 	/* Keep the broadcast address at table entry 1. */
 	cpsw_ale_entry_init(ale_entry);

--- if_cpswreg_1.2.h	2014-10-31 17:15:02 +0000
+++ if_cpswreg_new.h	2015-02-01 09:36:24 +0000
@@ -28,8 +28,11 @@
 
 #ifndef	_IF_CPSWREG_H
 #define	_IF_CPSWREG_H
 
+#define CPSW_ETH_PORTS			2
+#define CPSW_CPPI_PORTS			1
+
 #define CPSW_SS_OFFSET			0x0000
 #define CPSW_SS_IDVER			(CPSW_SS_OFFSET + 0x00)
 #define CPSW_SS_SOFT_RESET		(CPSW_SS_OFFSET + 0x08)
 #define CPSW_SS_STAT_PORT_EN		(CPSW_SS_OFFSET + 0x0C)
@@ -87,12 +90,19 @@
 #define CPSW_ALE_TBLW0			(CPSW_ALE_OFFSET + 0x3C)
 #define CPSW_ALE_PORTCTL(p)		(CPSW_ALE_OFFSET + 0x40 + ((p) * 0x04))
 
 #define CPSW_SL_OFFSET			0x0D80
+#define CPSW_SL_IDVER(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x00)
 #define CPSW_SL_MACCONTROL(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x04)
+#define CPSW_SL_MACSTATUS(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x08)
 #define CPSW_SL_SOFT_RESET(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x0C)
 #define CPSW_SL_RX_MAXLEN(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x10)
+#define CPSW_SL_BOFFTEST(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x14)
+#define CPSW_SL_RX_PAUSE(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x18)
+#define CPSW_SL_TX_PAUSE(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x1C)
+#define CPSW_SL_EMCONTROL(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x20)
 #define CPSW_SL_RX_PRI_MAP(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x24)
+#define CPSW_SL_TX_GAP(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x28)
 
 #define MDIO_OFFSET			0x1000
 #define MDIOCONTROL			(MDIO_OFFSET + 0x04)
 #define MDIOUSERACCESS0			(MDIO_OFFSET + 0x80)
@@ -116,16 +126,26 @@
 
 #define __BIT32(x) ((uint32_t)__BIT(x))
 #define __BITS32(x, y) ((uint32_t)__BITS((x), (y)))
 
-/* flags for desciptor word 3 */
+/* flags for descriptor word 3 */
 #define CPDMA_BD_SOP		__BIT32(31)
 #define CPDMA_BD_EOP		__BIT32(30)
 #define CPDMA_BD_OWNER		__BIT32(29)
 #define CPDMA_BD_EOQ		__BIT32(28)
 #define CPDMA_BD_TDOWNCMPLT	__BIT32(27)
 #define CPDMA_BD_PASSCRC	__BIT32(26)
+
+#define CPDMA_BD_LONG		__BIT32(25) /* Rx descriptor only */
+#define CPDMA_BD_SHORT		__BIT32(24)
+#define CPDMA_BD_MAC_CTL	__BIT32(23)
+#define CPDMA_BD_OVERRUN	__BIT32(22)
 #define CPDMA_BD_PKT_ERR_MASK	__BITS32(21,20)
+#define CPDMA_BD_RX_VLAN_ENCAP	__BIT32(19)
+#define CPDMA_BD_FROM_PORT	__BITS32(18,16)
+
+#define CPDMA_BD_TO_PORT_EN	__BIT32(20) /* Tx descriptor only */
+#define CPDMA_BD_TO_PORT	__BITS32(17,16)
 
 struct cpsw_cpdma_bd {
 	uint32_t word[4];
 } __packed __aligned(4);
@@ -196,9 +216,9 @@
 	ALE_ENTRY_TYPE,
 	ALE_MCAST_FWD_STATE,
 	ALE_PORT_MASK,
 	ALE_PORT_NUMBER,
-} ale_entry_filed_t;
+} ale_entry_field_t;
 
 #define ALE_TYPE_FREE		0
 #define ALE_TYPE_ADDRESS	1
 #define ALE_TYPE_VLAN		2




Home | Main Index | Thread Index | Old Index