Date: Wed, 26 Feb 2014 01:32:07 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r262514 - head/sys/dev/etherswitch/arswitch Message-ID: <201402260132.s1Q1W7mf026168@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Wed Feb 26 01:32:06 2014 New Revision: 262514 URL: http://svnweb.freebsd.org/changeset/base/262514 Log: Undo the DB120 hard-coded values in the AR8327 code and fetch it from the hints environment. Tested: * DB120 Modified: head/sys/dev/etherswitch/arswitch/arswitch_8327.c Modified: head/sys/dev/etherswitch/arswitch/arswitch_8327.c ============================================================================== --- head/sys/dev/etherswitch/arswitch/arswitch_8327.c Wed Feb 26 01:19:52 2014 (r262513) +++ head/sys/dev/etherswitch/arswitch/arswitch_8327.c Wed Feb 26 01:32:06 2014 (r262514) @@ -217,6 +217,196 @@ ar8327_get_port_init_status(struct ar832 } /* + * Fetch the port data for the given port. + * + * This goes and does dirty things with the hints space + * to determine what the configuration parameters should be. + * + * Returns 1 if the structure was successfully parsed and + * the contents are valid; 0 otherwise. + */ +static int +ar8327_fetch_pdata_port(struct arswitch_softc *sc, + struct ar8327_port_cfg *pcfg, + int port) +{ + int val; + char sbuf[128]; + + /* Check if force_link exists */ + val = 0; + snprintf(sbuf, 128, "port.%d.force_link", port); + (void) resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val); + if (val != 1) + return (0); + pcfg->force_link = 1; + + /* force_link is set; let's parse the rest of the fields */ + snprintf(sbuf, 128, "port.%d.speed", port); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) { + switch (val) { + case 10: + pcfg->speed = AR8327_PORT_SPEED_10; + break; + case 100: + pcfg->speed = AR8327_PORT_SPEED_100; + break; + case 1000: + pcfg->speed = AR8327_PORT_SPEED_1000; + break; + default: + device_printf(sc->sc_dev, + "%s: invalid port %d duplex value (%d)\n", + __func__, + port, + val); + return (0); + } + } + + snprintf(sbuf, 128, "port.%d.duplex", port); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pcfg->duplex = val; + + snprintf(sbuf, 128, "port.%d.txpause", port); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pcfg->txpause = val; + + snprintf(sbuf, 128, "port.%d.rxpause", port); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pcfg->rxpause = val; + +#if 0 + device_printf(sc->sc_dev, + "%s: port %d: speed=%d, duplex=%d, txpause=%d, rxpause=%d\n", + __func__, + port, + pcfg->speed, + pcfg->duplex, + pcfg->txpause, + pcfg->rxpause); +#endif + + return (1); +} + +/* + * Parse the pad configuration from the boot hints. + * + * The (mostly optional) fields are: + * + * uint32_t mode; + * uint32_t rxclk_sel; + * uint32_t txclk_sel; + * uint32_t txclk_delay_sel; + * uint32_t rxclk_delay_sel; + * uint32_t txclk_delay_en; + * uint32_t rxclk_delay_en; + * uint32_t sgmii_delay_en; + * uint32_t pipe_rxclk_sel; + * + * If mode isn't in the hints, 0 is returned. + * Else the structure is fleshed out and 1 is returned. + */ +static int +ar8327_fetch_pdata_pad(struct arswitch_softc *sc, + struct ar8327_pad_cfg *pc, + int pad) +{ + int val; + char sbuf[128]; + + /* Check if mode exists */ + val = 0; + snprintf(sbuf, 128, "pad.%d.mode", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) != 0) + return (0); + + /* assume that 'mode' exists and was found */ + pc->mode = val; + + snprintf(sbuf, 128, "pad.%d.rxclk_sel", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->rxclk_sel = val; + + snprintf(sbuf, 128, "pad.%d.txclk_sel", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->txclk_sel = val; + + snprintf(sbuf, 128, "pad.%d.txclk_delay_sel", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->txclk_delay_sel = val; + + snprintf(sbuf, 128, "pad.%d.rxclk_delay_sel", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->rxclk_delay_sel = val; + + snprintf(sbuf, 128, "pad.%d.txclk_delay_en", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->txclk_delay_en = val; + + snprintf(sbuf, 128, "pad.%d.rxclk_delay_en", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->rxclk_delay_en = val; + + snprintf(sbuf, 128, "pad.%d.sgmii_delay_en", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->sgmii_delay_en = val; + + snprintf(sbuf, 128, "pad.%d.pipe_rxclk_sel", pad); + if (resource_int_value(device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev), + sbuf, &val) == 0) + pc->pipe_rxclk_sel = val; + +#if 0 + device_printf(sc->sc_dev, + "%s: pad %d: mode=%d, rxclk_sel=%d, txclk_sel=%d, " + "txclk_delay_sel=%d, rxclk_delay_sel=%d, txclk_delay_en=%d, " + "rxclk_enable_en=%d, sgmii_delay_en=%d, pipe_rxclk_sel=%d\n", + __func__, + pad, + pc->mode, + pc->rxclk_sel, + pc->txclk_sel, + pc->txclk_delay_sel, + pc->rxclk_delay_sel, + pc->txclk_delay_en, + pc->rxclk_delay_en, + pc->sgmii_delay_en, + pc->pipe_rxclk_sel); +#endif + + return (1); +} + +/* * Initialise the ar8327 specific hardware features from * the hints provided in the boot environment. */ @@ -227,44 +417,41 @@ ar8327_init_pdata(struct arswitch_softc struct ar8327_port_cfg port_cfg; uint32_t t; - /* XXX hard-coded DB120 defaults for now! */ - - /* Port 0 - rgmii; 1000/full */ + /* Port 0 */ bzero(&port_cfg, sizeof(port_cfg)); - port_cfg.speed = AR8327_PORT_SPEED_1000; - port_cfg.duplex = 1; - port_cfg.rxpause = 1; - port_cfg.txpause = 1; - port_cfg.force_link = 1; - sc->ar8327.port0_status = ar8327_get_port_init_status(&port_cfg); + sc->ar8327.port0_status = 0; + if (ar8327_fetch_pdata_port(sc, &port_cfg, 0)) + sc->ar8327.port0_status = ar8327_get_port_init_status(&port_cfg); - /* Port 6 - ignore */ + /* Port 6 */ bzero(&port_cfg, sizeof(port_cfg)); - sc->ar8327.port6_status = ar8327_get_port_init_status(&port_cfg); + sc->ar8327.port6_status = 0; + if (ar8327_fetch_pdata_port(sc, &port_cfg, 6)) + sc->ar8327.port6_status = ar8327_get_port_init_status(&port_cfg); /* Pad 0 */ bzero(&pc, sizeof(pc)); - pc.mode = AR8327_PAD_MAC_RGMII, - pc.txclk_delay_en = true, - pc.rxclk_delay_en = true, - pc.txclk_delay_sel = AR8327_CLK_DELAY_SEL1, - pc.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, - - t = ar8327_get_pad_cfg(&pc); + t = 0; + if (ar8327_fetch_pdata_pad(sc, &pc, 0)) + t = ar8327_get_pad_cfg(&pc); #if 0 - if (AR8X16_IS_SWITCH(sc, AR8337)) - t |= AR8337_PAD_MAC06_EXCHANGE_EN; + if (AR8X16_IS_SWITCH(sc, AR8337)) + t |= AR8337_PAD_MAC06_EXCHANGE_EN; #endif arswitch_writereg(sc->sc_dev, AR8327_REG_PAD0_MODE, t); /* Pad 5 */ bzero(&pc, sizeof(pc)); - t = ar8327_get_pad_cfg(&pc); + t = 0; + if (ar8327_fetch_pdata_pad(sc, &pc, 5)) + t = ar8327_get_pad_cfg(&pc); arswitch_writereg(sc->sc_dev, AR8327_REG_PAD5_MODE, t); /* Pad 6 */ bzero(&pc, sizeof(pc)); - t = ar8327_get_pad_cfg(&pc); + t = 0; + if (ar8327_fetch_pdata_pad(sc, &pc, 6)) + t = ar8327_get_pad_cfg(&pc); arswitch_writereg(sc->sc_dev, AR8327_REG_PAD6_MODE, t); /* XXX LED config */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402260132.s1Q1W7mf026168>