Part Number: AM3358
Other Parts Discussed in Thread: AM3359
I have software based on the Starterware LWIP stack, but now heavily stripped down and bare metal. I'm using the CPSW in dual-MAC mode. All links are forced 100 Mb/s full duplex. The software works perfectly on the ICEv2.1 boards - I can transmit and receive on both Ethernet links.
I then run it on custom hardware, where:
- Port 1 is linked to an external PHY and magnetics which connects to a Micrel KSZ8895 switch. The PHY interface is MII.
- Port 2 is linked directly to a separate Micrel KSZ8895 switch, so the KSZ8895 acts as the PHY. The interface is MII.
- The processor is an AM3358-EP rather than an AM3359.
When I run the software on the custom hardware, I find that port 1 transmits and receives perfectly, port 2 transmits perfectly, but port 2 does not receive correctly.
Specifically, it does not generate a receive interrupt or forward data to port 0. However I can see the STATS registers correctly counting - it correctly counts unicast vs. broadcast and the correct frame size counters increment (for frames < 64 bytes and frames > 64 bytes). This proves that frames are actually entering the AM335x.
The obvious place to look is the interrupt config and ALE settings. However - I'm using the exact same interrupt config and ALE settings on both hardwares. The stats counters do not report any errors on any ports.
Any thoughts on this?
My ALE settings are very simple:
static void cpswif_port_to_host_vlan_cfg()
{
// Byte: 1 2 3 4 5 6 7 8 9
// VLAN entries
uint8_t entry1a[12] = {0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00};
uint8_t entry2a[12] = {0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00};
// Unicast entries
uint8_t entry1b[12] = {0x00, 0x02, 0x00, 0x0A, 0x00, 0x02, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00};
uint8_t entry2b[12] = {0x01, 0x02, 0x00, 0x0A, 0x00, 0x02, 0x02, 0x30, 0x00, 0x00, 0x00, 0x00};
ALETableEntrySet((uint32_t *)entry1a);
ALETableEntrySet((uint32_t *)entry1b);
ALETableEntrySet((uint32_t *)entry2a);
ALETableEntrySet((uint32_t *)entry2b);
}
Here's the basic CPSW config:
// Initialise ALE
*(volatile uint32_t *)(CPSW0_ALE_REGS + CPSW_ALE_CONTROL) = (CPSW_ALE_CONTROL_CLEAR_TABLE
| CPSW_ALE_CONTROL_ENABLE_ALE | CPSW_ALE_CONTROL_ALE_VLAN_AWARE);
/* Set the port 0, 1 and 2 states to FORWARD */
*(volatile uint32_t *)(CPSW0_ALE_REGS + 0x40U) &= ~CPSW_ALE_PORTCTL0_PORT_STATE;
*(volatile uint32_t *)(CPSW0_ALE_REGS + 0x40U) |= CPSW_ALE_PORT_STATE_FWD;
*(volatile uint32_t *)(CPSW0_ALE_REGS + 0x44U) &= ~CPSW_ALE_PORTCTL0_PORT_STATE;
*(volatile uint32_t *)(CPSW0_ALE_REGS + 0x44U) |= CPSW_ALE_PORT_STATE_FWD;
*(volatile uint32_t *)(CPSW0_ALE_REGS + 0x48U) &= ~CPSW_ALE_PORTCTL0_PORT_STATE;
*(volatile uint32_t *)(CPSW0_ALE_REGS + 0x48U) |= CPSW_ALE_PORT_STATE_FWD;
/* Set Dual Mac Mode */
*(volatile uint32_t *)(CPSW0_PORT_0_REGS + CPSW_PORT_TX_IN_CTL) &= ~CPSW_PORT_P0_TX_IN_CTL_TX_IN_SEL;
*(volatile uint32_t *)(CPSW0_PORT_0_REGS + CPSW_PORT_TX_IN_CTL) |= CPSW_PORT_P0_TX_IN_CTL_TX_IN_DUAL_MAC;
// Initialize the buffer descriptors for CPDMA
cpswif_cpdma_init();
/* Acknowledge receive and transmit interrupts for proper interrupt pulsing*/
*(volatile uint32_t *)(CPSW0_CPDMA_REGS + CPSW_CPDMA_CPDMA_EOI_VECTOR) = CPSW_EOI_TX_PULSE;
*(volatile uint32_t *)(CPSW0_CPDMA_REGS + CPSW_CPDMA_CPDMA_EOI_VECTOR) = CPSW_EOI_RX_PULSE;
/* Enable the interrupts for channel 0 and for control core 0 (wrapper) */
*(volatile uint32_t *)(CPSW0_CPDMA_REGS + CPSW_CPDMA_TX_INTMASK_SET) |= 1;
*(volatile uint32_t *)(CPSW0_WR_REGS + 0x10u + CPSW_CORE_INT_TX_PULSE) |= 1;
*(volatile uint32_t *)(CPSW0_CPDMA_REGS + CPSW_CPDMA_RX_INTMASK_SET) |= 1;
*(volatile uint32_t *)(CPSW0_WR_REGS + 0x10u + CPSW_CORE_INT_RX_PULSE) |= 1;
// Set up the MII interface.
*(volatile uint32_t *)(CPSW0_SLIVER_1_REGS + CPSW_SL_MACCONTROL)
|= (CPSW_SL_MACCONTROL_GMII_EN | CPSW_SL_MACCONTROL_FULL_DUPLEX);
// Set up the MII interface.
*(volatile uint32_t *)(CPSW0_SLIVER_2_REGS + CPSW_SL_MACCONTROL)
|= (CPSW_SL_MACCONTROL_GMII_EN | CPSW_SL_MACCONTROL_FULL_DUPLEX);
// Add ALE entries
cpswif_port_to_host_vlan_cfg();