With cpsw being a switch getting the port config isn't as
straightforward as fec.
We only handle the first port at the moment, though the following diff
fetches settings that might be helpful were we to support a second.
To give an idea of what the fdt looks like here are the cpsw nodes
extracted from the bbb and x15 dtbs. U-Boot fills in "mac-address"
and "local-mac-address" in the port configuration.
ethernet@4a100000 {
compatible = "ti,am335x-cpsw", "ti,cpsw";
ti,hwmods = "cpgmac0";
clocks = <0x0000003f 0x00000040>;
clock-names = "fck", "cpts";
cpdma_channels = <0x00000008>;
ale_entries = <0x00000400>;
bd_ram_size = <0x00002000>;
no_bd_ram = <0x00000000>;
rx_descs = <0x00000040>;
mac_control = <0x00000020>;
slaves = <0x00000002>;
active_slave = <0x00000000>;
cpts_clock_mult = <0x80000000>;
cpts_clock_shift = <0x0000001d>;
reg = <0x4a100000 0x00000800 0x4a101200 0x00000100>;
#address-cells = <0x00000001>;
#size-cells = <0x00000001>;
interrupt-parent = <0x00000001>;
interrupts = <0x00000028 0x00000029 0x0000002a 0x0000002b>;
ranges;
syscon = <0x00000039>;
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <0x00000041>;
pinctrl-1 = <0x00000042>;
mdio@4a101000 {
compatible = "ti,davinci_mdio";
#address-cells = <0x00000001>;
#size-cells = <0x00000000>;
ti,hwmods = "davinci_mdio";
bus_freq = <0x000f4240>;
reg = <0x4a101000 0x00000100>;
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <0x00000043>;
pinctrl-1 = <0x00000044>;
linux,phandle = <0x00000045>;
phandle = <0x00000045>;
};
slave@4a100200 {
mac-address = [00 00 00 00 00 00];
phy_id = <0x00000045 0x00000000>;
phy-mode = "mii";
};
slave@4a100300 {
mac-address = [00 00 00 00 00 00];
phy_id = <0x00000045 0x00000001>;
phy-mode = "mii";
};
cpsw-phy-sel@44e10650 {
compatible = "ti,am3352-cpsw-phy-sel";
reg = <0x44e10650 0x00000004>;
reg-names = "gmii-sel";
};
};
ethernet@48484000 {
compatible = "ti,dra7-cpsw", "ti,cpsw";
ti,hwmods = "gmac";
clocks = <0x00000027 0x000000e8>;
clock-names = "fck", "cpts";
cpdma_channels = <0x00000008>;
ale_entries = <0x00000400>;
bd_ram_size = <0x00002000>;
no_bd_ram = <0x00000000>;
rx_descs = <0x00000040>;
mac_control = <0x00000020>;
slaves = <0x00000002>;
active_slave = <0x00000000>;
cpts_clock_mult = <0x80000000>;
cpts_clock_shift = <0x0000001d>;
reg = <0x48484000 0x00001000 0x48485200 0x00002e00>;
#address-cells = <0x00000001>;
#size-cells = <0x00000001>;
ti,no-idle;
interrupts = <0x00000000 0x0000014e 0x00000004 0x00000000
0x0000014f 0x00000004 0x00000000 0x00000150 0x00000004 0x00000000 0x00000151
0x00000004>;
ranges;
syscon = <0x00000004>;
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <0x000000e9>;
pinctrl-1 = <0x000000ea>;
dual_emac;
mdio@48485000 {
compatible = "ti,davinci_mdio";
#address-cells = <0x00000001>;
#size-cells = <0x00000000>;
ti,hwmods = "davinci_mdio";
bus_freq = <0x000f4240>;
reg = <0x48485000 0x00000100>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <0x000000eb>;
pinctrl-1 = <0x000000ec>;
linux,phandle = <0x000000ed>;
phandle = <0x000000ed>;
};
slave@48480200 {
mac-address = [00 00 00 00 00 00];
phy_id = <0x000000ed 0x00000001>;
phy-mode = "rgmii";
dual_emac_res_vlan = <0x00000001>;
};
slave@48480300 {
mac-address = [00 00 00 00 00 00];
phy_id = <0x000000ed 0x00000002>;
phy-mode = "rgmii";
dual_emac_res_vlan = <0x00000002>;
};
cpsw-phy-sel@4a002554 {
compatible = "ti,dra7xx-cpsw-phy-sel";
reg = <0x4a002554 0x00000004>;
reg-names = "gmii-sel";
};
};
Index: if_cpsw.c
===================================================================
RCS file: /cvs/src/sys/arch/armv7/omap/if_cpsw.c,v
retrieving revision 1.35
diff -u -p -r1.35 if_cpsw.c
--- if_cpsw.c 26 Jun 2016 09:06:35 -0000 1.35
+++ if_cpsw.c 26 Jun 2016 12:31:45 -0000
@@ -83,7 +83,6 @@
#include <dev/mii/miivar.h>
#include <arch/armv7/armv7/armv7var.h>
-#include <arch/armv7/omap/sitara_cm.h>
#include <arch/armv7/omap/if_cpswreg.h>
#include <dev/ofw/openfirm.h>
@@ -119,6 +118,13 @@ struct cpsw_ring_data {
struct mbuf *rx_mb[CPSW_NRXDESCS];
};
+struct cpsw_port_config {
+ uint8_t enaddr[ETHER_ADDR_LEN];
+ int phy_id;
+ int rgmii;
+ int vlan;
+};
+
struct cpsw_softc {
struct device sc_dev;
bus_space_tag_t sc_bst;
@@ -152,6 +158,8 @@ struct cpsw_softc {
volatile bool sc_rxeoq;
struct timeout sc_tick;
int sc_active_port;
+
+ struct cpsw_port_config sc_port_config[2];
};
#define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
@@ -180,7 +188,7 @@ int cpsw_rxintr(void *);
int cpsw_txintr(void *);
int cpsw_miscintr(void *);
-void cpsw_get_mac_addr(struct cpsw_softc *);
+void cpsw_get_port_config(struct cpsw_port_config *, int);
struct cfattach cpsw_ca = {
sizeof(struct cpsw_softc),
@@ -270,27 +278,6 @@ cpsw_rxdesc_paddr(struct cpsw_softc * co
return sc->sc_rxdescs_pa + sizeof(struct cpsw_cpdma_bd) * x;
}
-void
-cpsw_get_mac_addr(struct cpsw_softc *sc)
-{
- struct arpcom *ac = &sc->sc_ac;
- u_int32_t mac_lo = 0, mac_hi = 0;
-
- sitara_cm_reg_read_4(OMAP2SCM_MAC_ID0_LO, &mac_lo);
- sitara_cm_reg_read_4(OMAP2SCM_MAC_ID0_HI, &mac_hi);
-
- if ((mac_lo == 0) && (mac_hi == 0))
- printf("%s: invalid ethernet address\n", DEVNAME(sc));
- else {
- ac->ac_enaddr[0] = (mac_hi >> 0) & 0xff;
- ac->ac_enaddr[1] = (mac_hi >> 8) & 0xff;
- ac->ac_enaddr[2] = (mac_hi >> 16) & 0xff;
- ac->ac_enaddr[3] = (mac_hi >> 24) & 0xff;
- ac->ac_enaddr[4] = (mac_lo >> 0) & 0xff;
- ac->ac_enaddr[5] = (mac_lo >> 8) & 0xff;
- }
-}
-
static void
cpsw_mdio_init(struct cpsw_softc *sc)
{
@@ -370,7 +357,9 @@ cpsw_attach(struct device *parent, struc
timeout_set(&sc->sc_tick, cpsw_tick, sc);
- cpsw_get_mac_addr(sc);
+ cpsw_get_port_config(sc->sc_port_config, faa->fa_node);
+ memcpy(sc->sc_ac.ac_enaddr, sc->sc_port_config[0].enaddr,
+ ETHER_ADDR_LEN);
sc->sc_rxthih = arm_intr_establish(intr[0], IPL_NET, cpsw_rxthintr, sc,
DEVNAME(sc));
@@ -466,7 +455,7 @@ cpsw_attach(struct device *parent, struc
ifmedia_init(&sc->sc_mii.mii_media, 0, cpsw_mediachange,
cpsw_mediastatus);
mii_attach(self, &sc->sc_mii, 0xffffffff,
- MII_PHY_ANY, MII_OFFSET_ANY, 0);
+ sc->sc_port_config[0].phy_id, MII_OFFSET_ANY, 0);
if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
printf("no PHY found!\n");
ifmedia_add(&sc->sc_mii.mii_media,
@@ -1282,4 +1271,34 @@ cpsw_miscintr(void *arg)
bus_space_write_4(sc->sc_bst, sc->sc_bsh, CPSW_CPDMA_CPDMA_EOI_VECTOR,
CPSW_INTROFF_MISC);
return 1;
+}
+
+void
+cpsw_get_port_config(struct cpsw_port_config *conf, int pnode)
+{
+ char mode[32];
+ uint32_t phy_id[2];
+ int node;
+ int port = 0;
+
+ for (node = OF_child(pnode); node; node = OF_peer(node)) {
+ if (OF_getprop(node, "local-mac-address", conf[port].enaddr,
+ sizeof(conf[port].enaddr)) != sizeof(conf[port].enaddr))
+ continue;
+
+ conf[port].vlan = OF_getpropint(node, "dual_emac_res_vlan", 0);
+
+ if (OF_getpropintarray(node, "phy_id", phy_id,
+ sizeof(phy_id)) == sizeof(phy_id))
+ conf[port].phy_id = phy_id[1];
+
+ if (OF_getprop(node, "phy-mode", mode, sizeof(mode)) > 0 &&
+ !strcmp(mode, "rgmii"))
+ conf[port].rgmii = 1;
+ else
+ conf[port].rgmii = 0;
+
+ if (port == 0)
+ port = 1;
+ }
}