static void at91emac_halt(struct eth_device *netdev) { at91_emac_t *emac; emac = (at91_emac_t *) netdev->iobase; writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE), &emac->ctl); DEBUG_AT91EMAC("halt MAC\n"); }
static int at91emac_write_hwaddr(struct eth_device *netdev) { emac_device *dev; at91_emac_t *emac; at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; emac = (at91_emac_t *) netdev->iobase; dev = (emac_device *) netdev->priv; writel(1 << AT91_ID_EMAC, &pmc->pcer); DEBUG_AT91EMAC("init MAC-ADDR %x%x \n", cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), cpu_to_le32(*((u32 *)netdev->enetaddr))); writel(cpu_to_le32(*((u32 *)netdev->enetaddr)), &emac->sa2l); writel(cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), &emac->sa2h); DEBUG_AT91EMAC("init MAC-ADDR %x%x \n", readl(&emac->sa2h), readl(&emac->sa2l)); return 0; }
static int at91emac_send(struct eth_device *netdev, volatile void *packet, int length) { at91_emac_t *emac; emac = (at91_emac_t *) netdev->iobase; while (!(readl(&emac->tsr) & AT91_EMAC_TSR_BNQ)) ; writel((u32) packet, &emac->tar); writel(AT91_EMAC_TCR_LEN(length), &emac->tcr); while (AT91_EMAC_TCR_LEN(readl(&emac->tcr))) ; DEBUG_AT91EMAC("Send %d \n", length); writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr); return 0; }
static int at91emac_recv(struct eth_device *netdev) { emac_device *dev; at91_emac_t *emac; rbf_t *rbfp; int size; emac = (at91_emac_t *) netdev->iobase; dev = (emac_device *) netdev->priv; rbfp = &dev->rbfdt[dev->rbindex]; while (rbfp->addr & RBF_OWNER) { size = rbfp->size & RBF_SIZE; NetReceive(NetRxPackets[dev->rbindex], size); DEBUG_AT91EMAC("Recv[%d]: %d bytes @ %x \n", dev->rbindex, size, rbfp->addr); rbfp->addr &= ~RBF_OWNER; rbfp->size = 0; if (dev->rbindex < (RBF_FRAMEMAX-1)) dev->rbindex++; else dev->rbindex = 0; rbfp = &(dev->rbfdt[dev->rbindex]); if (!(rbfp->addr & RBF_OWNER)) writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC, &emac->rsr); } if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) { /* EMAC silicon bug 41.3.1 workaround 1 */ writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl); writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl); dev->rbindex = 0; printf("%s: reset receiver (EMAC dead lock bug)\n", netdev->name); } return 0; }
static int at91emac_init(struct eth_device *netdev, bd_t *bd) { int i; u32 value; emac_device *dev; at91_emac_t *emac; at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; emac = (at91_emac_t *) netdev->iobase; dev = (emac_device *) netdev->priv; /* PIO Disable Register */ value = AT91_PMX_AA_EMDIO | AT91_PMX_AA_EMDC | AT91_PMX_AA_ERXER | AT91_PMX_AA_ERX1 | AT91_PMX_AA_ERX0 | AT91_PMX_AA_ECRS | AT91_PMX_AA_ETX1 | AT91_PMX_AA_ETX0 | AT91_PMX_AA_ETXEN | AT91_PMX_AA_EREFCK; writel(value, &pio->pioa.pdr); writel(value, &pio->pioa.asr); #ifdef CONFIG_RMII value = AT91_PMX_BA_ERXCK; #else value = AT91_PMX_BA_ERXCK | AT91_PMX_BA_ECOL | AT91_PMX_BA_ERXDV | AT91_PMX_BA_ERX3 | AT91_PMX_BA_ERX2 | AT91_PMX_BA_ETXER | AT91_PMX_BA_ETX3 | AT91_PMX_BA_ETX2; #endif writel(value, &pio->piob.pdr); writel(value, &pio->piob.bsr); writel(1 << AT91_ID_EMAC, &pmc->pcer); writel(readl(&emac->ctl) | AT91_EMAC_CTL_CSR, &emac->ctl); DEBUG_AT91EMAC("init MAC-ADDR %x%x \n", cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), cpu_to_le32(*((u32 *)netdev->enetaddr))); writel(cpu_to_le32(*((u32 *)netdev->enetaddr)), &emac->sa2l); writel(cpu_to_le16(*((u16 *)(netdev->enetaddr + 4))), &emac->sa2h); DEBUG_AT91EMAC("init MAC-ADDR %x%x \n", readl(&emac->sa2h), readl(&emac->sa2l)); /* Init Ethernet buffers */ for (i = 0; i < RBF_FRAMEMAX; i++) { dev->rbfdt[i].addr = (unsigned long) NetRxPackets[i]; dev->rbfdt[i].size = 0; } dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP; dev->rbindex = 0; writel((u32) &(dev->rbfdt[0]), &emac->rbqp); writel(readl(&emac->rsr) & ~(AT91_EMAC_RSR_OVR | AT91_EMAC_RSR_REC | AT91_EMAC_RSR_BNA), &emac->rsr); value = AT91_EMAC_CFG_CAF | AT91_EMAC_CFG_NBC | HCLK_DIV; #ifdef CONFIG_RMII value |= AT91C_EMAC_RMII; #endif writel(value, &emac->cfg); writel(readl(&emac->ctl) | AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE, &emac->ctl); if (!at91emac_phy_init(netdev)) { at91emac_UpdateLinkSpeed(emac); return 0; } return 1; }