X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Fdm9000x.c;h=a6c0a2452f2c8bcb76019f2eaff401f6f760131e;hb=8b71e46ceab8b66208107de688cbb4dd25fe38cd;hp=3a61b802e66c47eab510f9e881068312bc0c9cb1;hpb=ae9e1b579ea2ce23e531fd59a52423fd18effe77;p=u-boot diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 3a61b802e6..a6c0a2452f 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* dm9000.c: Version 1.2 12/15/2003 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. - (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match @@ -25,7 +16,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 @@ -53,7 +44,7 @@ v1.2 03/18/2003 Weilun Huang : notes (i.e. double reset) - some minor code cleanups These changes are tested with DM9000{A,EP,E} together - with a 200MHz Atmel AT91SAM92161 core + with a 200MHz Atmel AT91SAM9261 core TODO: external MII is not functional, only internal at the moment. */ @@ -62,6 +53,7 @@ TODO: external MII is not functional, only internal at the moment. #include #include #include +#include #include "dm9000x.h" @@ -74,7 +66,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); \ @@ -102,29 +94,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); -u16 read_srom_word(int); +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,16 +276,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; - DM9000_DBG("eth_init()\n"); + DM9000_DBG("%s\n", __func__); /* RESET device */ dm9000_reset(); @@ -344,33 +340,14 @@ eth_init(bd_t * bd) /* Clear interrupt status */ DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); - /* Set Node address */ -#if !defined(CONFIG_AT91SAM9261EK) - for (i = 0; i < 6; i++) - ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i); -#endif - - if (is_zero_ether_addr(bd->bi_enetaddr) || - is_multicast_ether_addr(bd->bi_enetaddr)) { - /* try reading from environment */ - u8 i; - char *s, *e; - s = getenv ("ethaddr"); - for (i = 0; i < 6; ++i) { - bd->bi_enetaddr[i] = s ? - simple_strtoul (s, &e, 16) : 0; - if (s) - s = (*e) ? e + 1 : e; - } + printf("MAC: %pM\n", dev->enetaddr); + if (!is_valid_ethaddr(dev->enetaddr)) { + printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n"); } - printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0], - bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3], - bd->bi_enetaddr[4], bd->bi_enetaddr[5]); - /* fill device MAC address registers */ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) - DM9000_iow(oft, bd->bi_enetaddr[i]); + DM9000_iow(oft, dev->enetaddr[i]); for (i = 0, oft = 0x16; i < 8; i++, oft++) DM9000_iow(oft, 0xff); @@ -386,7 +363,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) { @@ -396,7 +373,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: @@ -423,13 +400,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 */ @@ -447,7 +423,7 @@ eth_send(volatile void *packet, int length) DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ /* wait for end of transmission */ - tmo = get_timer(0) + 5 * CFG_HZ; + tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) { if (get_timer(0) >= tmo) { @@ -465,13 +441,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 */ @@ -480,10 +455,10 @@ 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]; + u8 rxbyte; + u8 *rdptr = (u8 *)net_rx_packets[0]; u16 RxStatus, RxLen = 0; struct board_info *db = &dm9000_info; @@ -541,10 +516,10 @@ 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); + net_process_received_packet(net_rx_packets[0], RxLen); } } return 0; @@ -553,18 +528,18 @@ eth_rx(void) /* Read a word data from SROM */ -u16 -read_srom_word(int offset) +#if !defined(CONFIG_DM9000_NO_SROM) +void dm9000_read_srom_word(int offset, u8 *to) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPCR, 0x4); udelay(8000); DM9000_iow(DM9000_EPCR, 0x0); - return (DM9000_ior(DM9000_EPDRL) + (DM9000_ior(DM9000_EPDRH) << 8)); + to[0] = DM9000_ior(DM9000_EPDRL); + to[1] = DM9000_ior(DM9000_EPDRH); } -void -write_srom_word(int offset, u16 val) +void dm9000_write_srom_word(int offset, u16 val) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); @@ -573,7 +548,16 @@ write_srom_word(int offset, u16 val) udelay(8000); DM9000_iow(DM9000_EPCR, 0); } +#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 @@ -599,7 +583,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; @@ -611,7 +595,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; } @@ -619,7 +603,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 */ @@ -631,5 +615,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; + strcpy(dev->name, "dm9000"); + + eth_register(dev); + + return 0; }