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.

AM3358: icss_emac on custom board not sending packages

Part Number: AM3358

Hello,

we want to switch from the prueth driver to the userspace icss_emac driver and we have some trouble to get it running.

The Problem:

If we run the modified version of icss_emacMainTest_am335x.out (to match our hardware) we see that no packages are sent. (checked via WireShark)

The init shows no errors and the firmware is loaded to the PRU. (at least the ICSS_EMAC_testFwVerValidate reads the right version back)

 But the only interrupt and callback that are called are the ones related to the link status.

I assume our problems with the icss_emac driver are not hardware related because we used the prueth driver for a long time and it was working as intended.

I read through various posts on this topic. like:

https://e2e.ti.com/support/processors/f/processors-forum/799760/linux-am3359-icss-emac-test-on-custom-board-with-linux-uio_module_drv

This post was the most helpful, but it has two major differences

1. It uses a dual emac setup. (we have a single emac)

2. The sending process seems to do at least something. (ARP)

Custom board hardware description:

We have two ethernet ports on our hardware: 

eth0 is a cpsw_emac (normal MII)

eth1 is connected to MII1_PRUSS1 peripherals according to the TI PinMux tool

So we only have one ethernet port connect to the PRUSS.

dts file :

/*
 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;

#include "am33xx.dtsi"
#include <dt-bindings/interrupt-controller/irq.h>

/ {
	model = "TI AM335x Custom";
	compatible = "ti,am3359-icev2" ,"ti,am335x-custom" , "ti,am33xx";

	cpus {
		cpu@0 {
			cpu0-supply = <&vdd1_reg>;
		};
	};

	memory@80000000 {
		device_type = "memory";
		reg = <0x80000000 0x20000000>; /* 512 MB */
	};

	chosen {
		stdout-path = &uart0; 
		bootargs = "console=ttyO0,115200n8";
	};

	/* Dual mac ethernet application node on icss */
	pruss_eth: pruss_eth {
		compatible = "ti,am3359-prueth";
		prus = <&pru0> , <&pru1>;
		firmware-name = "","ti-pruss/am335x-pru1-prueth-fw.elf";
		sram = <&ocmcram>;
		interrupt-parent = <&pruss_intc>;
		mii-rt = <&pruss_mii_rt>;
		iep = <&pruss_iep>;
 		pinctrl-0 = <&mii2_pru_pins_default>;
		pinctrl-names = "default";
		
		pruss_emac1: ethernet-mii1 {
			phy-handle = <&pruss_eth1_phy>;
			phy-mode = "mii";
			interrupts = <21>, <23>;
			interrupt-names = "rx", "tx";
			/* Filled in by bootloader */
			local-mac-address = [00 00 00 00 00 00];
		};
	};  

	vbat: fixedregulator0 {
		compatible = "regulator-fixed";
		regulator-name = "vbat";
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
		regulator-boot-on;
	};
};

&am33xx_pinmux {
	pinctrl-names = "default";
	/* if you want to test the GPIOs over PRU Make MUX_MODE5 */
	led_pins_default: led_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLUP | MUX_MODE7) /* LED_ERR 	(R5) lcd_hsync.gpio2[23] */
			AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLUP | MUX_MODE7) /* LED_RUN 	(V5) lcd_pclk.gpio2[24]  */
			AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLUP | MUX_MODE7) /* LED_COM 	(U5) lcd_vsync.gpio2[22] */
			AM33XX_IOPAD(0x95c, PIN_OUTPUT_PULLUP | MUX_MODE7) /* LED_1		(A16) spi0_cs0.gpio0[5]  */
			AM33XX_IOPAD(0x838, PIN_OUTPUT_PULLUP | MUX_MODE7) /* LED_2		(V13) gpmc_ad14.gpio1[14] */ 
		>;
	};

	gpio_input_pins_default: gpio_input_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x89c, PIN_INPUT | MUX_MODE7) /* (T6) gpmc_be0n_cle.gpio2[5] */
		>;
	};
	

	i2c1_pins_default: i2c1_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x984, PIN_INPUT_PULLUP | MUX_MODE3) /* (D15) uart1_txd.I2C1_SCL */
			AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE3) /* (D16) uart1_rxd.I2C1_SDA */
		>;
	};

	i2c0_pins_default: i2c0_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* (C16) I2C0_SCL.I2C0_SCL */
			AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* (C17) I2C0_SDA.I2C0_SDA */
		>;
	};

	mdio_pins_default: mdio_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* (M18) mdio_clk.mdio_clk */
			AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* (M17) mdio_data.mdio_data */
		>;
	};

	/* Optional sleep pin settings. Must manually enter values in the below skeleton. */
	mdio_pins_sleep: mdio_pins_sleep {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M18) mdio_clk.mdio_clk */
			AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M17) mdio_data.mdio_data */
		>;
	};

	mdio_mii2_pins_default: mdio_mii2_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x88c, PIN_OUTPUT_PULLUP | MUX_MODE5) /* (V12) gpmc_clk.pr1_mdio_mdclk */
			AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE5) /* (T13) gpmc_csn3.pr1_mdio_data */
		>;
	};

	/* Optional sleep pin settings. Must manually enter values in the below skeleton. */
	mdio_mii2_pins_sleep: mdio_mii2_pins_sleep {
		pinctrl-single,pins = <
		/*	AM33XX_IOPAD(0x88c, PIN_INPUT_PULLDOWN | MUX_MODE7)  (V12) gpmc_clk.pr1_mdio_mdclk */
		/* 	AM33XX_IOPAD(0x888, PIN_INPUT_PULLDOWN | MUX_MODE7)  (T13) gpmc_csn3.pr1_mdio_data */
		>;
	};


	mii1_pins_default: mii1_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxerr.mii1_rxerr */
			AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txen.mii1_txen */
			AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxdv.mii1_rxdv */
			AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd3.mii1_txd3 */
			AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd2.mii1_txd2 */
			AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd1.mii1_txd1 */
			AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd0.mii1_txd0 */
			AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_txclk.mii1_txclk */
			AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxclk.mii1_rxclk */
			AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd3.mii1_rxd3 */
			AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd2.mii1_rxd2 */
			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd1.mii1_rxd1 */
			AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd0.mii1_rxd0 */
		>;
	};

	/* Optional sleep pin settings. Must manually enter values in the below skeleton. */
	mii1_pins_sleep: mii1_pins_sleep {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
			AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
		>;
	};

	mii2_pru_pins_default: mii2_pru_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE5) /* (R13) gpmc_a0.pr1_mii_mt1_clk */
			AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (R14) gpmc_a4.pr1_mii1_txd0 */
			AM33XX_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (T14) gpmc_a3.pr1_mii1_txd1 */
			AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (U14) gpmc_a2.pr1_mii1_txd2 */
			AM33XX_IOPAD(0x844, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (V14) gpmc_a1.pr1_mii1_txd3 */
			AM33XX_IOPAD(0x860, PIN_INPUT_PULLUP | MUX_MODE5) /* (V16) gpmc_a8.pr1_mii1_rxd0 */
			AM33XX_IOPAD(0x85c, PIN_INPUT_PULLUP | MUX_MODE5) /* (T15) gpmc_a7.pr1_mii1_rxd1 */
			AM33XX_IOPAD(0x858, PIN_INPUT_PULLUP | MUX_MODE5) /* (U15) gpmc_a6.pr1_mii1_rxd2 */
			AM33XX_IOPAD(0x854, PIN_INPUT_PULLUP | MUX_MODE5) /* (V15) gpmc_a5.pr1_mii1_rxd3 */
			AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (U17) gpmc_wpn.pr1_mii1_txen */
			AM33XX_IOPAD(0x864, PIN_INPUT_PULLUP | MUX_MODE5) /* (U16) gpmc_a9.pr1_mii_mr1_clk */
			AM33XX_IOPAD(0x868, PIN_INPUT_PULLUP | MUX_MODE5) /* (T16) gpmc_a10.pr1_mii1_rxdv */
			AM33XX_IOPAD(0x86c, PIN_INPUT_PULLUP | MUX_MODE5) /* (V17) gpmc_a11.pr1_mii1_rxer */
			AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE5) /* (U18) gpmc_be1n.pr1_mii1_rxlink */
			AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLUP | MUX_MODE2) /* (R6) lcd_ac_bias_en.pr1_mii1_crs */
			AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE5) /* (T17) gpmc_wait0.pr1_mii1_col */
		>;
	};

	/* Optional sleep pin settings. Must manually enter values in the below skeleton. */
	mii2_pru_pins_sleep: mii2_pru_pins_sleep {
		pinctrl-single,pins = <
		/* AM33XX_IOPAD(0x840, PIN_INPUT_PULLDOWN | MUX_MODE7)  (R13) gpmc_a0.pr1_mii_mt1_clk */
		/*	AM33XX_IOPAD(0x850, PIN_INPUT_PULLDOWN | MUX_MODE7)  (R14) gpmc_a4.pr1_mii1_txd0 */
		/*	AM33XX_IOPAD(0x84c, PIN_INPUT_PULLDOWN | MUX_MODE7)  (T14) gpmc_a3.pr1_mii1_txd1 */
		/*	AM33XX_IOPAD(0x848, PIN_INPUT_PULLDOWN | MUX_MODE7)  (U14) gpmc_a2.pr1_mii1_txd2 */
		/*	AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)  (V14) gpmc_a1.pr1_mii1_txd3 */
		/*	AM33XX_IOPAD(0x860, PIN_INPUT_PULLDOWN | MUX_MODE7)  (V16) gpmc_a8.pr1_mii1_rxd0 */
		/*	AM33XX_IOPAD(0x85c, PIN_INPUT_PULLDOWN | MUX_MODE7)  (T15) gpmc_a7.pr1_mii1_rxd1 */
		/*	AM33XX_IOPAD(0x858, PIN_INPUT_PULLDOWN | MUX_MODE7)  (U15) gpmc_a6.pr1_mii1_rxd2 */
		/*	AM33XX_IOPAD(0x854, PIN_INPUT_PULLDOWN | MUX_MODE7)  (V15) gpmc_a5.pr1_mii1_rxd3 */
		/*	AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE7)  (U17) gpmc_wpn.pr1_mii1_txen */
		/*	AM33XX_IOPAD(0x864, PIN_INPUT_PULLDOWN | MUX_MODE7)  (U16) gpmc_a9.pr1_mii_mr1_clk */
		/*	AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)  (T16) gpmc_a10.pr1_mii1_rxdv */
		/*	AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)  (V17) gpmc_a11.pr1_mii1_rxer */
		/*	AM33XX_IOPAD(0x878, PIN_INPUT_PULLDOWN | MUX_MODE7)  (U18) gpmc_be1n.pr1_mii1_rxlink */
		/*	AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7)  (R6) lcd_ac_bias_en.pr1_mii1_crs */
		/*	AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE7)  (T17) gpmc_wait0.pr1_mii1_col */
		>;
	};

	emmc_pins_default: emmc_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* (U9) gpmc_csn1.mmc1_clk */
			AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* (V9) gpmc_csn2.mmc1_cmd */
			AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* (U7) gpmc_ad0.mmc1_dat0 */
			AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* (V7) gpmc_ad1.mmc1_dat1 */
			AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* (R8) gpmc_ad2.mmc1_dat2 */
			AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* (T8) gpmc_ad3.mmc1_dat3 */
			AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* (U8) gpmc_ad4.mmc1_dat4 */
			AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* (V8) gpmc_ad5.mmc1_dat5 */
			AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* (R9) gpmc_ad6.mmc1_dat6 */
			AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* (T9) gpmc_ad7.mmc1_dat7 */
		>;
	};

	sd_card_pins_default: sd_card_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* (G17) mmc0_clk.mmc0_clk */
			AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* (G18) mmc0_cmd.mmc0_cmd */
			AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* (G16) mmc0_dat0.mmc0_dat0 */
			AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* (G15) mmc0_dat1.mmc0_dat1 */
			AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* (F18) mmc0_dat2.mmc0_dat2 */
			AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* (F17) mmc0_dat3.mmc0_dat3 */
			AM33XX_IOPAD(0x960, PIN_INPUT_PULLUP | MUX_MODE5) /* (C15) spi0_cs1.mmc0_sdcd */
		>;
	};

	rs232_pins_default: rs232_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* (E15) uart0_rxd.uart0_rxd */
			AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* (E16) uart0_txd.uart0_txd */
		>;
	};

	rs485_pins_default: rs485_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1) /* (A17) spi0_sclk.uart2_rxd */
			AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1) /* (B17) spi0_d0.uart2_txd */
			AM33XX_IOPAD(0x958, PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* (B16) spi0_d1.gpio0[4] */
		>;
	};

	usb0_pins_default: usb0_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0xa34, PIN_OUTPUT_PULLUP | MUX_MODE0) /* (F15) USB1_DRVVBUS.USB1_DRVVBUS */
		>;
	};

	usb1_pins_default: usb1_pins_default {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0xa1c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* (F16) USB0_DRVVBUS.USB0_DRVVBUS */
		>;
	};

};


&uart0 {
	pinctrl-names = "default";
	pinctrl-0 = <&rs232_pins_default>;
	
	status = "okay";
};

&uart2 {
	pinctrl-names = "default";
	pinctrl-0 = <&rs485_pins_default>;
	rts-gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
	rs485-rts-active-high;
	rs485-rts-delay = <0 0>;
	linux,rs485-enabled-at-boot-time;
	status = "okay";
};

&i2c0 {
	pinctrl-names = "default";
	pinctrl-0 = <&i2c0_pins_default>;

	status = "okay";
	clock-frequency = <400000>;

	tps: tps@2d {
		reg = <0x2d>;
	};
};

&i2c1 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&i2c1_pins_default>;
	clock-frequency = <400000>;

	pcf8563@51 {
		compatible = "nxp,pcf8563";
		reg = <0x51>;
	};
};

/include/ "tps65910.dtsi"

&tps {
	vcc1-supply = <&vbat>;
	vcc2-supply = <&vbat>;
	vcc3-supply = <&vbat>;
	vcc4-supply = <&vbat>;
	vcc5-supply = <&vbat>;
	vcc6-supply = <&vbat>;
	vcc7-supply = <&vbat>;
	vccio-supply = <&vbat>;

	regulators {
		vrtc_reg: regulator@0 {
			regulator-always-on;
		};

		vio_reg: regulator@1 {
			regulator-always-on;
		};

		vdd1_reg: regulator@2 {
			/* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
			regulator-name = "vdd_mpu";
			regulator-min-microvolt = <912500>;
			regulator-max-microvolt = <1312500>;
			regulator-boot-on;
			regulator-always-on;
		};

		vdd2_reg: regulator@3 {
			/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
			regulator-name = "vdd_core";
			regulator-min-microvolt = <912500>;
			regulator-max-microvolt = <1150000>;
			regulator-boot-on;
			regulator-always-on;
		};

		vdd3_reg: regulator@4 {
			regulator-always-on;
		};

		vdig1_reg: regulator@5 {
			regulator-always-on;
		};

		vdig2_reg: regulator@6 {
			regulator-always-on;
		};

		vpll_reg: regulator@7 {
			regulator-always-on;
		};

		vdac_reg: regulator@8 {
			regulator-always-on;
		};

		vaux1_reg: regulator@9 {
			regulator-always-on;
		};

		vaux2_reg: regulator@10 {
			regulator-always-on;
		};

		vaux33_reg: regulator@11 {
			regulator-always-on;
		};

		vmmc_reg: regulator@12 {
			regulator-min-microvolt = <1800000>;
			regulator-max-microvolt = <3300000>;
			regulator-always-on;
		};
	};
};


&cpsw_emac0 {
	phy_id = <&davinci_mdio>, <1>;
	phy-mode = "mii";
};

&mac {
	slaves = <1>;
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&mii1_pins_default>;
	pinctrl-1 = <&mii1_pins_sleep>;
	status = "okay";
};

&davinci_mdio {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&mdio_pins_default>;
	pinctrl-1 = <&mdio_pins_sleep>;
	status = "okay";
};

&mmc1 {
	status = "okay";
	vmmc-supply = <&vmmc_reg>;
	bus-width = <0x4>;
	pinctrl-names = "default";
	pinctrl-0 = <&sd_card_pins_default>;
};

&mmc2 {
	vmmc-supply = <&vmmc_reg>;
	pinctrl-names = "default";
	pinctrl-0 = <&emmc_pins_default>;
	bus-width = <0x8>;
	status = "okay";
};

&usb {
	status = "okay";
};

&usb_ctrl_mod {
	status = "okay";
};

&usb0_phy {
	status = "okay";
};

&usb1_phy {
	status = "okay";
};

&usb0 {
	pinctrl-names = "default";
	pinctrl-0 = <&usb0_pins_default>;
	status = "okay";
	dr_mode = "peripheral";
};

&usb1 {
	pinctrl-names = "default";
	pinctrl-0 = <&usb1_pins_default>;
	status = "okay";
	dr_mode = "host";
};

&cppi41dma  {
	status = "okay";
};

&sham {
	status = "okay";
};

&aes {
	status = "okay";
};


&pruss_soc_bus {
	status = "okay";

	pruss: pruss@4a300000 {
		status = "okay";

		pru0: pru@4a334000 {
			status = "okay";
		};

		pru1: pru@4a338000 {
			status = "okay";
		};
	};
};

&pruss_mdio {
	pinctrl-0 = <&mdio_mii2_pins_default>;
	pinctrl-names = "default";
	reset-delay-us = <2>; /* PHY datasheet states 1uS min */
	status = "disabled";
	pruss_eth1_phy: ethernet-phy@0 {
		 reg = <1>;
	 };
};


/*******  ADD this for UIO PRUSS ********/

&pruss_soc_bus {
		uio_pruss_mdio: uio_pruss_mdio@4a332400 {
			compatible = "ti,davinci_mdio";
			reg = <0x4a332400 0x90>;
			clocks = <&dpll_core_m4_ck>;
			clock-names = "fck";
			bus_freq = <1000000>;
			#address-cells = <1>;
			#size-cells = <0>;
			status = "disabled";
		};

		uio_pruss_mem: uio_pruss_mem {
			compatible = "ti,uio-module-drv";
			mem = <0x4a300000 0x2000>,
			      <0x4a302000 0x2000>,
			      <0x4a310000 0x3000>,
			      <0x4a320000 0x2000>,
			      <0x4a326000 0x2000>,
			      <0x4a32e000 0x31c>,
			      <0x4a332000 0x58>;
			mem-names = "dram0", "dram1", "shrdram2", "intc", "cfg",
				    "iep", "mii_rt";

			status = "okay";
		};
		uio_pruss_mem2: uio_pruss_mem2 {
			compatible = "ti,uio-module-drv";
			mem = <0x4a328000 0xd4>,
			      <0x4a330000 0x174>,
			      <0x4a332400 0x90>,
			      <0x40302000 0x0e000>;
			mem-names = "uart", "ecap", "mdio", "ocmc";
			status = "okay";
		};

		uio_pruss_evt0: uio_pruss_evt0 {
			compatible = "ti,uio-module-drv";
                        interrupts = <20>;
			interrupt-mode = <1>;
			status = "okay";
		};
		uio_pruss_evt1: uio_pruss_evt1 {
			compatible = "ti,uio-module-drv";
                        interrupts = <21>;
			interrupt-mode = <1>;
			status = "okay";
		};
		uio_pruss_evt2: uio_pruss_evt2 {
			compatible = "ti,uio-module-drv";
                        interrupts = <22>;
			interrupt-mode = <1>;
			status = "okay";
		};
		uio_pruss_evt3: uio_pruss_evt3 {
			compatible = "ti,uio-module-drv";
                        interrupts = <23>;
			interrupt-mode = <1>;
			status = "okay";
		};
		uio_pruss_evt4: uio_pruss_evt4 {
			compatible = "ti,uio-module-drv";
                        interrupts = <24>;
			interrupt-mode = <1>;
			status = "okay";
		};
		uio_pruss_evt5: uio_pruss_evt5 {
			compatible = "ti,uio-module-drv";
                        interrupts = <25>;
			interrupt-mode = <1>;
			status = "okay";
		};
		uio_pruss_evt6: uio_pruss_evt6 {
			compatible = "ti,uio-module-drv";
                        interrupts = <26>;
			interrupt-mode = <1>;
			status = "okay";
		};
		uio_pruss_evt7: uio_pruss_evt7 {
			compatible = "ti,uio-module-drv";
                        interrupts = <27>;
			interrupt-mode = <1>;
			status = "okay";
		};

		uio_pruss_0_mem: uio_pruss_0_mem {
			compatible = "ti,uio-module-drv";
			mem = <0x4a334000 0x2000>,
			      <0x4a322000 0x400>,
			      <0x4a322400 0x100>;
			mem-names = "iram", "control", "debug";
			status = "okay";
		};

		uio_pruss_1_mem: uio_pruss_1_mem {
			compatible = "ti,uio-module-drv";
			mem = <0x4a338000 0x2000>,
			      <0x4a324000 0x400>,
			      <0x4a324400 0x100>;
			mem-names = "iram", "control", "debug";
			status = "okay";
		};
};

&am33xx_pinmux {
	uio_pruss_mdio_eth_default: uio_pruss_mdio_eth_default {
		pinctrl-single,pins = <
			/* MDIO CONFIG */
			AM33XX_IOPAD(0x88c, PIN_OUTPUT_PULLUP | MUX_MODE5) /* (V12) gpmc_clk.pr1_mdio_mdclk */
			AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE5) /* (T13) gpmc_csn3.pr1_mdio_data */
			/* MII CONFIG */
			AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE5) /* (R13) gpmc_a0.pr1_mii_mt1_clk */
			AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (R14) gpmc_a4.pr1_mii1_txd0 */
			AM33XX_IOPAD(0x84c, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (T14) gpmc_a3.pr1_mii1_txd1 */
			AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (U14) gpmc_a2.pr1_mii1_txd2 */
			AM33XX_IOPAD(0x844, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (V14) gpmc_a1.pr1_mii1_txd3 */
			AM33XX_IOPAD(0x860, PIN_INPUT_PULLUP | MUX_MODE5) /* (V16) gpmc_a8.pr1_mii1_rxd0 */
			AM33XX_IOPAD(0x85c, PIN_INPUT_PULLUP | MUX_MODE5) /* (T15) gpmc_a7.pr1_mii1_rxd1 */
			AM33XX_IOPAD(0x858, PIN_INPUT_PULLUP | MUX_MODE5) /* (U15) gpmc_a6.pr1_mii1_rxd2 */
			AM33XX_IOPAD(0x854, PIN_INPUT_PULLUP | MUX_MODE5) /* (V15) gpmc_a5.pr1_mii1_rxd3 */
			AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLDOWN | MUX_MODE5) /* (U17) gpmc_wpn.pr1_mii1_txen */
			AM33XX_IOPAD(0x864, PIN_INPUT_PULLUP | MUX_MODE5) /* (U16) gpmc_a9.pr1_mii_mr1_clk */
			AM33XX_IOPAD(0x868, PIN_INPUT_PULLUP | MUX_MODE5) /* (T16) gpmc_a10.pr1_mii1_rxdv */
			AM33XX_IOPAD(0x86c, PIN_INPUT_PULLUP | MUX_MODE5) /* (V17) gpmc_a11.pr1_mii1_rxer */
			AM33XX_IOPAD(0x878, PIN_INPUT_PULLUP | MUX_MODE5) /* (U18) gpmc_be1n.pr1_mii1_rxlink */
			AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLUP | MUX_MODE2) /* (R6) lcd_ac_bias_en.pr1_mii1_crs */
			AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE5) /* (T17) gpmc_wait0.pr1_mii1_col */
		>;
	};
};

&uio_pruss_mdio {
	pinctrl-0 = <&uio_pruss_mdio_eth_default>;
	pinctrl-names = "default";
	reset-delay-us = <2>; /* PHY datasheet states 1uS min */
	status = "okay";
	
	uio_pruss_eth1_phy: ethernet-phy@0 {
		reg = <0>;
	};
};

&pruss {
	status = "disabled";
};

&pru0 {
	status = "disabled";
};

&pru1 {
	status = "disabled";
};

&pruss_intc {
	status = "disabled";
};

&pruss_mdio {
	status = "disabled";
};

&pruss_emac1 {
	status = "disabled";
};

Software: 

We use the Arago distro with a ti linux kernel 4.19.94-rt39

the uio_module_drv has version 2.2.1.0

The necessary kernel modules are automatically loaded on boot:

root@am335x:~#         lsmod | grep uio
uio_module_drv         20480  0
uio                    20480  1 uio_module_drv

Test-Software:

as stated above, we use a modified version of the icss_emacMainTest_am335x.out because we only have one emac that connected to the pruss (PR1_MII1)

main.c:

/*
 * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
 *
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

#define __LINUX_USER_SPACE

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define __LINUX_USER_SPACE
#ifdef __LINUX_USER_SPACE
#include <sys/mman.h>
#include <unistd.h>
#include "mmap_helper.h"
#endif

#include <ti/csl/soc.h>

#include <ti/drv/pruss/pruicss.h>
#include <ti/drv/pruss/soc/pruicss_v1.h>

#include <ti/drv/icss_emac/icss_emacDrv.h>
#include <ti/drv/icss_emac/test/src/test_common_utils.h>
#ifdef SWITCH_EMAC
#include <ti/drv/icss_emac/test/src/tiswitch_pruss_intc_mapping.h>
#else
#include <ti/drv/icss_emac/test/src/tiemac_pruss_intc_mapping.h>
#endif

#ifdef __LINUX_USER_SPACE
/* ICSS EMAC  PHY address definitions */
#define BOARD_ICSS_EMAC_PORT0_PHY_ADDR       (1U)
#define BOARD_ICSS_EMAC_PORT1_PHY_ADDR       (3U)
#endif

#include <ti/starterware/include/hw/soc_am335x.h>

extern uint8_t ICSS_EMAC_testPkt[];

extern uint8_t    ICSS_EMAC_testTtsModePort1;

extern ICSS_EmacHandle ICSS_EMAC_testHandle;

extern uint32_t ICSS_EMAC_testPacketRcvdPort0;

extern uint8_t ICSS_EMAC_testLclMac[];


uint8_t ICSS_EMAC_testEvmType = ICSS_EMAC_TEST_BOARD_ICEV2AM335x;

PRUICSS_Handle ICSS_EMAC_testPruIcssHandle1 = NULL;

#ifdef __LINUX_USER_SPACE
static inline void linux_sleep_ms(unsigned long ms) {
    struct timespec ts;
    ts.tv_sec = (ms)/1000;
    ms = ms - ts.tv_sec*1000;
    ts.tv_nsec = (ms*1000000);
    nanosleep(&ts, NULL);
}
#define SLEEP(t) linux_sleep_ms(t)
#define PRINT printf
#else
#define SLEEP Task_sleep
#define PRINT UART_printf
#endif


#ifdef __LINUX_USER_SPACE
extern tprussdrv *pruss_drv_handle;
extern PRUICSS_HwAttrs linux_prussHwAttrs[PRUICCSS_INSTANCE_MAX-1];
extern PRUICSS_V1_Object linux_prussObjects[PRUICCSS_INSTANCE_MAX-1];
extern PRUICSS_Config linux_pruss_config[PRUICCSS_INSTANCE_MAX];

pthread_t port0_rxTask_th, port0_txTask_th, port0_ttsCycTask_th, port0_linkTask_th,
          port1_rxTask_th, port1_txTask_th, port1_ttsCycTask_th, port1_linkTask_th;

int eth0_rxIntNum = 0,
    eth0_txIntNum = 2,
    eth0_linkIntNum = 6,
    eth1_rxIntNum = 1,
    eth1_txIntNum = 3,
    eth1_linkIntNum = 7;
#endif

/***********************************************************************/
/* function definitions                                                */
/***********************************************************************/
int32_t ICSS_EMAC_testPruIcssInstanceSetup(void)
{
    PRUICSS_Config  *cfg;
    ICSS_EmacInitConfig* icss_emacTestInitCfg0;

    int status;
    int priority = 20;
    pthread_attr_t pthread_attr;
	struct sched_param sched_param;

	// generic init
    linux_init((void**)&pruss_drv_handle, linux_prussHwAttrs, PRUICCSS_INSTANCE_ONE);
    cfg = linux_pruss_config;

    // generic init
    ICSS_EMAC_testPruIcssHandle1 = PRUICSS_create((PRUICSS_Config*) cfg, PRUICCSS_INSTANCE_ONE);

    /*Port I initializations*/
    ICSS_EMAC_testHandle = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig));
    icss_emacTestInitCfg0 = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig));

    if ((ICSS_EMAC_testHandle == NULL) || (icss_emacTestInitCfg0 == NULL))
    {
        PRINT("main: malloc returned null\n");
        return -1;
    }

    // port specific
    icss_emacTestInitCfg0->phyAddr[0]=BOARD_ICSS_EMAC_PORT0_PHY_ADDR;
    icss_emacTestInitCfg0->portMask = ICSS_EMAC_MODE_MAC1;
    icss_emacTestInitCfg0->ethPrioQueue = ICSS_EMAC_QUEUE1;

    // options
    icss_emacTestInitCfg0->halfDuplexEnable = 0;
    icss_emacTestInitCfg0->enableIntrPacing = ICSS_EMAC_ENABLE_PACING;
    icss_emacTestInitCfg0->ICSS_EmacIntrPacingMode = ICSS_EMAC_INTR_PACING_MODE1;
    icss_emacTestInitCfg0->pacingThreshold = 100;
    icss_emacTestInitCfg0->learningEn = 0;

    icss_emacTestInitCfg0->macId = ICSS_EMAC_testLclMac;

    ICSS_EMAC_testDrvInit(ICSS_EMAC_testHandle, 1);


    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkInt_fd = prussdrv_open(pruss_drv_handle, eth0_linkIntNum);
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->rxInt_fd = prussdrv_open(pruss_drv_handle, eth0_rxIntNum);
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->txInt_fd = prussdrv_open(pruss_drv_handle, eth0_txIntNum);
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->ttsCycInt_fd = prussdrv_open(pruss_drv_handle, eth0_txIntNum);


    /*  Enable interrupt mode for TTS Cyclic Packet     */
    icss_emacTestInitCfg0->ICSS_EmacTTSEnableCycPktInterrupt = ICSS_EMAC_TTS_CYC_INTERRUPT_ENABLE;


    icss_emacTestInitCfg0->rxIntNum   = eth0_rxIntNum;
    icss_emacTestInitCfg0->linkIntNum = eth0_linkIntNum;
    icss_emacTestInitCfg0->txIntNum   = eth0_txIntNum;
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->pruss_drv_handle = pruss_drv_handle;

    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->pruIcssHandle = ICSS_EMAC_testPruIcssHandle1;
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->emacInitcfg = icss_emacTestInitCfg0;


    PRUICSS_IntcInitData pruss_intc_initdata = PRUSS_INTC_INITDATA;

    ICSS_EmacInit(ICSS_EMAC_testHandle,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC1);
    /* Test ICSS_EmacDeInit */
    ICSS_EmacDeInit(ICSS_EMAC_testHandle, ICSS_EMAC_MODE_MAC1);

    ICSS_EmacInit(ICSS_EMAC_testHandle,&pruss_intc_initdata, ICSS_EMAC_MODE_MAC1);


    /* Register TTS Callbacks  */

    ICSS_EmacRegisterHwIntTTSCyc(ICSS_EMAC_testHandle, (ICSS_EmacCallBack)ICSS_EMAC_testTtsCycPort1Callback);
    /* Register RX Callbacks: Required for TTS Unit Testing    */
    ICSS_EmacRegisterHwIntRx(ICSS_EMAC_testHandle, (ICSS_EmacCallBack)ICSS_EMAC_testCallbackRxPacket);
    /* Register Tx Callbacks */
    ICSS_EmacRegisterHwIntTx(ICSS_EMAC_testHandle, (ICSS_EmacCallBack)ICSS_EMAC_testCallbackTxComplete);
    /* Register Link ISR Callbacks */
    ICSS_EmacRegisterPort0ISRCallback(ICSS_EMAC_testHandle, (ICSS_EmacCallBack)ICSS_EMAC_testLinkIsrCb, (void*)ICSS_EMAC_TEST_PRU1ETH0);



    pthread_attr_init(&pthread_attr);
    pthread_attr_setinheritsched(&pthread_attr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&pthread_attr, SCHED_FIFO);
    sched_param.sched_priority = priority;
    pthread_attr_setschedparam(&pthread_attr, &sched_param);

    if ((status = pthread_create(&port1_linkTask_th, &pthread_attr, ICSS_EMacOsLinkTaskFnc, (void *)ICSS_EMAC_testHandle))) {
        printf("ERROR: \"port0_linkTaskFnc\" task-create failed (%d)\n", status);
        return (-2);
    }
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->rxTaskHandle = &port1_rxTask_th;
    if ((status = pthread_create(&port1_rxTask_th,
                &pthread_attr, ICSS_EMacOsRxTaskFnc, (void *)ICSS_EMAC_testHandle))) {
        printf("ERROR: \"port0_rxTaskFnc\" task-create failed (%d)\n", status);
        return (-2);
    }
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->txTaskHandle = &port1_txTask_th;
    if ((status = pthread_create(&port1_txTask_th,
                &pthread_attr, ICSS_EMacOsTxTaskFnc, (void *)ICSS_EMAC_testHandle))) {
        printf("ERROR: \"port0_txTaskFnc\" task-create failed (%d)\n", status);
        return (-2);
    }
    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->ttsCycTaskHandle = &port1_ttsCycTask_th;
    if ((status = pthread_create(&port1_ttsCycTask_th,
                &pthread_attr, ICSS_EMacOsTTSCycTaskFnc, (void *)ICSS_EMAC_testHandle))) {
        printf("ERROR: \"port0_ttsCycTaskFnc\" task-create failed (%d)\n", status);
        return (-2);
    }

    pthread_attr_destroy(&pthread_attr);

    return 0;
}

/*
 *  ======== main ========
 */
#ifdef __LINUX_USER_SPACE
uint32_t num_iteration = 10;
uint32_t cycle_period_port1 = ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT1;
uint32_t cycle_period_port2 = ICSS_EMAC_TEST_TTS_CYCLE_PERIOD_PORT2;
uint32_t config_time =   ICSS_EMAC_TEST_TTS_CONFIG_TIME;

int main(int argc, char **argv)
{
    uint32_t numPorts = 2;
    int status;
    int switchTask_priority = 10;
    int ttsTask_priority = 10;
    pthread_t ICSS_EMAC_testTaskPruss_th, ICSS_EMAC_testPort1TxTask_th, ICSS_EMAC_testPort2TxTask_th;
    pthread_attr_t pthread_attr;
    struct sched_param sched_param;

    if(argc > 1)
    {
        num_iteration =  atoi(argv[1]);
        cycle_period_port1  = atoi(argv[2]);
        cycle_period_port2  = atoi(argv[3]);
        config_time   = atoi(argv[4]);
    }

    ICSS_EMAC_testPruIcssInstanceSetup();


    pthread_attr_init(&pthread_attr);
    pthread_attr_setinheritsched(&pthread_attr,PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&pthread_attr, SCHED_RR);
    sched_param.sched_priority = switchTask_priority;
    pthread_attr_setschedparam(&pthread_attr, &sched_param);

    mlockall(MCL_FUTURE);

    if ((status = pthread_create(&ICSS_EMAC_testTaskPruss_th, &pthread_attr, ICSS_EMAC_testTaskPruss1, NULL))) {
        printf("ERROR: \"SwitchTask1\" task-create failed (%d)\n", status);
        return (-1);
    }

    // Set TTS tasks priority
    pthread_attr_setschedpolicy(&pthread_attr, SCHED_FIFO);
    sched_param.sched_priority = ttsTask_priority;
    pthread_attr_setschedparam(&pthread_attr, &sched_param);

    if ((status = pthread_create(&ICSS_EMAC_testPort1TxTask_th, &pthread_attr, ICSS_EMAC_testPort1TxTask, NULL))) {
        printf("ERROR: \"ttsPort1TxTask\" task-create failed (%d)\n", status);
        return (-1);
    }


    pthread_join(ICSS_EMAC_testTaskPruss_th, NULL);
    pthread_join(ICSS_EMAC_testPort1TxTask_th, NULL);

    pthread_attr_destroy(&pthread_attr);

    return(0);
}
#endif




test_common_utils.c:

2337.test_common_utils.c

From my understanding, I should init my emac as port2 instead of port1. But if I do so the link will not be detected anymore.

What I don't understand is why the link status is properly detected in this configuration, but no other interrupts are triggered.

Log of test code:

root@am335x:~# gdbserver  :2345 /home/root/uio_test;exit
Process /home/root/uio_test created; pid = 1344
Listening on port 2345
Remote debugging from host 192.168.7.1

DEBUG:Got Memory section uio_pruss_mem:dram0 physbase 0x4a300000, virtp 0xb6ffb000, size 0x2000
DEBUG:Memory section dram0: First location 0x11

DEBUG:Got Memory section uio_pruss_mem:intc physbase 0x4a320000, virtp 0xb6ff6000, size 0x2000
DEBUG:Memory section intc: First location 0x4e82a900
DEBUG:Got hw version 2

DEBUG:Got Memory section uio_pruss_mem:dram1 physbase 0x4a302000, virtp 0xb6ff4000, size 0x2000
DEBUG:Memory section dram1: First location 0x11
PRUSS V2 

DEBUG:Got Memory section uio_pruss_mem:shrdram2 physbase 0x4a310000, virtp 0xb6ff1000, size 0x3000
DEBUG:Memory section shrdram2: First location 0x0

DEBUG:Got Memory section uio_pruss_mem:cfg physbase 0x4a326000, virtp 0xb6fef000, size 0x2000
DEBUG:Memory section cfg: First location 0x47000000

DEBUG:Got Memory section uio_pruss_mem:iep physbase 0x4a32e000, virtp 0xb6ffa000, size 0x31c
DEBUG:Memory section iep: First location 0x551

DEBUG:Got Memory section uio_pruss_mem:mii_rt physbase 0x4a332000, virtp 0xb6fee000, size 0x58
DEBUG:Memory section mii_rt: First location 0x15

DEBUG:Got Memory section uio_pruss_mem2:uart physbase 0x4a328000, virtp 0xb6e24000, size 0xd4
DEBUG:Memory section uart: First location 0x0

DEBUG:Got Memory section uio_pruss_mem2:ecap physbase 0x4a330000, virtp 0xb6e23000, size 0x174
DEBUG:Memory section ecap: First location 0x65d1b116

DEBUG:Got Memory section uio_pruss_mem2:mdio physbase 0x4a332400, virtp 0xb6e22400, size 0x90
DEBUG:Memory section mdio: First location 0x40070106

DEBUG:Got Memory section uio_pruss_mem2:ocmc physbase 0x40302000, virtp 0xb6e14000, size 0xe000
DEBUG:Memory section ocmc: First location 0x0

DEBUG:Got Memory section uio_pruss_0_mem:iram physbase 0x4a334000, virtp 0xb6e12000, size 0x2000
DEBUG:Memory section iram: First location 0x0

DEBUG:Got Memory section uio_pruss_0_mem:control physbase 0x4a322000, virtp 0xb6e11000, size 0x400
DEBUG:Memory section control: First location 0x8003

DEBUG:Got Memory section uio_pruss_0_mem:debug physbase 0x4a322400, virtp 0xb6e10400, size 0x100
DEBUG:Memory section debug: First location 0x0

DEBUG:Got Memory section uio_pruss_1_mem:iram physbase 0x4a338000, virtp 0xb6e0e000, size 0x2000
DEBUG:Memory section iram: First location 0x0

DEBUG:Got Memory section uio_pruss_1_mem:control physbase 0x4a324000, virtp 0xb6e0d000, size 0x400
DEBUG:Memory section control: First location 0x8003

DEBUG:Got Memory section uio_pruss_1_mem:debug physbase 0x4a324400, virtp 0xb6e0c400, size 0x100
DEBUG:Memory section debug: First location 0x0
ICSS_EMAC_testDrvInit: instance: 1, data0RamSize: 0x2000, data1RamSize: 0x2000, sharedDataRamSize: 0x3000, l3OcmcSize: 0x10000
Validate Firmware: Release1: 0x11, Release2: 0x85020007

PRU-ICSS STATS for PRU1ETH0, port: 1
txBcast:0x0
txMcast:0x0
txUcast:0x0
txOctets:0x0
rxBcast:0x0
rxMcast:0x0
rxUcast:0x0
rxOctets:0x0
tx64byte:0x0
tx65_127byte:0x0
tx128_255byte:0x0
tx512_1023byte:0x0
tx1024byte:0x0
rx64byte:0x0
rx65_127byte:0x0
rx128_255byte:0x0
rx512_1023byte:0x0
rx1024byte:0x0
lateColl:0x0
singleColl:0x0
multiColl:0x0
excessColl:0x0
rxMisAlignmentFrames:0x0
stormPrevCounter:0x0
macRxError:0x0
SFDError:0x0
defTx:0x0
macTxError:0x0
rxOverSizedFrames:0x0
rxUnderSizedFrames:0x0
rxCRCFrames:0x0
droppedPackets:0x0
txOverFlow:0x0
txUnderFlow:0x0
sqeTestError:0x0
TXqueueLevel:0x0
CSError:0x0

ICSS_EMAC_testTaskPruss1: PRU1 ETH0: LINK IS UP, eth0 state: 1



============================================================
 ICSS_EMAC_testTaskPruss1: Testing NonPromiscuous Mode 
 sending Unicast packets as destination address == eth own address
============================================================

ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0
ICSS_EMAC_testTaskPruss1: Received no packet for PRU1 ETH0

PRU-ICSS STATS for PRU1ETH0, port: 1
txBcast:0x0
txMcast:0x0
txUcast:0x0
txOctets:0x0
rxBcast:0x0
rxMcast:0x0
rxUcast:0x0
rxOctets:0x0
tx64byte:0x0
tx65_127byte:0x0
tx128_255byte:0x0
tx512_1023byte:0x0
tx1024byte:0x0
rx64byte:0x0
rx65_127byte:0x0
rx128_255byte:0x0
rx512_1023byte:0x0
rx1024byte:0x0
lateColl:0x0
singleColl:0x0
multiColl:0x0
excessColl:0x0
rxMisAlignmentFrames:0x0
stormPrevCounter:0x0
macRxError:0x0
SFDError:0x0
defTx:0x0
macTxError:0x0
rxOverSizedFrames:0x0
rxUnderSizedFrames:0x0
rxCRCFrames:0x0
droppedPackets:0x0
txOverFlow:0x0
txUnderFlow:0x0
sqeTestError:0x0
TXqueueLevel:0x0
CSError:0x0

Thanks in advance

Regards,

Marcel

  • Hi Marcel Fehlberg,

    We need some more information to analyze this issue in better way, could you provide me below details.

    Which SDK version your using?

    memory dump of firmware statistics to analyze, here is the memory address

    For PRU1 – DRAM1 + IF00 to 1FA8

    Regards,

    Roopak

  • Hello Roopak,

    I did some further research on my own. Now I'm able to send and receive packages via eth1 just like I wanted to.

    The solution was to change the PHY address for eth1 from 3 to 1.

    Now the link status is recognized from the PRU1 and the driver and the test application seem to work fine.

    Regards,

    Marcel

  • Hello Roopak,

    a new problem arose.

    If I start the unit test no packages will be sent. 

    ((ICSS_EmacObject*)ICSS_EMAC_testHandle->object)->linkStatus[0] is true and ICSS_EmacTxPacket(&txArgs, NULL) is called.

     ICSS_EmacTxPacket(&txArgs, NULL) does not return an error and the ICSS_EMAC_testCallbackTxComplete is called too.

    But no packages can be detected via Wireshark.

    Only if I pull out the network cable and plug it back in the sending of packages starts and the unit test works like expected.

    What could be the cause of this? 

    We use PROCESSOR-SDK-LINUX-AM335X 06_03_00_106.

    Regards,

    Marcel

  • Hi Marcel, 

    Sorry for the delayed response.


    As you mentioned ICSS_EMAC_testCallbackTxComplete got hit means Firmware able pick up the package and it sends.

    Can you verify few things here:

    1) Link interrupts are working as expected and re verify Hardware configuration.

    2) Can you please check PRU statistics before pull out of network cable and after plug in. You will find the statistics in DRAM0 for PRU0 and          DRAM1 for PRU1. 

         For your reference Statistics will start from DRAM0 + 0x1F00 offset for PRU0 and  DRAM1 + 0x1F00 offset for PRU1. Can you please try       to get below statistics. Each will be 4 bytes.

         a) TX_BC_FRAMES_OFFSET      0x1F00          Number of Transmitted Broadcast Frames

         b) TX_MC_FRAMES_OFFSET     0x1F04           Number of Transmitted Multicast Frames

         c) TX_UC_FRAMES_OFFSET     0x1F08           Number of Transmitted Unicast Frames

    3) Can you please try to get the value at the PORT_STATUS_OFFSET(similar to stats). This is one byte value and used to check weather           port link is up or down from firmware. Can you please try to get this value before pull out of network cable and after plug in.

         For your reference PORT_STATUS_OFFSET is at DRAM0 + 0x1F98 for PRU0 and  DRAM1 + 0x1F98 for PRU1.

    Regards,

    mohan

  • Hello Mohan,

    To 1) The link interrupt works reliable and the hardware configuration seems correct to me.

    To 2)  Test 1: Cabel plug it. No Frames detected overwireshark

     

    PRU-ICSS STATS for PRU1ETH1, port: 2
    txBcast:0x0
    txMcast:0x0
    txUcast:0x0
    Portstatus:0xeb
    
    PRU-ICSS STATS for PRU1ETH1, port: 2
    txBcast:0x0
    txMcast:0x0
    txUcast:0xa
    Portstatus:0xeb
    
    PRU-ICSS STATS for PRU1ETH1, port: 2
    txBcast:0x0
    txMcast:0x0
    txUcast:0x14
    Portstatus:0xeb

    Test 2: Cabel pullt out and back in before sending. Frames now detectable with Wireshark

    PRU-ICSS STATS for PRU1ETH1, port: 2
    txBcast:0x0
    txMcast:0x0
    txUcast:0x0
    Portstatus:0xeb
    
    PRU-ICSS STATS for PRU1ETH1, port: 2
    txBcast:0x0
    txMcast:0x0
    txUcast:0xa
    Portstatus:0xeb
    
    PRU-ICSS STATS for PRU1ETH1, port: 2
    txBcast:0x0
    txMcast:0x0
    txUcast:0x14
    Portstatus:0xeb

    Both Logs the same. The function to print out the stats looks like this:

    int32_t ICSS_EMAC_GetPruStatsSmall(uint8_t portNum, ICSS_EmacHandle icssEmacHandle)
    {
        if (icssEmacHandle == ICSS_EMAC_Handle)
        {
            PRINT("\nPRU-ICSS STATS for PRU1ETH1, port: %d\n", portNum);
        }
        else
        {
            PRINT("ICSS_EMAC_testGetPruStats: Invalid ICSS_EmacHandle, returning without stats\n");
            return -1;
        }
    
        ICSS_EmacReadStats(portNum, icssEmacHandle);
        ICSS_EmacPruStatistics_t* pruStatsPtr = (ICSS_EmacPruStatistics_t *)(((ICSS_EmacObject *)icssEmacHandle->object)->pruStat);
    
        PRINT("txBcast:0x%x\n", pruStatsPtr->txBcast);
        PRINT("txMcast:0x%x\n", pruStatsPtr->txMcast);
        PRINT("txUcast:0x%x\n", pruStatsPtr->txUcast);
    
        ICSS_EmacBaseAddressHandle_T emacBaseAddr = ((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg;
        ICSS_EmacFwStaticMmap *pStaticMMap = (&((ICSS_EmacObject*)icssEmacHandle->object)->fwStaticMMap);
        volatile uint8_t *portStatusPtr = NULL;
        uint32_t temp_addr = 0U;
        temp_addr = ((((ICSS_EmacHwAttrs const *)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr + pStaticMMap->portStatusOffset);
        portStatusPtr = (uint8_t*)(temp_addr);
        PRINT("Portstatus:0x%x\n", *portStatusPtr);
    
    
        return 0;
    
    }

    I did some further digging and the problem to me is that the Link interrupt is not called when the cable is connected and then I start my program. This is correct, but it seems that the link interrupt is needed one time before sending for the sending process to work.

    So I wrote a function that does more or less the same as ICSS_EmacPollLink but outside of the link interrupt and only port2.

    bool ICSS_EMAC_SetPort2SettingsAccordingToLink(ICSS_EmacHandle handle)
    {
        ICSSEMAC_IoctlCmd ioctlParams;
        ICSS_EmacBaseAddressHandle_T emacBaseAddr = ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg;
        ICSS_EmacFwStaticMmap *pStaticMMap = (&((ICSS_EmacObject*)handle->object)->fwStaticMMap);
        volatile uint8_t *portStatusPtr = NULL;
        uint32_t temp_addr = 0U;
        temp_addr = ((((ICSS_EmacHwAttrs const *)handle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr + pStaticMMap->portStatusOffset);
        portStatusPtr = (uint8_t*)(temp_addr);
    
    
    	if (((ICSS_EmacObject*) handle->object)->linkStatus[0])
    	{
    		uint32_t ioctlvalue = ICSS_EMAC_IOCTL_PORT_CTRL_DISABLE;
    		ioctlParams.ioctlVal = &ioctlvalue;
    		ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_PORT_CTRL, (uint8_t) ICSS_EMAC_PORT_2, (void*) &ioctlParams);
    		ioctlvalue = (uint8_t) (ICSS_EMAC_IOCTL_PORT_CTRL_ENABLE);
    		ioctlParams.ioctlVal = &ioctlvalue;
    		ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_PORT_CTRL, (uint8_t) ICSS_EMAC_PORT_2, (void*) &ioctlParams);
    	    if(portStatusPtr)
    	    {
    	    	*portStatusPtr = 1U;
    	    }
    	}
    	else
    	{
    		uint32_t ioctlvalue = ICSS_EMAC_IOCTL_PORT_CTRL_DISABLE;
    		ioctlParams.ioctlVal = &ioctlvalue;
    		ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_PORT_CTRL, (uint8_t) ICSS_EMAC_PORT_2, (void*) &ioctlParams);
    	    if(portStatusPtr)
    	    {
    	    	*portStatusPtr = 0U;
    	    }
    	}
    
    	ICSS_EmacUpdatePhyStatus(2,handle);
    
    	return ((ICSS_EmacObject*) handle->object)->linkStatus[0];
    }

    When I call this function at the end of my init. The sending works every time. So this seems to resolve my error.

    Is there any reason why this might not be a good idea?

    Regards,

    Marcel

  • Hi Marcel,

    The workaround looks good to me and I don't see an issue in that and it will work as expected.

    I could suspect order of initialization of MDIO, PHY and Link interrupts.

    Can you please confirm me what sequence you are following to initialize MDIO, PHY and Link interrupts. 

    Regards,

    Mohan

  • Hello Mohan,

    sorry for the delayed response.

    Not quite sure how to distinguish between those interrupts. I thought the link status is also detected via MDIO. 

    But the init sequence of the interrupts, or rather the whole init is the same as the test code from the main_a8.c so think it's correct. 

    The driver seems to work quite well now. So to me, the issue is resolved.

    But I have one more question (a bit unrelated):

    are there any plans to release a new version of the AM335x processor Linux SDK with a newer kernel than 4.19? like a 5.4 kernel?

    Regards,

    Marcel

  • Hello Mohan,

    just when I ask for a new release, you guys release one :D 

    So all my issues are resolved. Thank you Mohan.

    Regards,

    Marcel

  • Hi Marcel,

    Thanks for the update.

    Regards,

    Mohan.