/* Marvell 88E1310 */
static int m88e1310_config(struct phy_device *phydev)
{
	u16 reg;

	/* LED link and activity */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003);
	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL);
	reg = (reg & ~0xf) | 0x1;
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL, reg);

	/* Set LED2/INT to INT mode, low active */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003);
	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN);
	reg = (reg & 0x77ff) | 0x0880;
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN, reg);

	/* Set RGMII delay */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0002);
	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL);
	reg |= 0x0030;
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL, reg);

	/* Ensure to return to page 0 */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0000);

	genphy_config_aneg(phydev);
	phy_reset(phydev);

	return 0;
}
static int
mvphy_reset_88e1116(phy_handle_t *ph)
{
	uint16_t reg;

	/* make sure that this PHY uses page 0 (copper) */
	phy_write(ph, MVPHY_EADR, 0);

	reg = phy_read(ph, MVPHY_PSC);

	reg &= ~MV_PSC_POWER_DOWN;
	/* Disable energy detect mode */
	reg &= ~MV_PSC_EN_DETECT_MASK;
	reg |= MV_PSC_AUTO_X_MODE;
	reg |= MV_PSC_ASSERT_CRS_TX;
	reg &= ~MV_PSC_POL_REVERSE;
	phy_write(ph, MVPHY_PSC, reg);

	phy_write(ph, MVPHY_EADR, 2);
	PHY_SET(ph, MVPHY_PSC, MV_PSC_RGMII_POWER_UP);

	/* page 3 is led control */
	phy_write(ph, MVPHY_EADR, 3);
	phy_write(ph, MVPHY_PSC,
	    MV_PSC_LED_LOS_CTRL(1) |		/* link/act */
	    MV_PSC_LED_INIT_CTRL(8) |		/* 10 Mbps */
	    MV_PSC_LED_STA1_CTRL(7) |		/* 100 Mbps */
	    MV_PSC_LED_STA0_CTRL(7));		/* 1000 Mbps */
	phy_write(ph, MVPHY_INTEN, 0);

	phy_write(ph, MVPHY_EADR, 0);

	return (phy_reset(ph));
}
Exemple #3
0
/* Marvell 88E1145 */
static int m88e1145_config(struct phy_device *phydev)
{
	int reg;

	/* Errata E0, E1 */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x001b);
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0x418f);
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x0016);
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0xa2da);

	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_SCR,
			MIIM_88E1xxx_PHY_MDI_X_AUTO);

	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR);
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
		reg |= MIIM_M88E1145_RGMII_RX_DELAY |
			MIIM_M88E1145_RGMII_TX_DELAY;
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR, reg);

	genphy_config_aneg(phydev);

	phy_reset(phydev);

	return 0;
}
static int
mvphy_reset_88e3016(phy_handle_t *ph)
{
	uint16_t	reg;
	int		rv;

	rv = phy_reset(ph);

	reg = phy_read(ph, MVPHY_PSC);

	reg |= MV_PSC_AUTO_MDIX;
	reg &= ~(MV_PSC_EN_DETECT | MV_PSC_DIS_SCRAMBLER);
	reg |= MV_PSC_LPNP;

	/* enable class A driver for Yukon FE+ A0. */
	PHY_SET(ph, MII_VENDOR(12), 0x0001);

	phy_write(ph, MVPHY_PSC, reg);

	/* LED2 = ACT blink, LED1 = LINK), LED0 = SPEED */
	phy_write(ph, MVPHY_LED_PSEL,
	    MV_LED_PSEL_LED2(MV_LED_PSEL_ACT_BL) |
	    MV_LED_PSEL_LED1(MV_LED_PSEL_LINK) |
	    MV_LED_PSEL_LED0(MV_LED_PSEL_SPEED));

	/* calibration, values not documented */
	phy_write(ph, MVPHY_PAGE_ADDR, 17);
	phy_write(ph, MVPHY_PAGE_DATA, 0x3f60);

	/* Normal BMCR reset now */
	return (rv);
}
Exemple #5
0
static void pic32_eth_stop(struct udevice *dev)
{
	struct pic32eth_dev *priv = dev_get_priv(dev);
	struct pic32_ectl_regs *ectl_p = priv->ectl_regs;
	struct pic32_emac_regs *emac_p = priv->emac_regs;

	/* Reset the phy if the controller is enabled */
	if (readl(&ectl_p->con1.raw) & ETHCON_ON)
		phy_reset(priv->phydev);

	/* Shut down the PHY */
	phy_shutdown(priv->phydev);

	/* Stop rx/tx */
	writel(ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr);
	mdelay(10);

	/* reset MAC */
	writel(EMAC_SOFTRESET, &emac_p->cfg1.raw);

	/* clear reset */
	writel(0, &emac_p->cfg1.raw);
	mdelay(10);

	/* disable controller */
	writel(ETHCON_ON, &ectl_p->con1.clr);
	mdelay(10);

	/* wait until everything is down */
	wait_for_bit_le32(&ectl_p->stat.raw, ETHSTAT_BUSY, false,
			  2 * CONFIG_SYS_HZ, false);

	/* clear any existing interrupt event */
	writel(0xffffffff, &ectl_p->irq.clr);
}
static int
mvphy_reset_88e1112(phy_handle_t *ph)
{
	uint16_t	reg, page;

	if (phy_read(ph, MVPHY_EPSS) & MV_EPSS_FCRESOL) {

		/* interface indicates fiber */
		PHY_CLR(ph, MVPHY_PSC, MV_PSC_AUTO_X_MODE);

		page = phy_read(ph, MVPHY_EADR);

		/* Go into locked 1000BASE-X mode */
		page = phy_read(ph, MVPHY_EADR);
		phy_write(ph, MVPHY_EADR, 2);
		reg = phy_read(ph, MVPHY_PSC);
		reg &= ~MV_PSC_MODE_MASK;
		reg |= MV_PSC_MODE_1000BASEX;
		phy_write(ph, MVPHY_PSC, reg);
		phy_write(ph, MVPHY_EADR, page);

	} else {
		reg = phy_read(ph, MVPHY_PSC);

		/* Disable energy detect mode */
		reg &= ~MV_PSC_EN_DETECT_MASK;
		reg |= MV_PSC_AUTO_X_MODE;
		reg |= MV_PSC_ASSERT_CRS_TX;
		reg &= ~MV_PSC_POL_REVERSE;
		phy_write(ph, MVPHY_PSC, reg);
	}

	return (phy_reset(ph));
}
Exemple #7
0
/* Broadcom BCM5461S */
static int bcm5461_config(struct phy_device *phydev)
{
	genphy_config_aneg(phydev);

	phy_reset(phydev);

	return 0;
}
Exemple #8
0
static void lan9118_reset(DeviceState *d)
{
    lan9118_state *s = LAN9118(d);

    s->irq_cfg &= (IRQ_TYPE | IRQ_POL);
    s->int_sts = 0;
    s->int_en = 0;
    s->fifo_int = 0x48000000;
    s->rx_cfg = 0;
    s->tx_cfg = 0;
    s->hw_cfg = s->mode_16bit ? 0x00050000 : 0x00050004;
    s->pmt_ctrl &= 0x45;
    s->gpio_cfg = 0;
    s->txp->fifo_used = 0;
    s->txp->state = TX_IDLE;
    s->txp->cmd_a = 0xffffffffu;
    s->txp->cmd_b = 0xffffffffu;
    s->txp->len = 0;
    s->txp->fifo_used = 0;
    s->tx_fifo_size = 4608;
    s->tx_status_fifo_used = 0;
    s->rx_status_fifo_size = 704;
    s->rx_fifo_size = 2640;
    s->rx_fifo_used = 0;
    s->rx_status_fifo_size = 176;
    s->rx_status_fifo_used = 0;
    s->rxp_offset = 0;
    s->rxp_size = 0;
    s->rxp_pad = 0;
    s->rx_packet_size_tail = s->rx_packet_size_head;
    s->rx_packet_size[s->rx_packet_size_head] = 0;
    s->mac_cmd = 0;
    s->mac_data = 0;
    s->afc_cfg = 0;
    s->e2p_cmd = 0;
    s->e2p_data = 0;
    s->free_timer_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 40;

    ptimer_stop(s->timer);
    ptimer_set_count(s->timer, 0xffff);
    s->gpt_cfg = 0xffff;

    s->mac_cr = MAC_CR_PRMS;
    s->mac_hashh = 0;
    s->mac_hashl = 0;
    s->mac_mii_acc = 0;
    s->mac_mii_data = 0;
    s->mac_flow = 0;

    s->read_word_n = 0;
    s->write_word_n = 0;

    phy_reset(s);

    s->eeprom_writable = 0;
    lan9118_reload_eeprom(s);
}
Exemple #9
0
/* Marvell 88E1149S */
static int m88e1149_config(struct phy_device *phydev)
{
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x1f);
	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c);
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x5);
	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x0);
	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);

	genphy_config_aneg(phydev);

	phy_reset(phydev);

	return 0;
}
static int
mvphy_reset_88e1118(phy_handle_t *ph)
{
	uint16_t reg;
	reg = phy_read(ph, MVPHY_PSC);

	/* Disable energy detect mode */
	reg &= ~MV_PSC_EN_DETECT_MASK;
	reg |= MV_PSC_AUTO_X_MODE;
	reg |= MV_PSC_ASSERT_CRS_TX;
	reg &= ~MV_PSC_POL_REVERSE;
	phy_write(ph, MVPHY_PSC, reg);

	return (phy_reset(ph));
}
static int
mvphy_reset_88e3082(phy_handle_t *ph)
{
	uint16_t reg;
	int	rv;

	rv = phy_reset(ph);

	reg = phy_read(ph, MVPHY_PSC);
	reg |= (MV_PSC_AUTO_X_MODE >> 1);
	reg |= MV_PSC_ASSERT_CRS_TX;
	reg &= ~MV_PSC_POL_REVERSE;
	phy_write(ph, MVPHY_PSC, reg);

	return (rv);
}
static int
mvphy_reset(phy_handle_t *ph)
{
	uint16_t reg;

	reg = phy_read(ph, MVPHY_PSC);

	reg &= ~MV_PSC_AUTO_X_MODE;
	reg |= MV_PSC_ASSERT_CRS_TX;
	reg &= ~MV_PSC_POL_REVERSE;
	phy_write(ph, MVPHY_PSC, reg);

	PHY_SET(ph, MVPHY_EPSC, MV_EPSC_TX_CLK_25);

	/* Normal BMCR reset now */
	return (phy_reset(ph));
}
Exemple #13
0
int main()
{
    // Initialize the platform
    platform_init();

    // Configure periodic sending
    soft_timer_init();
    soft_timer_set_handler(&tim, tx, NULL);
    soft_timer_start(&tim, soft_timer_s_to_ticks(1), 1);

    printf("PHY SimpleTX test\n");
    phy_reset(PHY);
    phy_set_channel(PHY, 15);

    platform_run();
    return 0;
}
Exemple #14
0
/** @brief Initialize ethernet
 *
 * This function will initialize ethernet, set up clocks, and initialize DMA.
 *
 * @param[in] phy phy id
 * @param[in] clock enum eth_clk Core clock speed
 */
void eth_init(uint8_t phy, enum eth_clk clock)
{
	ETH_MACMIIAR = clock;
	phy_reset(phy);

	ETH_MACCR = ETH_MACCR_CSTF | ETH_MACCR_FES | ETH_MACCR_DM |
		ETH_MACCR_APCS | ETH_MACCR_RD;
	ETH_MACFFR = ETH_MACFFR_RA | ETH_MACFFR_PM;
	ETH_MACHTHR = 0; /* pass all frames */
	ETH_MACHTLR = 0;
	ETH_MACFCR = (0x100 << ETH_MACFCR_PT_SHIFT);
	ETH_MACVLANTR = 0;
	ETH_DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_DFRF |
		ETH_DMAOMR_TSF | ETH_DMAOMR_FEF | ETH_DMAOMR_OSF;
	ETH_DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_FB |
		(32 << ETH_DMABMR_RDP_SHIFT) | (32 << ETH_DMABMR_PBL_SHIFT) |
		ETH_DMABMR_PM_2_1 | ETH_DMABMR_USP;
}
Exemple #15
0
/* Marvell 88E1118 */
static int m88e1118_config(struct phy_device *phydev)
{
	/* Change Page Number */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0002);
	/* Delay RGMII TX and RX */
	phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x1070);
	/* Change Page Number */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0003);
	/* Adjust LED control */
	phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x021e);
	/* Change Page Number */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);

	genphy_config_aneg(phydev);

	phy_reset(phydev);

	return 0;
}
Exemple #16
0
static void do_phy_write(Ftgmac100State *s, int reg, uint32_t val)
{
    PHY_DEBUG("PHY: write 0x%04x @%d\n", val, reg);

    if (reg > 31) {
        /* we only advertise one phy */
        return;
    }

    switch (reg) {
    case 0:     /* Basic Control */
        if (val & 0x8000) {
            phy_reset(s);
        } else {
            s->phy_control = val & 0x7980;
            /* Complete autonegotiation immediately.  */
            if (val & 0x1000) {
                s->phy_status |= 0x0020;
            }
        }
        break;
    case 4:     /* Auto-neg advertisement */
        s->phy_advertise = (val & 0x2d7f) | 0x80;
        break;
    case 30:    /* Interrupt mask */
        s->phy_int_mask = val & 0xff;
        phy_update_irq(s);
        break;
    case 17:
    case 18:
    case 27:
    case 31:
        qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
                      __func__, reg);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
                      __func__, reg);
        break;
    }
}
Exemple #17
0
static void ftgmac100_reset(DeviceState *d)
{
    Ftgmac100State *s = FTGMAC100(d);

    /* Reset the FTGMAC100 */
    s->isr = 0;
    s->ier = 0;
    s->rx_enabled = 0;
    s->maccr = 0;
    s->rx_ring = 0;
    s->rx_descriptor = 0;
    s->rbsr = 0x640; /* HW default according to u-boot driver */
    s->tx_ring = 0;
    s->tx_descriptor = 0;
    s->phycr = 0;
    s->phydata = 0;
    s->aptcr = 0;

    /* We also reset the PHY */
    phy_reset(s);
}
static int
mvphy_reset_88e1011(phy_handle_t *ph)
{
	uint16_t reg;

	if (phy_read(ph, MVPHY_EPSS) & MV_EPSS_FCRESOL) {

		/* interface indicates fiber */
		PHY_CLR(ph, MVPHY_PSC, MV_PSC_AUTO_X_MODE);

	} else {
		reg = phy_read(ph, MVPHY_PSC);
		reg &= ~MV_PSC_AUTO_X_MODE;
		reg |= MV_PSC_ASSERT_CRS_TX;
		reg &= ~MV_PSC_POL_REVERSE;
		phy_write(ph, MVPHY_PSC, reg);
	}
	/* force TX CLOCK to 25 MHz */
	PHY_SET(ph, MVPHY_EPSC, MV_EPSC_TX_CLK_25);

	return (phy_reset(ph));
}
Exemple #19
0
/* Initialize pins in complex peripheral */
void init_eth(void)
{
	int phy_pins[] = {
		PHY_CRSDV,	PHY_RXD0,	PHY_RXD1,	PHY_REFCLK,
		PHY_TXEN,	PHY_TXD0,	PHY_TXD1,	PHY_MDIO,
		PHY_MDC
	};
	
	/* Initialize all pins that belongs to RMII */
	for (int i = 0; i < sizeof(phy_pins) / sizeof(phy_pins[0]); i++) {
		pin_clock_enable(phy_pins[i]);
		pin_af_pushpull(phy_pins[i]);
		pin_speed_high(phy_pins[i]);
		pin_af_map(phy_pins[i], GPIO_AF_ETH);
	}

	pin_input(PHY_INTRP);
	pin_pull_up(PHY_INTRP);
	pin_set(PHY_RST, true);
	pin_output_pushpull(PHY_RST);


	/* Reset the connected PHY by signal */
	pin_set(PHY_RST, false);
	for (int i = 0; i < 10000; i++) {
		__asm volatile ("nop");
	}
	pin_set(PHY_RST, true);
	for (int i = 0; i < 10000; i++) {
		__asm volatile ("nop");
	}
	
	/* Initialize phy over SNI */
	phy_reset(1);			/* out of scope of this example */
	
	/* Initialize ethernet MAC */
	eth_init();			/* out of scope of this example */
}
static int
ns83840_reset(phy_handle_t *ph)
{
	/* first do an ordinary reset */
	if (phy_reset(ph) != DDI_SUCCESS) {
		return (DDI_FAILURE);
	}

	/*
	 * As per INTEL "PRO/100B Adapter Software Technical Reference
	 * Manual", set bit 10 of MII register 23.  National
	 * Semiconductor documentation shows this as "reserved, write
	 * to as zero". We also set the "CIM_DIS" bit, also as
	 * requested by the PRO/100B doc, to disable the carrier
	 * integrity monitor.  (That should only ever be used by
	 * repeaters.)
	 *
	 * NetBSD also sets bit 8, without any explanation, so we'll
	 * follow suit.
	 */
	PHY_SET(ph, MII_VENDOR(7), (1<<10) | (1<<8) | (1<<5));
	return (DDI_SUCCESS);
}
Exemple #21
0
/* Marvell 88E1111S */
static int m88e1111s_config(struct phy_device *phydev)
{
	int reg;

	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
			(phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
			(phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
			(phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
		reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x1b);
		reg = (reg & 0xfff0) | 0xb;
		phy_write(phydev, MDIO_DEVAD_NONE, 0x1b, reg);
	} else {
		phy_write(phydev, MDIO_DEVAD_NONE, 0x1b, 0x1f);
	}

	phy_write(phydev, MDIO_DEVAD_NONE, 0x14, 0x0cd2);

	genphy_config_aneg(phydev);

	phy_reset(phydev);

	return 0;
}
Exemple #22
0
static int exynos_pcie_establish_link(struct exynos_pcie *ep)
{
	struct dw_pcie *pci = ep->pci;
	struct pcie_port *pp = &pci->pp;
	struct device *dev = pci->dev;

	if (dw_pcie_link_up(pci)) {
		dev_err(dev, "Link already up\n");
		return 0;
	}

	exynos_pcie_assert_core_reset(ep);

	phy_reset(ep->phy);

	exynos_pcie_writel(ep->mem_res->elbi_base, 1,
			PCIE_PWR_RESET);

	phy_power_on(ep->phy);
	phy_init(ep->phy);

	exynos_pcie_deassert_core_reset(ep);
	dw_pcie_setup_rc(pp);
	exynos_pcie_assert_reset(ep);

	/* assert LTSSM enable */
	exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
			  PCIE_APP_LTSSM_ENABLE);

	/* check if the link is up or not */
	if (!dw_pcie_wait_for_link(pci))
		return 0;

	phy_power_off(ep->phy);
	return -ETIMEDOUT;
}
Exemple #23
0
    void reset() {
        phy_reset();
        // device reset - the RST bit is self-clearing
        ioreg(reg::CTRL, ioreg(reg::CTRL) | CTRL_RST);
        for (int timeout = 0; ; ++timeout) {
            REQUIRE(timeout < 1000 && "Failed to reset i825x device");
            delay_microseconds(2); // Need to delay at least 1us before reading status after a reset
            if (!(ioreg(reg::CTRL) & CTRL_RST)) {
                break;
            }
        }

        // LRST->0 enables auto-negotiation, clear ILOS and disable VLAN Mode Enable
        ioreg(reg::CTRL, (ioreg(reg::CTRL) & ~(CTRL_LRST | CTRL_ILOS | CTRL_VME)) | CTRL_ASDE | CTRL_SLU);

        // TODO: Reset flow control
        // TODO: Clear statistics counters

        // Program the Receive Address Register
        ioreg(reg::RAL0, (mac_addr_[0]) | (mac_addr_[1] << 8) | (mac_addr_[2] << 16) | (mac_addr_[3] << 24));
        ioreg(reg::RAH0, (mac_addr_[4]) | (mac_addr_[5] << 8) | RAH_AV);

        // Initialize the MTA (Multicast Table Array) to 0
        for (int i = 0; i < 128; i++) {
            ioreg(static_cast<reg>(static_cast<uint32_t>(reg::MTA) + i * 4), 0);
        }

        // Program the Interrupt Mask Set/Read (IMS) register
        ioreg(reg::IMC, ~0U); // Inhibit interrupts
        ioreg(reg::ICR, ~0U); // Clear pending interrupts
        ioreg(reg::IMS, ICR_TXDW | ICR_LSC | ICR_RXDMT0 | ICR_RXT0); // Enable interrupts

        // Program the Receive Descriptor Base Address
        const uint64_t rx_desc_phys = virt_to_phys((const void*)&rx_desc_[0]);
        ioreg(reg::RDBAL0, static_cast<uint32_t>(rx_desc_phys));
        ioreg(reg::RDBAH0, static_cast<uint32_t>(rx_desc_phys>>32));

        // Set the Receive Descriptor Length (RDLEN) register to the size (in bytes) of the descriptor ring.
        ioreg(reg::RDLEN0, sizeof(rx_desc_));

        // Initialize Receive Descriptor Head and Tail registers
        ioreg(reg::RDH0, 0);
        ioreg(reg::RDT0, num_rx_descriptors-1);

        memset((void*)rx_desc_, 0, sizeof(rx_desc_));
        for (uint32_t i = 0; i < num_rx_descriptors; ++i) {
            rx_desc_[i].buffer_addr = virt_to_phys(rx_buffer_[i]);
            rx_desc_[i].status = 0;
        }

        // Enable RX
        ioreg(reg::RCTL, RCTL_EN
                           | RCTL_SBP // recieve everyting
                           | RCTL_UPE // even
                           | RCTL_MPE // bad packets
                           | RCTL_BAM // and multicast..
                           | RCTL_SZ_2048);
        rx_head_ = 0;

        // Enable TX
        memset((void*)tx_desc_, 0, sizeof(tx_desc_));
        const uint64_t tx_desc_phys = virt_to_phys((const void*)&tx_desc_[0]);
        REQUIRE((tx_desc_phys & 15) == 0);
        ioreg(reg::TDBAL0, static_cast<uint32_t>(tx_desc_phys));
        ioreg(reg::TDBAH0, static_cast<uint32_t>(tx_desc_phys>>32));

        ioreg(reg::TDLEN0, sizeof(tx_desc_));
        static_assert(sizeof(tx_desc_) % 128 == 0, "");
        static_assert(sizeof(tx_desc_) >= 128, "");

        // Set the transmit descriptor write-back policy
        ioreg(reg::TXDCTL0, (ioreg(reg::TXDCTL0) & TXDCTL_WTHRESH) | TXDCTL_FULL_TX_DESC_WB/* | TXDCTL_COUNT_DESC*/);
        ioreg(reg::TDH0, 0);
        ioreg(reg::TDT0, 0);
        ioreg(reg::TCTL, ioreg(reg::TCTL) | TCTL_EN | TCTL_PSP);

        tx_tail_ = 0;
    }
Exemple #24
0
/* Marvell 88E1111S */
static int m88e1111s_config(struct phy_device *phydev)
{
	int reg;

	if (phy_interface_is_rgmii(phydev)) {
		reg = phy_read(phydev,
			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
		if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
		    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) {
			reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
			reg &= ~MIIM_88E1111_TX_DELAY;
			reg |= MIIM_88E1111_RX_DELAY;
		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
			reg &= ~MIIM_88E1111_RX_DELAY;
			reg |= MIIM_88E1111_TX_DELAY;
		}

		phy_write(phydev,
			  MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);

		reg = phy_read(phydev,
			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);

		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);

		if (reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES)
			reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII;
		else
			reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII;

		phy_write(phydev,
			  MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg);
	}

	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
		reg = phy_read(phydev,
			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);

		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
		reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK;
		reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;

		phy_write(phydev, MDIO_DEVAD_NONE,
			  MIIM_88E1111_PHY_EXT_SR, reg);
	}

	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
		reg = phy_read(phydev,
			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
		reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
		phy_write(phydev,
			  MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);

		reg = phy_read(phydev, MDIO_DEVAD_NONE,
			       MIIM_88E1111_PHY_EXT_SR);
		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK |
			MIIM_88E1111_HWCFG_FIBER_COPPER_RES);
		reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
		phy_write(phydev, MDIO_DEVAD_NONE,
			  MIIM_88E1111_PHY_EXT_SR, reg);

		/* soft reset */
		phy_reset(phydev);

		reg = phy_read(phydev, MDIO_DEVAD_NONE,
			       MIIM_88E1111_PHY_EXT_SR);
		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK |
			 MIIM_88E1111_HWCFG_FIBER_COPPER_RES);
		reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI |
			MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
		phy_write(phydev, MDIO_DEVAD_NONE,
			  MIIM_88E1111_PHY_EXT_SR, reg);
	}

	/* soft reset */
	phy_reset(phydev);

	genphy_config_aneg(phydev);
	genphy_restart_aneg(phydev);

	return 0;
}
Exemple #25
0
static int m88e1518_config(struct phy_device *phydev)
{
	u16 reg;

	/*
	 * As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
	 * /88E1514 Rev A0, Errata Section 3.1
	 */

	/* EEE initialization */
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x00ff);
	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146);
	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233);
	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);

	/* SGMII-to-Copper mode initialization */
	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
		/* Select page 18 */
		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 18);

		/* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
		m88e1518_phy_writebits(phydev, MIIM_88E151x_GENERAL_CTRL,
				       0, 3, MIIM_88E151x_MODE_SGMII);

		/* PHY reset is necessary after changing MODE[2:0] */
		m88e1518_phy_writebits(phydev, MIIM_88E151x_GENERAL_CTRL,
				       MIIM_88E151x_RESET_OFFS, 1, 1);

		/* Reset page selection */
		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0);

		udelay(100);
	}

	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
		reg = phy_read(phydev, MDIO_DEVAD_NONE,
			       MIIM_88E1111_PHY_EXT_SR);

		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
		reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK;
		reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;

		phy_write(phydev, MDIO_DEVAD_NONE,
			  MIIM_88E1111_PHY_EXT_SR, reg);
	}

	if (phy_interface_is_rgmii(phydev)) {
		phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 2);

		reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR);
		reg &= ~MIIM_88E151x_RGMII_RXTX_DELAY;
		if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
		    phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
			reg |= MIIM_88E151x_RGMII_RXTX_DELAY;
		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
			reg |= MIIM_88E151x_RGMII_RX_DELAY;
		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
			reg |= MIIM_88E151x_RGMII_TX_DELAY;
		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR, reg);

		phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 0);
	}

	/* soft reset */
	phy_reset(phydev);

	genphy_config_aneg(phydev);
	genphy_restart_aneg(phydev);

	return 0;
}
Exemple #26
0
/*
 * mac hw init is done here
 */
static int enet_hw_init(struct net_device *dev)
{
	struct tangox_enet_priv *priv;
	unsigned int val = 0;

	if(phy_reset(dev))
		return -EBUSY;

	priv = netdev_priv(dev);

	/* set pad_mode according to rgmii or not*/
	val = enet_readb(priv->enet_mac_base + 0x400) & 0xf0;
	if(priv->rgmii)
		enet_writeb(priv->enet_mac_base + 0x400, val | 0x01);

	/* software reset IP */
	enet_writeb(priv->enet_mac_base + 0x424, 0);
	udelay(10);
	enet_writeb(priv->enet_mac_base + 0x424, 1);

	/*set threshold for internal clock 0x1*/
	enet_writeb(ENET_IC_THRESHOLD(priv->enet_mac_base), 1);

	/*set Random seed 0x8*/
	enet_writeb(ENET_RANDOM_SEED(priv->enet_mac_base), 0x08);

	/*set TX single deferral params 0xc*/
	enet_writeb(ENET_TX_SDP(priv->enet_mac_base), 0xc);

	/*set slot time  0x7f for 10/100Mbps*/
	enet_writeb(ENET_SLOT_TIME(priv->enet_mac_base), 0x7f);

	/*set Threshold for partial full  0x7f */
	enet_writeb(ENET_PF_THRESHOLD(priv->enet_mac_base), 0x7f);

	/* configure TX DMA Channels */
	val = enet_readl(ENET_TXC_CR(priv->enet_mac_base));
	val |=	TCR_RS  | TCR_LE  | TCR_TFI(1) | 
		/*TCR_DIE |*/ TCR_BTS(2);
	val |=	TCR_DM;
 
	enet_writel(ENET_TXC_CR(priv->enet_mac_base), val);
	val = enet_readl(ENET_TXC_CR(priv->enet_mac_base));

 	/* configure RX DMA Channels */
	val = enet_readl(ENET_RXC_CR(priv->enet_mac_base));
	val |= (RCR_RS    | RCR_LE | RCR_RFI(1) | 
		RCR_BTS(2) | RCR_FI | RCR_DIE /* | RCR_EN*/); 
	val |=	RCR_DM;

	val |=  RX_BUF_SIZE << 16;
	enet_writel(ENET_RXC_CR(priv->enet_mac_base), val); 

	/* configure MAC ctrller */
	val = enet_readb(ENET_TX_CTL1(priv->enet_mac_base));
	val |= (TX_RETRY_EN | TX_PAD_EN | TX_APPEND_FCS);
	enet_writeb(ENET_TX_CTL1(priv->enet_mac_base), (unsigned char)val);

	/* set retry 5 time when collision occurs*/
	enet_writeb(ENET_TX_CTL2(priv->enet_mac_base), 5);

	val = enet_readb(ENET_RX_CTL(priv->enet_mac_base));
	val |= (RX_RUNT | RX_PAD_STRIP | RX_SEND_CRC 
	                | RX_PAUSE_EN| RX_AF_EN);
	enet_writeb(ENET_RX_CTL(priv->enet_mac_base), (unsigned char)val);

#ifdef ENABLE_MULTICAST
	/* clear internal multicast address table */
	enet_writeb(ENET_MC_INIT(priv->enet_mac_base),  0x00);
	while(enet_readb(ENET_MC_INIT(priv->enet_mac_base)));
	DBG("Internal multicast address table is cleared\n");
#endif

	/* unicast */
	/* Threshold for internal clock*/
	/* threshold for partial empty*/
	/* threshold for partial full */

	/* buffer size for transmit must be 1 from the doc
	   however, it's said that using 0xff ??*/
	enet_writeb(ENET_TX_BUFSIZE(priv->enet_mac_base), 0xff);

	/* fifo control */

	/*MAC mode*/
	enet_mac_config(dev);

	/* check gmii mode support */
	priv->mii.supports_gmii = mii_check_gmii_support(&priv->mii);
	DBG("gmii support=0x%x id=0x%x\n", priv->mii.supports_gmii, priv->mii.phy_id);

	return 0;
}
Exemple #27
0
static char *radio_pkt(uint8_t channel, uint8_t tx_power)
{
    static phy_packet_t tx_pkt = {
        .data = tx_pkt.raw_data,
        .length = 125,
    };
    uint16_t i;
    for (i = 0; i < 125; i++) {
        tx_pkt.data[i] = i;
    }

    int success;
    char *ret = NULL;
    xQueueReceive(radio_queue, &success, 0);  // cleanup queue

    phy_idle(platform_phy);

    /*
     * config radio
     */
    if (phy_set_channel(platform_phy, channel))
        ON_ERROR("err_set_channel", radio_cleanup);
    if (phy_set_power(platform_phy, tx_power))
        ON_ERROR("err_set_power", radio_cleanup);

    /*
     * Send packet
     *
     * No interlocking because
     *     Current queue is EVENT_QUEUE_APPLI
     *     phy_ handlers are executed by EVENT_QUEUE_NETWORK
     */
    if (phy_tx_now(platform_phy, &tx_pkt, radio_rx_tx_done))
        ON_ERROR("err_tx", radio_cleanup);
    if (pdTRUE != xQueueReceive(radio_queue, &success, ONE_SECOND) || !success)
        ON_ERROR("tx_failed", radio_cleanup);

    // SUCCESS

radio_cleanup:
    phy_reset(platform_phy);
    return ret;
}

static char *radio_ping_pong(uint8_t channel, uint8_t tx_power)
{
    char *ret = NULL;
    int success;
    static phy_packet_t tx_pkt = {
        .data = tx_pkt.raw_data,
        .length = sizeof(RADIO_TX_STR),
        .raw_data = RADIO_TX_STR,
    };
    static phy_packet_t rx_pkt = {.data = rx_pkt.raw_data};

    xQueueReceive(radio_queue, &success, 0);  // cleanup queue

    phy_idle(platform_phy);

    /* config radio */
    if (phy_set_channel(platform_phy, channel))
        ON_ERROR("err_set_channel", ping_pong_cleanup);
    if (phy_set_power(platform_phy, tx_power))
        ON_ERROR("err_set_power", ping_pong_cleanup);

    /*
     * Send packet
     *
     * No interlocking because
     *     Current queue is EVENT_QUEUE_APPLI
     *     phy_ handlers are executed by EVENT_QUEUE_NETWORK
     */
    if (phy_tx_now(platform_phy, &tx_pkt, radio_rx_tx_done))
        ON_ERROR("err_tx", ping_pong_cleanup);
    if (pdTRUE != xQueueReceive(radio_queue, &success, ONE_SECOND) || !success)
        ON_ERROR("tx_failed", ping_pong_cleanup);

    /*
     * Wait for answer
     */
    memset(rx_pkt.raw_data, 0, sizeof(rx_pkt.raw_data));
    phy_rx_now(platform_phy, &rx_pkt, radio_rx_tx_done);
    if (pdTRUE != xQueueReceive(radio_queue, &success, ONE_SECOND) || !success)
        ON_ERROR("rx_timeout", ping_pong_cleanup);

    // Packet reception
    if (strcmp("RX_PKT_HELLO_WORLD", (char *)rx_pkt.raw_data))
        ON_ERROR("wrong_packet_received", ping_pong_cleanup);

    // SUCCESS
    ret = NULL;

ping_pong_cleanup:
    phy_reset(platform_phy);
    return ret;
}

#ifdef IOTLAB_M3

////////
static int test_flash_nand()
{
    static uint8_t buf_EE[256] = {[0 ... 255] = 0xEE};
    static uint8_t buf[256]    = {[0 ... 255] = 0x00};

    // Write subsector 200 and re-read it
    n25xxx_write_enable(); n25xxx_erase_subsector(0x00c80000);
    n25xxx_write_enable(); n25xxx_write_page(0x00c80000, buf_EE);
    n25xxx_read(0x00c80000, buf, sizeof(buf));
    n25xxx_write_enable(); n25xxx_erase_subsector(0x00c80000);

    // check read values
    return memcmp(buf_EE, buf, sizeof(buf));
}
////////


static int cmd_get_light(char *command)
{
    if (strcmp(command, "get_light"))
        return 1;
    printf("ACK get_light %f lux\n", isl29020_read_sample());
    return 0;
}

static int cmd_get_pressure(char *command)
{
    if (strcmp(command, "get_pressure"))
        return 1;

    uint32_t pressure;
    lps331ap_read_pres(&pressure);
    printf("ACK get_pressure %f mbar\n", pressure / 4096.0);
    return 0;
}

static int cmd_test_flash_nand(char *command)
{
    if (strcmp(command, "test_flash"))
        return 1;

    if (test_flash_nand())
        printf("NACK test_flash read_different_write\n");
    else
        printf("ACK test_flash\n");
    return 0;
}

#endif // IOTLAB_M3


/* Leds Commands */
static int cmd_leds_on(char *command)
{
    uint8_t leds = 0;
    if (1 != sscanf(command, "leds_on %u", &leds))
        return 1;

    leds_on(leds);
    printf("ACK leds_on %x\n", leds);
    return 0;
}

static int cmd_leds_off(char *command)
{
    uint8_t leds = 0;
    if (1 != sscanf(command, "leds_off %u", &leds))
        return 1;

    leds_off(leds);
    printf("ACK leds_off %x\n", leds);
    return 0;
}
static int
mvphy_reset_88e1149(phy_handle_t *ph)
{
	uint16_t reg;
	int rv;

	/* make sure that this PHY uses page 0 (copper) */
	phy_write(ph, MVPHY_EADR, 0);

	reg = phy_read(ph, MVPHY_PSC);
	/* Disable energy detect mode */
	reg &= ~MV_PSC_EN_DETECT_MASK;
	reg |= MV_PSC_AUTO_X_MODE;
	reg |= MV_PSC_DOWNSHIFT_EN;
	reg &= ~MV_PSC_POL_REVERSE;
	phy_write(ph, MVPHY_PSC, reg);

	rv = phy_reset(ph);

	phy_write(ph, MVPHY_EADR, 2);
	PHY_SET(ph, MVPHY_PSC, MV_PSC_RGMII_POWER_UP);

	/*
	 * Fix for signal amplitude in 10BASE-T, undocumented.
	 * This is from the Marvell reference source code.
	 */
	phy_write(ph, MVPHY_EADR, 255);
	phy_write(ph, 0x18, 0xaa99);
	phy_write(ph, 0x17, 0x2011);

	if (MII_PHY_REV(ph->phy_id) == 0) {
		/*
		 * EC_U: IEEE A/B 1000BASE-T symmetry failure
		 *
		 * EC_U is rev 0, Ultra 2 is rev 1 (at least the
		 * unit I have), so we trigger on revid.
		 */
		phy_write(ph, 0x18, 0xa204);
		phy_write(ph, 0x17, 0x2002);
	}

	/* page 3 is led control */
	phy_write(ph, MVPHY_EADR, 3);
	phy_write(ph, MVPHY_PSC,
	    MV_PSC_LED_LOS_CTRL(1) |		/* link/act */
	    MV_PSC_LED_INIT_CTRL(8) |		/* 10 Mbps */
	    MV_PSC_LED_STA1_CTRL(7) |		/* 100 Mbps */
	    MV_PSC_LED_STA0_CTRL(7));		/* 1000 Mbps */
	phy_write(ph, MVPHY_INTEN, 0);

	phy_write(ph, MVPHY_EADR, 0);

	/*
	 * Weird... undocumented logic in the Intel e1000g driver.
	 * I'm not sure what these values really do.
	 */
	phy_write(ph, MVPHY_PAGE_ADDR, 3);
	phy_write(ph, MVPHY_PAGE_DATA, 0);

	return (rv);
}