#include <net.h>
#include <pci.h>
-#undef DEBUG
#undef DEBUG_SROM
#undef DEBUG_SROM2
#define SROM_HWADD 0x0014 /* Hardware Address offset in SROM */
#define SROM_RD 0x00004000 /* Read from Boot ROM */
-#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
-#define EE_WRITE_0 0x4801
-#define EE_WRITE_1 0x4805
-#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
+#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
+#define EE_WRITE_0 0x4801
+#define EE_WRITE_1 0x4805
+#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
#define SROM_SR 0x00000800 /* Select Serial ROM when set */
#define DT_IN 0x00000004 /* Serial Data In */
#define POLL_DEMAND 1
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+#define RESET_DM9102(dev) {\
+ unsigned long i;\
+ i=INL(dev, 0x0);\
+ udelay(1000);\
+ OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+ udelay(1000);\
+}
+#else
#define RESET_DE4X5(dev) {\
int i;\
i=INL(dev, DE4X5_BMR);\
for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
udelay(1000);\
}
+#endif
#define START_DE4X5(dev) {\
s32 omr; \
}
#define NUM_RX_DESC PKTBUFSRX
-#define NUM_TX_DESC 1 /* Number of TX descriptors */
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+ #define NUM_TX_DESC 1 /* Number of TX descriptors */
+#else
+ #define NUM_TX_DESC 4
+#endif
#define RX_BUFF_SZ PKTSIZE_ALIGN
#define TOUT_LOOP 1000000
#define SETUP_FRAME_LEN 192
#define ETH_ALEN 6
-
struct de4x5_desc {
volatile s32 status;
u32 des1;
u32 next;
};
-static struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring */
-static struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring */
+static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring */
+static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */
static int rx_new; /* RX descriptor ring pointer */
static int tx_new; /* TX descriptor ring pointer */
static char rxRingSize;
static char txRingSize;
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
static void sendto_srom(struct eth_device* dev, u_int command, u_long addr);
static int getfrom_srom(struct eth_device* dev, u_long addr);
-static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len);
-static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len);
-static int read_srom(struct eth_device *dev, u_long ioaddr, int index);
+static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len);
+static int do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len);
+#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
#ifdef UPDATE_SROM
static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value);
static void update_srom(struct eth_device *dev, bd_t *bis);
#endif
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+static int read_srom(struct eth_device *dev, u_long ioaddr, int index);
static void read_hw_addr(struct eth_device* dev, bd_t * bis);
+#endif /* CONFIG_TULIP_FIX_DAVICOM */
static void send_setup_frame(struct eth_device* dev, bd_t * bis);
static int dc21x4x_init(struct eth_device* dev, bd_t* bis);
static struct pci_device_id supported[] = {
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+ { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A },
+#endif
{ }
};
{
int idx=0;
int card_number = 0;
- int cfrv;
+ unsigned int cfrv;
unsigned char timer;
pci_dev_t devbusfn;
unsigned int iobase;
/* Get the chip configuration revision register. */
pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
+#ifndef CONFIG_TULIP_FIX_DAVICOM
if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
printf("Error: The chip is not DC21143.\n");
continue;
}
+#endif
pci_read_config_word(devbusfn, PCI_COMMAND, &status);
status |=
pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase);
iobase &= PCI_BASE_ADDRESS_MEM_MASK;
#endif
-
-#ifdef DEBUG
- printf("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
-#endif
+ debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
dev = (struct eth_device*) malloc(sizeof *dev);
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+ sprintf(dev->name, "Davicom#%d", card_number);
+#else
sprintf(dev->name, "dc21x4x#%d", card_number);
+#endif
+
#ifdef CONFIG_TULIP_USE_IO
dev->iobase = pci_io_to_phys(devbusfn, iobase);
#else
udelay(10 * 1000);
+#ifndef CONFIG_TULIP_FIX_DAVICOM
read_hw_addr(dev, bis);
-
+#endif
eth_register(dev);
card_number++;
/* Ensure we're not sleeping. */
pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+ RESET_DM9102(dev);
+#else
RESET_DE4X5(dev);
+#endif
if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
printf("Error: Cannot reset ethernet controller.\n");
rx_ring[i].status = cpu_to_le32(R_OWN);
rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+ rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC]));
+#else
rx_ring[i].next = 0;
+#endif
}
for (i=0; i < NUM_TX_DESC; i++) {
tx_ring[i].status = 0;
tx_ring[i].des1 = 0;
tx_ring[i].buf = 0;
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+ tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC]));
+#else
tx_ring[i].next = 0;
+#endif
}
rxRingSize = NUM_RX_DESC;
if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
#if 0 /* test-only */
printf("TX error status = 0x%08X\n",
- le32_to_cpu(tx_ring[tx_new].status));
+ le32_to_cpu(tx_ring[tx_new].status));
#endif
+ tx_ring[tx_new].status = 0x0;
goto Done;
}
status = length;
Done:
+ tx_new = (tx_new+1) % NUM_TX_DESC;
return status;
}
if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
}
+ tx_new = (tx_new+1) % NUM_TX_DESC;
+
Done:
return;
}
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
/* SROM Read and write routines.
*/
-
static void
sendto_srom(struct eth_device* dev, u_int command, u_long addr)
{
return retval;
}
+#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
-/* This executes a generic EEPROM command, typically a write or write enable.
- It returns the data output from the EEPROM, and thus may also be used for
- reads. */
+/* This executes a generic EEPROM command, typically a write or write
+ * enable. It returns the data output from the EEPROM, and thus may
+ * also be used for reads.
+ */
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len)
{
unsigned retval = 0;
return retval;
}
+#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
+#ifndef CONFIG_TULIP_FIX_DAVICOM
static int read_srom(struct eth_device *dev, u_long ioaddr, int index)
{
int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
(((SROM_READ_CMD << ee_addr_size) | index) << 16)
| 0xffff, 3 + ee_addr_size + 16);
}
+#endif /* CONFIG_TULIP_FIX_DAVICOM */
#ifdef UPDATE_SROM
static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value)
}
#endif
+#ifndef CONFIG_TULIP_FIX_DAVICOM
static void read_hw_addr(struct eth_device *dev, bd_t *bis)
{
- u_short tmp, *p = (short *)(&dev->enetaddr[0]);
+ u_short tmp, *p = (u_short *)(&dev->enetaddr[0]);
int i, j = 0;
for (i = 0; i < (ETH_ALEN >> 1); i++) {
if ((j == 0) || (j == 0x2fffd)) {
memset (dev->enetaddr, 0, ETH_ALEN);
-#ifdef DEBUG
- printf("Warning: can't read HW address from SROM.\n");
-#endif
+ debug ("Warning: can't read HW address from SROM.\n");
goto Done;
}
#endif
return;
}
+#endif /* CONFIG_TULIP_FIX_DAVICOM */
#ifdef UPDATE_SROM
static void update_srom(struct eth_device *dev, bd_t *bis)
write_srom(dev, DE4X5_APROM, i, eeprom[i]);
}
}
-#endif
+#endif /* UPDATE_SROM */
-#endif
+#endif /* CFG_CMD_NET && CONFIG_NET_MULTI && CONFIG_TULIP */