NetBSD Problem Report #49622
From www@NetBSD.org Sun Feb 1 10:07:55 2015
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 69D35A654C
for <gnats-bugs@gnats.NetBSD.org>; Sun, 1 Feb 2015 10:07:55 +0000 (UTC)
Message-Id: <20150201100753.B42A6A65B8@mollari.NetBSD.org>
Date: Sun, 1 Feb 2015 10:07:53 +0000 (UTC)
From: webpages@sprow.co.uk
Reply-To: webpages@sprow.co.uk
To: gnats-bugs@NetBSD.org
Subject: Minor enhancements to if_cpsw
X-Send-Pr-Version: www-1.0
>Number: 49622
>Category: port-arm
>Synopsis: Minor enhancements to if_cpsw
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: skrll
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Feb 01 10:10:00 +0000 2015
>Closed-Date: Fri Mar 27 09:16:49 +0000 2015
>Last-Modified: Fri Mar 27 09:16:49 +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
>Release-Note:
>Audit-Trail:
From: Sprow <webpages@sprow.co.uk>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: port-arm/49622: Minor enhancements to if_cpsw
Date: Wed, 11 Feb 2015 08:14:58 +0000 (GMT)
Patch updated to apply against if_cpsw.c revision 1.7.
if_cpsw.c
~~~~~~~~~
Line 875:
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 1016:
During cpsw_stop the MISC interrupts were being left enabled, looks like a
copy & paste mistake from cpsw_init.
Line 1205:
Remove unnecessary calculation of cpi, since it's recalculated as the second
thing inside the loop that processes receive buffers.
General/others:
Couple of typos, swap to using host/ethernet port limits from the header
file as for loop limits, some const's, parenthesis for clarity.
--- if_cpsw_1_7.c 2015-02-01 20:35:10 +0000
+++ if_cpsw_new.c 2015-02-11 08:12:34 +0000
@@ -656,7 +656,7 @@
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);
@@ -875,11 +875,11 @@
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 */
@@ -976,9 +976,9 @@
cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, CPSW_INTROFF_TX);
cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, CPSW_INTROFF_MISC);
- /* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */
+ /* Initialize 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);
@@ -1016,7 +1016,7 @@
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);
@@ -1039,7 +1039,7 @@
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);
}
@@ -1205,14 +1205,13 @@
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;
}
- cpi = (tx0_cp - sc->sc_txdescs_pa) / sizeof(struct cpsw_cpdma_bd);
-
for (;;) {
tx0_cp = cpsw_read_4(sc, CPSW_CPDMA_TX_CP(0));
cpi = (tx0_cp - sc->sc_txdescs_pa) / sizeof(struct cpsw_cpdma_bd);
@@ -1367,7 +1366,7 @@
}
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) {
@@ -1424,7 +1423,7 @@
}
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]);
@@ -1507,7 +1506,7 @@
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 = CPSW_CPPI_PORTS; i < (CPSW_ETH_PORTS + CPSW_CPPI_PORTS); ++i)
cpsw_ale_set_outgoing_mac(sc, i, mac);
/* Keep the broadcast address at table entry 1. */
Responsible-Changed-From-To: port-arm-maintainer->skrll
Responsible-Changed-By: skrll@NetBSD.org
Responsible-Changed-When: Thu, 12 Mar 2015 20:52:59 +0000
Responsible-Changed-Why:
Take
From: "Nick Hudson" <skrll@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/49622 CVS commit: src/sys/arch/arm/omap
Date: Fri, 13 Mar 2015 08:56:35 +0000
Module Name: src
Committed By: skrll
Date: Fri Mar 13 08:56:35 UTC 2015
Modified Files:
src/sys/arch/arm/omap: if_cpsw.c if_cpswreg.h
Log Message:
Stylistic and non-functional changes from
PR/49622 (Minor enhancements to if_cpsw)
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/omap/if_cpsw.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/omap/if_cpswreg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->feedback
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Thu, 26 Mar 2015 22:03:51 +0000
State-Changed-Why:
Fixes committed. OK to close?
From: "Nick Hudson" <skrll@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/49622 CVS commit: src/sys/arch/arm/omap
Date: Thu, 26 Mar 2015 22:00:46 +0000
Module Name: src
Committed By: skrll
Date: Thu Mar 26 22:00:45 UTC 2015
Modified Files:
src/sys/arch/arm/omap: if_cpsw.c
Log Message:
Fixes from PR/49622
- Use bit definitions from the header instead of magic numbers
- 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
- During cpsw_stop the MISC interrupts were being left enabled
- Remove unnecessary cpi assignment before loop.
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/omap/if_cpsw.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Robert Sprowson <webpages@sprow.co.uk>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: port-arm/49622 (Minor enhancements to if_cpsw)
Date: Fri, 27 Mar 2015 08:55:54 +0000 (GMT)
On 26 Mar, <skrll@NetBSD.org> wrote:
> Fixes committed. OK to close?
Looks good to close. Thanks for picking this PR up.
State-Changed-From-To: feedback->closed
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Fri, 27 Mar 2015 09:16:49 +0000
State-Changed-Why:
Fixed
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.