]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/net/dm9000x.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / net / dm9000x.c
index f1394354eb39350c5690ebd58839489db19a53c6..b68d808c74287f010bd29d5a740de617082b60f9 100644 (file)
@@ -4,15 +4,7 @@
        A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
        Copyright (C) 1997  Sten Wang
 
-       This program is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License
-       as published by the Free Software Foundation; either version 2
-       of the License, or (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
+ * SPDX-License-Identifier:    GPL-2.0+
 
   (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
 
@@ -25,7 +17,7 @@ V0.11 06/20/2001      REG_0A bit3=1, default enable BP with DA match
                R17 = (R17 & 0xfff0) | NF
 
 v1.00                  modify by simon 2001.9.5
-                       change for kernel 2.4.x
+                       change for kernel 2.4.x
 
 v1.1   11/09/2001      fix force mode bug
 
@@ -75,7 +67,7 @@ TODO: external MII is not functional, only internal at the moment.
 #define DM9000_DMP_PACKET(func,packet,length)  \
        do { \
                int i;                                                  \
-               printf(func ": length: %d\n", length);                  \
+               printf("%s: length: %d\n", func, length);               \
                for (i = 0; i < length; i++) {                          \
                        if (i % 8 == 0)                                 \
                                printf("\n%s: %02x: ", func, i);        \
@@ -103,28 +95,34 @@ typedef struct board_info {
        void (*outblk)(volatile void *data_ptr, int count);
        void (*inblk)(void *data_ptr, int count);
        void (*rx_status)(u16 *RxStatus, u16 *RxLen);
+       struct eth_device netdev;
 } board_info_t;
 static board_info_t dm9000_info;
 
+
 /* function declaration ------------------------------------- */
-int eth_init(bd_t * bd);
-int eth_send(volatile void *, int);
-int eth_rx(void);
-void eth_halt(void);
 static int dm9000_probe(void);
-static u16 phy_read(int);
-static void phy_write(int, u16);
+static u16 dm9000_phy_read(int);
+static void dm9000_phy_write(int, u16);
 static u8 DM9000_ior(int);
 static void DM9000_iow(int reg, u8 value);
 
 /* DM9000 network board routine ---------------------------- */
-
-#define DM9000_outb(d,r) ( *(volatile u8 *)r = d )
-#define DM9000_outw(d,r) ( *(volatile u16 *)r = d )
-#define DM9000_outl(d,r) ( *(volatile u32 *)r = d )
-#define DM9000_inb(r) (*(volatile u8 *)r)
-#define DM9000_inw(r) (*(volatile u16 *)r)
-#define DM9000_inl(r) (*(volatile u32 *)r)
+#ifndef CONFIG_DM9000_BYTE_SWAPPED
+#define DM9000_outb(d,r) writeb(d, (volatile u8 *)(r))
+#define DM9000_outw(d,r) writew(d, (volatile u16 *)(r))
+#define DM9000_outl(d,r) writel(d, (volatile u32 *)(r))
+#define DM9000_inb(r) readb((volatile u8 *)(r))
+#define DM9000_inw(r) readw((volatile u16 *)(r))
+#define DM9000_inl(r) readl((volatile u32 *)(r))
+#else
+#define DM9000_outb(d, r) __raw_writeb(d, r)
+#define DM9000_outw(d, r) __raw_writew(d, r)
+#define DM9000_outl(d, r) __raw_writel(d, r)
+#define DM9000_inb(r) __raw_readb(r)
+#define DM9000_inw(r) __raw_readw(r)
+#define DM9000_inl(r) __raw_readl(r)
+#endif
 
 #ifdef CONFIG_DM9000_DEBUG
 static void
@@ -279,17 +277,15 @@ dm9000_reset(void)
                printf("ERROR: resetting DM9000 -> not responding\n");
 }
 
-/* Initilize dm9000 board
+/* Initialize dm9000 board
 */
-int
-eth_init(bd_t * bd)
+static int dm9000_init(struct eth_device *dev, bd_t *bd)
 {
        int i, oft, lnk;
        u8 io_mode;
        struct board_info *db = &dm9000_info;
-       uchar enetaddr[6];
 
-       DM9000_DBG("eth_init()\n");
+       DM9000_DBG("%s\n", __func__);
 
        /* RESET device */
        dm9000_reset();
@@ -345,20 +341,20 @@ eth_init(bd_t * bd)
        /* Clear interrupt status */
        DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
 
-       /* Set Node address */
-       if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
-#if !defined(CONFIG_DM9000_NO_SROM)
-               for (i = 0; i < 3; i++)
-                       dm9000_read_srom_word(i, enetaddr + 2 * i);
-               eth_setenv_enetaddr("ethaddr", enetaddr);
+       printf("MAC: %pM\n", dev->enetaddr);
+       if (!is_valid_ether_addr(dev->enetaddr)) {
+#ifdef CONFIG_RANDOM_MACADDR
+               printf("Bad MAC address (uninitialized EEPROM?), randomizing\n");
+               eth_random_enetaddr(dev->enetaddr);
+               printf("MAC: %pM\n", dev->enetaddr);
+#else
+               printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n");
 #endif
        }
 
-       printf("MAC: %pM\n", enetaddr);
-
        /* fill device MAC address registers */
        for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
-               DM9000_iow(oft, enetaddr[i]);
+               DM9000_iow(oft, dev->enetaddr[i]);
        for (i = 0, oft = 0x16; i < 8; i++, oft++)
                DM9000_iow(oft, 0xff);
 
@@ -374,7 +370,7 @@ eth_init(bd_t * bd)
        DM9000_iow(DM9000_IMR, IMR_PAR);
 
        i = 0;
-       while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
+       while (!(dm9000_phy_read(1) & 0x20)) {  /* autonegation complete bit */
                udelay(1000);
                i++;
                if (i == 10000) {
@@ -384,7 +380,7 @@ eth_init(bd_t * bd)
        }
 
        /* see what we've got */
-       lnk = phy_read(17) >> 12;
+       lnk = dm9000_phy_read(17) >> 12;
        printf("operating at ");
        switch (lnk) {
        case 1:
@@ -411,13 +407,12 @@ eth_init(bd_t * bd)
   Hardware start transmission.
   Send a packet to media from the upper layer.
 */
-int
-eth_send(volatile void *packet, int length)
+static int dm9000_send(struct eth_device *netdev, void *packet, int length)
 {
        int tmo;
        struct board_info *db = &dm9000_info;
 
-       DM9000_DMP_PACKET("eth_send", packet, length);
+       DM9000_DMP_PACKET(__func__ , packet, length);
 
        DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
 
@@ -453,13 +448,12 @@ eth_send(volatile void *packet, int length)
   Stop the interface.
   The interface is stopped when it is brought.
 */
-void
-eth_halt(void)
+static void dm9000_halt(struct eth_device *netdev)
 {
-       DM9000_DBG("eth_halt\n");
+       DM9000_DBG("%s\n", __func__);
 
        /* RESET devie */
-       phy_write(0, 0x8000);   /* PHY RESET */
+       dm9000_phy_write(0, 0x8000);    /* PHY RESET */
        DM9000_iow(DM9000_GPR, 0x01);   /* Power-Down PHY */
        DM9000_iow(DM9000_IMR, 0x80);   /* Disable all interrupt */
        DM9000_iow(DM9000_RCR, 0x00);   /* Disable RX */
@@ -468,8 +462,7 @@ eth_halt(void)
 /*
   Received a packet and pass to upper layer
 */
-int
-eth_rx(void)
+static int dm9000_rx(struct eth_device *netdev)
 {
        u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
        u16 RxStatus, RxLen = 0;
@@ -529,7 +522,7 @@ eth_rx(void)
                                dm9000_reset();
                        }
                } else {
-                       DM9000_DMP_PACKET("eth_rx", rdptr, RxLen);
+                       DM9000_DMP_PACKET(__func__ , rdptr, RxLen);
 
                        DM9000_DBG("passing packet to upper layer\n");
                        NetReceive(NetRxPackets[0], RxLen);
@@ -563,6 +556,15 @@ void dm9000_write_srom_word(int offset, u16 val)
 }
 #endif
 
+static void dm9000_get_enetaddr(struct eth_device *dev)
+{
+#if !defined(CONFIG_DM9000_NO_SROM)
+       int i;
+       for (i = 0; i < 3; i++)
+               dm9000_read_srom_word(i, dev->enetaddr + (2 * i));
+#endif
+}
+
 /*
    Read a byte from I/O port
 */
@@ -587,7 +589,7 @@ DM9000_iow(int reg, u8 value)
    Read a word from phyxcer
 */
 static u16
-phy_read(int reg)
+dm9000_phy_read(int reg)
 {
        u16 val;
 
@@ -599,7 +601,7 @@ phy_read(int reg)
        val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
 
        /* The read data keeps on REG_0D & REG_0E */
-       DM9000_DBG("phy_read(0x%x): 0x%x\n", reg, val);
+       DM9000_DBG("dm9000_phy_read(0x%x): 0x%x\n", reg, val);
        return val;
 }
 
@@ -607,7 +609,7 @@ phy_read(int reg)
    Write a word to phyxcer
 */
 static void
-phy_write(int reg, u16 value)
+dm9000_phy_write(int reg, u16 value)
 {
 
        /* Fill the phyxcer register into REG_0C */
@@ -619,5 +621,23 @@ phy_write(int reg, u16 value)
        DM9000_iow(DM9000_EPCR, 0xa);   /* Issue phyxcer write command */
        udelay(500);                    /* Wait write complete */
        DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer write command */
-       DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value);
+       DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value);
+}
+
+int dm9000_initialize(bd_t *bis)
+{
+       struct eth_device *dev = &(dm9000_info.netdev);
+
+       /* Load MAC address from EEPROM */
+       dm9000_get_enetaddr(dev);
+
+       dev->init = dm9000_init;
+       dev->halt = dm9000_halt;
+       dev->send = dm9000_send;
+       dev->recv = dm9000_rx;
+       sprintf(dev->name, "dm9000");
+
+       eth_register(dev);
+
+       return 0;
 }