]> git.sur5r.net Git - u-boot/blobdiff - drivers/net/bfin_mac.c
Merge git://www.denx.de/git/u-boot-marvell
[u-boot] / drivers / net / bfin_mac.c
index 12d98c2df551e887d861bc0bb41d577cb7d4a4ca..26a626b4cbd59eea4eef55886213bf6c3d2cde66 100644 (file)
 #include <command.h>
 #include <malloc.h>
 #include <miiphy.h>
+#include <linux/mdio.h>
 #include <linux/mii.h>
 
 #include <asm/blackfin.h>
+#include <asm/clock.h>
+#include <asm/portmux.h>
 #include <asm/mach-common/bits/dma.h>
 #include <asm/mach-common/bits/emac.h>
 #include <asm/mach-common/bits/pll.h>
@@ -70,18 +73,20 @@ static int bfin_miiphy_wait(void)
        return 0;
 }
 
-static int bfin_miiphy_read(char *devname, uchar addr, uchar reg, ushort *val)
+static int bfin_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
 {
+       ushort val = 0;
        if (bfin_miiphy_wait())
                return 1;
        bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY);
        if (bfin_miiphy_wait())
                return 1;
-       *val = bfin_read_EMAC_STADAT();
-       return 0;
+       val = bfin_read_EMAC_STADAT();
+       return val;
 }
 
-static int bfin_miiphy_write(char *devname, uchar addr, uchar reg, ushort val)
+static int bfin_miiphy_write(struct mii_dev *bus, int addr, int devad,
+                            int reg, u16 val)
 {
        if (bfin_miiphy_wait())
                return 1;
@@ -98,7 +103,7 @@ int bfin_EMAC_initialize(bd_t *bis)
                hang();
 
        memset(dev, 0, sizeof(*dev));
-       sprintf(dev->name, "Blackfin EMAC");
+       strcpy(dev->name, "bfin_mac");
 
        dev->iobase = 0;
        dev->priv = 0;
@@ -106,35 +111,45 @@ int bfin_EMAC_initialize(bd_t *bis)
        dev->halt = bfin_EMAC_halt;
        dev->send = bfin_EMAC_send;
        dev->recv = bfin_EMAC_recv;
+       dev->write_hwaddr = bfin_EMAC_setup_addr;
 
        eth_register(dev);
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-       miiphy_register(dev->name, bfin_miiphy_read, bfin_miiphy_write);
+       int retval;
+       struct mii_dev *mdiodev = mdio_alloc();
+       if (!mdiodev)
+               return -ENOMEM;
+       strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
+       mdiodev->read = bfin_miiphy_read;
+       mdiodev->write = bfin_miiphy_write;
+
+       retval = mdio_register(mdiodev);
+       if (retval < 0)
+               return retval;
+
+       dev->priv = mdiodev;
 #endif
 
        return 0;
 }
 
-static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
-                         int length)
+static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length)
 {
        int i;
        int result = 0;
-       unsigned int *buf;
-       buf = (unsigned int *)packet;
 
        if (length <= 0) {
                printf("Ethernet: bad packet size: %d\n", length);
                goto out;
        }
 
-       if ((*pDMA2_IRQ_STATUS & DMA_ERR) != 0) {
+       if (bfin_read_DMA2_IRQ_STATUS() & DMA_ERR) {
                printf("Ethernet: tx DMA error\n");
                goto out;
        }
 
-       for (i = 0; (*pDMA2_IRQ_STATUS & DMA_RUN) != 0; i++) {
+       for (i = 0; (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN); ++i) {
                if (i > TOUT_LOOP) {
                        puts("Ethernet: tx time out\n");
                        goto out;
@@ -143,9 +158,9 @@ static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
        txbuf[txIdx]->FrmData->NoBytes = length;
        memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
        txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
-       *pDMA2_NEXT_DESC_PTR = txbuf[txIdx]->Dma;
-       *pDMA2_CONFIG = txdmacfg.data;
-       *pEMAC_OPMODE |= TE;
+       bfin_write_DMA2_NEXT_DESC_PTR(txbuf[txIdx]->Dma);
+       bfin_write_DMA2_CONFIG(txdmacfg.data);
+       bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
 
        for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
                if (i > TOUT_LOOP) {
@@ -186,10 +201,12 @@ static int bfin_EMAC_recv(struct eth_device *dev)
                        printf("Ethernet: bad frame\n");
                        break;
                }
-               NetRxPackets[rxIdx] =
-                   (volatile uchar *)(rxbuf[rxIdx]->FrmData->Dest);
-               NetReceive(NetRxPackets[rxIdx], length - 4);
-               *pDMA1_IRQ_STATUS |= DMA_DONE | DMA_ERR;
+
+               debug("%s: len = %d\n", __func__, length - 4);
+
+               net_rx_packets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest;
+               net_process_received_packet(net_rx_packets[rxIdx], length - 4);
+               bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR);
                rxbuf[rxIdx]->StatusWord = 0x00000000;
                if ((rxIdx + 1) >= PKTBUFSRX)
                        rxIdx = 0;
@@ -209,63 +226,41 @@ static int bfin_EMAC_recv(struct eth_device *dev)
 /* MDC = SCLK / MDC_freq / 2 - 1 */
 #define MDC_FREQ_TO_DIV(mdc_freq) (get_sclk() / (mdc_freq) / 2 - 1)
 
+#ifndef CONFIG_BFIN_MAC_PINS
+# ifdef CONFIG_RMII
+#  define CONFIG_BFIN_MAC_PINS P_RMII0
+# else
+#  define CONFIG_BFIN_MAC_PINS P_MII0
+# endif
+#endif
+
 static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
 {
-       u16 phydat;
+       const unsigned short pins[] = CONFIG_BFIN_MAC_PINS;
+       int phydat;
        size_t count;
+       struct mii_dev *mdiodev = dev->priv;
 
        /* Enable PHY output */
-       *pVR_CTL |= CLKBUFOE;
+       bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);
 
        /* Set all the pins to peripheral mode */
-#ifdef CONFIG_RMII
-       /* grab RMII pins */
-# if defined(__ADSPBF51x__)
-       *pPORTF_MUX = (*pPORTF_MUX & \
-               ~(PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
-               PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
-       *pPORTF_FER |= PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
-       *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
-       *pPORTG_FER |= PG0 | PG1 | PG2;
-# elif defined(__ADSPBF52x__)
-       *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
-       *pPORTG_FER |= PG14 | PG15;
-       *pPORTH_MUX = (*pPORTH_MUX & ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK)) | \
-               PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
-       *pPORTH_FER |= PH0 | PH1 | PH2 | PH3 | PH4 | PH5 | PH6 | PH7 | PH8;
-# else
-       *pPORTH_FER |= PH0 | PH1 | PH4 | PH5 | PH6 | PH8 | PH9 | PH14 | PH15;
-# endif
-#else
-       /* grab MII & RMII pins */
-# if defined(__ADSPBF51x__)
-       *pPORTF_MUX = (*pPORTF_MUX & \
-               ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK | PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
-               PORT_x_MUX_0_FUNC_1 | PORT_x_MUX_1_FUNC_1 | PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
-       *pPORTF_FER |= PF0 | PF1 | PF2 | PF3 | PF4 | PF5 | PF6 | PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
-       *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
-       *pPORTG_FER |= PG0 | PG1 | PG2;
-# elif defined(__ADSPBF52x__)
-       *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
-       *pPORTG_FER |= PG14 | PG15;
-       *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
-       *pPORTH_FER = -1; /* all pins */
-# else
-       *pPORTH_FER = -1; /* all pins */
-# endif
-#endif
+       peripheral_request_list(pins, "bfin_mac");
 
        /* Odd word alignment for Receive Frame DMA word */
        /* Configure checksum support and rcve frame word alignment */
        bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ)));
 
        /* turn on auto-negotiation and wait for link to come up */
-       bfin_miiphy_write(dev->name, CONFIG_PHY_ADDR, MII_BMCR, BMCR_ANENABLE);
+       bfin_miiphy_write(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE, MII_BMCR,
+                         BMCR_ANENABLE);
        count = 0;
        while (1) {
                ++count;
-               if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_BMSR, &phydat))
-                       return -1;
+               phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR,
+                                         MDIO_DEVAD_NONE, MII_BMSR);
+               if (phydat < 0)
+                       return phydat;
                if (phydat & BMSR_LSTATUS)
                        break;
                if (count > 30000) {
@@ -276,30 +271,49 @@ static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
        }
 
        /* see what kind of link we have */
-       if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_LPA, &phydat))
-               return -1;
+       phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE,
+                                 MII_LPA);
+       if (phydat < 0)
+               return phydat;
        if (phydat & LPA_DUPLEX)
                *opmode = FDMODE;
        else
                *opmode = 0;
 
        bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
+       bfin_write_EMAC_VLAN1(EMAC_VLANX_DEF_VAL);
+       bfin_write_EMAC_VLAN2(EMAC_VLANX_DEF_VAL);
 
        /* Initialize the TX DMA channel registers */
-       *pDMA2_X_COUNT = 0;
-       *pDMA2_X_MODIFY = 4;
-       *pDMA2_Y_COUNT = 0;
-       *pDMA2_Y_MODIFY = 0;
+       bfin_write_DMA2_X_COUNT(0);
+       bfin_write_DMA2_X_MODIFY(4);
+       bfin_write_DMA2_Y_COUNT(0);
+       bfin_write_DMA2_Y_MODIFY(0);
 
        /* Initialize the RX DMA channel registers */
-       *pDMA1_X_COUNT = 0;
-       *pDMA1_X_MODIFY = 4;
-       *pDMA1_Y_COUNT = 0;
-       *pDMA1_Y_MODIFY = 0;
+       bfin_write_DMA1_X_COUNT(0);
+       bfin_write_DMA1_X_MODIFY(4);
+       bfin_write_DMA1_Y_COUNT(0);
+       bfin_write_DMA1_Y_MODIFY(0);
 
        return 0;
 }
 
+static int bfin_EMAC_setup_addr(struct eth_device *dev)
+{
+       bfin_write_EMAC_ADDRLO(
+               dev->enetaddr[0] |
+               dev->enetaddr[1] << 8 |
+               dev->enetaddr[2] << 16 |
+               dev->enetaddr[3] << 24
+       );
+       bfin_write_EMAC_ADDRHI(
+               dev->enetaddr[4] |
+               dev->enetaddr[5] << 8
+       );
+       return 0;
+}
+
 static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
 {
        u32 opmode;
@@ -315,7 +329,7 @@ static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
                return -1;
 
        /* Initialize EMAC address */
-       bfin_EMAC_setup_addr(dev->enetaddr);
+       bfin_EMAC_setup_addr(dev);
 
        /* Initialize TX and RX buffer */
        for (i = 0; i < PKTBUFSRX; i++) {
@@ -336,8 +350,8 @@ static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
        }
 
        /* Set RX DMA */
-       *pDMA1_NEXT_DESC_PTR = rxbuf[0]->Dma;
-       *pDMA1_CONFIG = rxbuf[0]->Dma[0].CONFIG_DATA;
+       bfin_write_DMA1_NEXT_DESC_PTR(rxbuf[0]->Dma);
+       bfin_write_DMA1_CONFIG(rxbuf[0]->Dma[0].CONFIG_DATA);
 
        /* Wait MII done */
        bfin_miiphy_wait();
@@ -358,7 +372,7 @@ static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
        opmode |= TE | RMII;
 #endif
        /* Turn on the EMAC */
-       *pEMAC_OPMODE = opmode;
+       bfin_write_EMAC_OPMODE(opmode);
        return 0;
 }
 
@@ -366,23 +380,10 @@ static void bfin_EMAC_halt(struct eth_device *dev)
 {
        debug("Eth_halt: ......\n");
        /* Turn off the EMAC */
-       *pEMAC_OPMODE = 0x00000000;
+       bfin_write_EMAC_OPMODE(0);
        /* Turn off the EMAC RX DMA */
-       *pDMA1_CONFIG = 0x0000;
-       *pDMA2_CONFIG = 0x0000;
-
-}
-
-void bfin_EMAC_setup_addr(uchar *enetaddr)
-{
-       *pEMAC_ADDRLO =
-               enetaddr[0] |
-               enetaddr[1] << 8 |
-               enetaddr[2] << 16 |
-               enetaddr[3] << 24;
-       *pEMAC_ADDRHI =
-               enetaddr[4] |
-               enetaddr[5] << 8;
+       bfin_write_DMA1_CONFIG(0);
+       bfin_write_DMA2_CONFIG(0);
 }
 
 ADI_ETHER_BUFFER *SetupRxBuffer(int no)
@@ -463,16 +464,19 @@ int ether_post_test(int flags)
        uchar buf[64];
        int i, value = 0;
        int length;
+       uint addr;
 
        printf("\n--------");
        bfin_EMAC_init(NULL, NULL);
        /* construct the package */
-       buf[0] = buf[6] = (unsigned char)(*pEMAC_ADDRLO & 0xFF);
-       buf[1] = buf[7] = (unsigned char)((*pEMAC_ADDRLO & 0xFF00) >> 8);
-       buf[2] = buf[8] = (unsigned char)((*pEMAC_ADDRLO & 0xFF0000) >> 16);
-       buf[3] = buf[9] = (unsigned char)((*pEMAC_ADDRLO & 0xFF000000) >> 24);
-       buf[4] = buf[10] = (unsigned char)(*pEMAC_ADDRHI & 0xFF);
-       buf[5] = buf[11] = (unsigned char)((*pEMAC_ADDRHI & 0xFF00) >> 8);
+       addr = bfin_read_EMAC_ADDRLO();
+       buf[0] = buf[6] = addr;
+       buf[1] = buf[7] = addr >> 8;
+       buf[2] = buf[8] = addr >> 16;
+       buf[3] = buf[9] = addr >> 24;
+       addr = bfin_read_EMAC_ADDRHI();
+       buf[4] = buf[10] = addr;
+       buf[5] = buf[11] = addr >> 8;
        buf[12] = 0x08;         /* Type: ARP */
        buf[13] = 0x06;
        buf[14] = 0x00;         /* Hardware type: Ethernet */
@@ -487,7 +491,7 @@ int ether_post_test(int flags)
        for (i = 0; i < 42; i++)
                buf[i + 22] = i;
        printf("--------Send 64 bytes......\n");
-       bfin_EMAC_send(NULL, (volatile void *)buf, 64);
+       bfin_EMAC_send(NULL, buf, 64);
        for (i = 0; i < 100; i++) {
                udelay(10000);
                if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {