This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM8148 booting using an Ethernet switch in MII-PHY mode

The board we are developing has a DM8148 with its emac0 port connected to a Micrel KSZ8864 switch in RMII mode.

The KSZ8864's MII interface is pin-programmed to run in MII-PHY mode.

This setup works with the ROM Boot Loader, which loads and executes u-boot (stage 1).

Unfortunately u-boot is unable to access the network beyond this point.  No TFTP requests ever appear on the network/

Is there anything obvious about this setup that keeps it from working?  Is there some extra setup needed to use the CPSW

with a MII pretending to be a PHY?

In anticipation of the most obvious question EMAC[0]_MRXER (J26) is grounded through a 1K ohm resistor.

Thanks!

Erwin Kann

  • Erwin Kann

    Is the first stage u-boot built with ti8148_evm_min_eth?

    Are you able to manually download files in first stage u-boot?

    with regards

    Mugunthan V N

  • Mugnathan,

    Well, I built it with ti8148_evm_min_emac.  u-boot built this way works fine on the TMDXEVM8148 eval board,

    booting stage 2 and that in turn booting linux with no problems.  Our board replaces the 8031 RGMII PHY with

    a Micrel KSZ8864 switch, which uses an RMII interface.  Accordingly, we changed the boot mode BTMODE[9:8] bits

    and ROM Boot Loader works with this setup, loading and starting u-boot stage 1.  Its just that u-boot is not able to

    send out its TFTP requests to load stage 2.

    I first tried disabling PHY access--after all the Micrel was already pin-programmed to a useful state.

    That did not work, so I went over the PHY code to make sure it was compatible with the Micrel in MII-PHY mode.

    My posting here was hoping for something along the lines "of course when you switch from RGMII to RMII and PHY to MII-PHY

    you have to ...."   But if there is no "obvious" known issue, I'll just have to dog my way through everything until I find out the

    problem and make it work.

  • So far I have not made much progress.  I looked at a lot of data sheets, read a lot of manuals, printed out a lot of internal state.

    I changed the PHY address to 2, which is the only PHY address whose status register indicates Link Up.  Other PHY addresses

    are 1, 3, 4, and 5, but aside from toggling MDI/MDIX status (hunting for normal/reversed cat5 cabling) the other PHY addresses don't do anything.

    But  the CPSW still does not complete any DMA transfers, read or write.   The requests remain queued up and the DMA status always remains Idle

    (0x80000000).  The TFTP code reports timeouts every few seconds.  A Netgear switch show a "link" light the whole time.

    But its not the hardware--the RBL (ROM Boot Loader) is able to use the Micrel switch and network-boot without any problem.

    Is there something different between the way the RBL and u-boot use the CPSW?

  • Not sure if this will help. Or quite understand your situation. I take it you have the processor's EMAC connected directly to a switch chip without a PHY. Most of the net driver code in U-Boot and Linux are written with the assumption that a real PHY is connected. Without a real PHY to talk to, the driver thinks the link is never up. I've had to handle similiar situation with an Atmel / Marvell combination. Unfortunately, it takes a lot of code hacks in the driver code to get around this. A couple of approaches. Rework the driver code so that link negotiation is replaced with hard-coded link up and speed. Another way would be fake out the PHY registers so that the link negotiation code thinks that the link has been negotiated and is up. At times, I've seriously considered asking for a real PHY put into the HW design.

  • Erwin Kann

    Which PSP release are you using.

    with regards

    Mugunthan V N

  • I think you hit it right on the money.  The DM8148's CPSW is connected via RMII to a PHY port on the Micrel switch.  A different port on the Micrel

    switch actually goes out to the ethernet.  The only PHY which shows a Link Up status is the one connected to the ethernet, not the one directly

    connected to the processor.  The directly-connected PHY never reports link up, because it isn't really any more than an RMII interface.

    I need to somehow convince the CPSW to ignore Link Up, and perform its DMA without it.  Do you know how to do that?

    Somehow ROM Boot Loader avoids this obstacle, and is able to do a network boot on my system.  Do you know what it does differently?

  • We started with psp04.01.00.06, and modified it a lot to successfully network boot the evaluation board.

  • One approach is to hard-code the link details for the CPU's port. I'll use the omap-3 u-boot git drivers/net/cpsw.c file as an example.

    static void cpsw_slave_update_link(struct cpsw_slave *slave,
      struct cpsw_priv *priv, int *link)
    {
      char *name = priv->dev->name;
      int phy_id = slave->data->phy_id;
      int speed, duplex;
      unsigned short reg;
      u32 mac_control = 0;

      if(phy_id == YOUR_CPU_PHY_ID)                           /*ADD */
      {                                                       /*ADD */
        speed  = YOUR_RMII_SPEED;                             /*ADD */
        duplex = FULL;                                        /*ADD */
       *link   = 1;                                           /*ADD */
        ,,, Setup mac_control similiar to real PHY below.     /*ADD */
      }                                                       /*ADD */
      else /*ADD */
      { /*ADD */
        if (miiphy_read(name, phy_id, PHY_BMSR, &reg))
          return; /* could not read, assume no link */

        if (reg & PHY_BMSR_LS) { /* link up */
          speed = miiphy_speed(name, phy_id);
          duplex = miiphy_duplex(name, phy_id);
         *link = 1;
          mac_control = priv->data.mac_control;
          if (speed == 1000)
            mac_control |= BIT(7); /* GIGABITEN    */
            if (duplex == FULL)
               mac_control |= BIT(0); /* FULLDUPLEXEN    */
        }
      }                                                         /*ADD */

      if (mac_control == slave->mac_control)
         return;

      if (mac_control) {
        printf("link up on port %d, speed %d, %s duplex\n",
                slave->slave_num, speed,
                (duplex == FULL) ?  "full" : "half");
      } else {
         printf("link down on port %d\n", slave->slave_num);
      }

      __raw_writel(mac_control, &slave->sliver->mac_control);
      slave->mac_control = mac_control;
    }

    The other way would be emulate the PHY registers with an array. A bit more work as you have to initialize the array with the correct register values for speed, duplex, etc. The fake PHY register array would be accessed for the CPU port in cpsw_mdio_read() and cpsc_mdio_write(). Other ports would pass through to the real MDIO port. This approach is a bit more elegant. A bit more time consuming to look up the PHY register constants and build the fake values.

    You might be lucky and your U-Boot or Linux may have code for this situation. Search for compilation flags with names like FIXED_PHY.

  • Norman,

    I have been basically following the approach you outlined.   On my board, PHY address 2 (the one I configured as phy_id)

    actually indicates link up.   And the CPSW DMA descriptors seem to be getting set up properly.  But it seems that no data ever

    gets transferred.  It seems like the CPSW is holding back for some unknown reason.

    I discovered the CPSW  PHY Alive status register (TRM 9.4.2.3), and the PHY Link status register.  The first

    one returns 0x3E, consistent with the PHY addresses 1-5 which I see, and the second returns 0x04, consistent with

    PHY address 2 being the only one which reports link up.  So it is obvious that the CPSW is polling the PHY register

    space via the MDIO interface.  But something keeps the CPSW from transferring any data.

    I'm going to try changing the PHY register write (cpsw_mdio_write) to write the same register in all the available PHYs,

    but only read from PHY 2 (the one connected to the external network).

  • My experience is with the Marvell switch...the Micrel will probably be different. On that switch, the processor was connected to port 0. Any real PHYs connected to the switch had to have MDIO IDs that matched the port, ie port 1 would have to a MDIO ID of 1. The key was getting U-Boot and Linux to think port 0 (with virtual PHY with MDIO ID 0) was up and connected. Since your real PHY is at 2, I think that your processor should be some other PHY id other than 2.

  • Norman,

    It turns out our problem was mostly fixed by moving the u-boot network data buffers from DDR3 into SRAM (they just fit!)

    Is there an issue using the CPSW DMA controller with a 16-bit-wide DRAM?   Is there a setting in the CPSW and/or

    DRAM controller that must be changed?

    Our DDR3 consists of two 256Meg  x 16bit chips, each one wired to a separate EMIF port.

    Erwin Kann

  • Good to here. Sorry...I know little about the CPSW DMA or DMA. If I were to guess, it might be DRAM timing problem. DMA is harder on timing than PIO access. SRAM rarely has timing problems. That's all I got. Hopefully some DMA experts chime in.