> Date: Sun, 26 Jun 2016 22:46:26 +1000
> From: Jonathan Gray <[email protected]>
>
> With cpsw being a switch getting the port config isn't as
> straightforward as fec.
Not terribly fond of the !strcmp() idiom, but otherwise this looks ok
to me.
> 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;
> + }
> }
>
>