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.

Enable EMAC1 only in ti8148 board

Hi, I am trying to disable EMAC0 and only enable EMAC1 on ti8148 custom board in Linux. I have tried these things to achieve that,

1. Enable only EMAC1 in  cpsw_slave_data, and commented out the EMAC0.

2. Make slaves=1 in cpsw_platform_data.

3. Made cpsw_slaves[0].phy_id = "0:01";

I am unable to make the EMAC1 work when disabling the EMAC0 slave data. EMAC1 works when both the slave data are enabled.

Please some one tell me if i am doing the correct thing.

Thanks

  • Chaitanya

    You don't need to modify the driver, Linux driver will work if EMAC1 is connected without any change in driver.

    Regards
    Mugunthan V N

  • Thanks for your reply Mugunthan,

    I am sorry, i didnt mention that i was doing the said changes in the board file of ti8148evm (board-ti8148evm.c). And i have not done pin mux for EMAC0 (because those pins are used for some other purpose).

    Yes, the EMAC1 is working when i have the board file as it is with both the slave data populated in to the cpsw_slaves structure, however my doubt is that will it impact the working of EMAC1? dont we have to NOT populate the EMAC0 slave data, because we are not using it?

    Thanks

  • Hi,

    As i can see in the cpsw driver (drivers/net/cpsw.c), the port number for setting the ALE registers is taken from the place of the slave member in the cpsw_slave_data structure in the arch/arm/mach-omap2/devices.c, using  "cpsw_get_slave_port" i.e if the slave member is in the first place in the structure, its taken as port 1 and if in the second place then as port2, this is why when i try to interchange the cpsw_slave_data members, the EMAC doesnt work.

    How ever when i hardcode the slave port to be 2, and interchange the slave members in the cpsw_slave_data structure (i.e EMAC1 in first place and EMAC0 in second place), the EMAC1 works fine, but when i make "slaves = 1" in the cpsw_platform_data structure in the arch/arm/mach-omap2/devices.c, so that EMAC0 slave data gets disabled, the EMAC1 doesnt work.

    Has any one observed this behaviour of driver? is this the way the driver is meant to work?, means the EMAC0 has to be enabled for the EMAC1 to work, but EMAC0 works without the EMAC1 enabled.

  • Chaitanya

    No need to change all the slave data changes in the driver and change alve_count = 1, as switch will take care of forwarding to the proper port.
    The slave count is used in various location where ALE table and offset is calculated, so it is advised not to change the slave count in devices.c file.

    Regards
    Mugunthan V N

  • Thanks Mugunthan,

    Since we have only EMAC1 in our board, I have removed the boundry checks in the cpsw_ale.c file which is done when setting the ale control register (this is where the slave count is taken in to consideration). And also I have hard coded the "cpsw_get_slave_port" to return 2 always. Now the EMAC1 works alone.

    I have another query about the u-boot EMAC1 bring up: I have followed these instructions,

    • In evm file:
      • Add pinmux for CPSW EMAC 1 in cpsw_pad_config()
      • Interchange the cpsw_slaves platform data.
    • In driver: make cpsw_get_slave_port to return CPSW port 2 offset ie "2"

    The  ethernet in u-boot works, but after 10-15 iterations of testing the ethernet (i power off and power on the board every iteration), i get this message:

    "failed to read bmcr". As i can see that this means that we are not able to read the PHY registers, I have tried to read other registers, it doesnt work. I suspect the MDIO clk speed.

    Can you please give me some inputs on this.

  • Chaitanya

    The error denotes that phy read is failed. Can you check hardware points to verify whether the MDIO clock and data line are proper.
    Also during this error, can you try to read the phy registers using MII command and verfy MDIO link.

    Regards
    Mugunthan V N

  • chaitanya godavarthi said:

    Thanks Mugunthan,

    Since we have only EMAC1 in our board, I have removed the boundry checks in the cpsw_ale.c file which is done when setting the ale control register (this is where the slave count is taken in to consideration). And also I have hard coded the "cpsw_get_slave_port" to return 2 always. Now the EMAC1 works alone.

    I am facing the same issue. Would you mind detailing the list of changes you made? The end result was that you

    1. interchanged the cpsw_slaves members
    2. changed the cpsw_slaves[0].phy_id to "0:01"
    3. made cpsw_get_slave_port always return 2
    4. modified bounds checking in cpsw_ale.c (please explain?)
    5. did you change the cpsw_platform_data.slaves to 1 or leave it as 2?
    Also, i saw in the CPSW driver code a define for CONFIG_TI_CPSW_DUAL_EMAC. It's not "y" (or even present) in the defconfig file. Did you add it and set it to "=y" ?
    Thank you
  • Hi Dennis,

    This is the work around i have done:

    1. Interchanged the cpsw_slaves member

    A: No, I commented the second member and put the EMAC1's data in the first member.

    2. changed the cpsw_slaves[0].phy_id to "0:01"

    A. Yes, but this anyway depends on your PHY ID.

    3. made cpsw_get_slave_port always return 2

    A: Yes

    4. modified bounds checking in cpsw_ale.c (please explain?)

    A: cpsw_ale_control_set and cpsw_ale_control_get in cpsw_ale.c have boundry checks for "port" (ale_port) which is between "0 and cpsw_platform_data.slaves value" which is 0 - 1 in our case, but we pass 2 to it always. So i have commented out those boundary checks.

    5. did you change the cpsw_platform_data.slaves to 1 or leave it as 2?

    A: Changed to 1.

    CONFIG_TI_CPSW_DUAL_EMAC is not required if you have single EMAC.

    Thanks

    Chaitanya

  • FYI, I've been working with the u-boot cpsw drivers and enabling EMAC0 and EMAC1 independently on the TI8148 and while the comments above are close, there's a small detail you're missing (I believe, apologies if you know this)

    First off, I modified the priv data structure to update the slave member details. As long as I had both slaves in the, and slaves==2 I could link on either port, however whenever I put only one slave in the list it would only work for EMAC0 and not EMAC1, even if I swapped the reg/phy id's over in the structure.

    The comment about about returning '2' on cpsw_get_slave_port is kind of close to the fix, in that it works, but it's actually going wrong a little sooner.

    The cpsw_register is called, it loops through each slave calling cpsw_slave_setup.

       for_each_slave(priv,cpsw_slave_setup,idx,priv);

    The idx parameter here is passed as the 'slave number' and thus counts up from 0 for each successive slave instance. This is then explicitly assigned to the slaves 'slave number' member in the cpsw_slave_setup routine.

    cpsw_get_slave_port actually just returns this value - with a hack for whether the host port is 0 or not (if the host port is 0, then the slave port is incremented by one, since there are actually three MAC's on the CPSW and EMAC0/EMAC1 are ports 2 and 3 in effect ).

    By hard coding the response you're basically avoiding the bug in the for_each_slave loop.

    The better solution is actually to pass in the proper slave number so that the slave details record the actual EMAC mapped to the slave/phy combination. This would then make it possible to have EMAC0, EMAC1 or both enabled appropriately, instead of assuming that they are always both assigned (in that order) or only EMAC0 is assigned.

    I have yet to modify the code to do this, but my expectation is that I'd have to add a member to the slave data structure to record the controller id, and then use this instead of idx when calling cpsw_slave_setup.

    For myself however, I am able to just simply define EMAC0/EMAC1 as present in the cpsw data structures, and then just disable the RGMII pin mux/GMII SEL register so only one port actually get's sent out to the pins. It's a fudge and does mean that any ping/network access initis both MAC's , waits for one to time out with no auto-neg response and then continues.

    Hope this helps a little...

    Ian