#include "etherboot.h"
#include "nic.h"
-#include "pci.h"
+#include <gpxe/pci.h>
+#include <gpxe/ethernet.h>
#include "timer.h"
+static struct nic_operations a3c90x_operations;
+
#define XCVR_MAGIC (0x5A00)
/** any single transmission fails after 16 collisions or other errors
** this is the number of times to retry the transmission -- this should
/*** Global variables ***/
static struct
{
+ unsigned int is3c556;
unsigned char isBrev;
unsigned char CurrentWindow;
unsigned int IOAddr;
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
/** Read the value. **/
- outw(address + ((0x02)<<6), ioaddr + regEepromCommand_0_w);
+ if (INF_3C90X.is3c556)
+ {
+ outw(address + (0x230), ioaddr + regEepromCommand_0_w);
+ }
+ else
+ {
+ outw(address + ((0x02)<<6), ioaddr + regEepromCommand_0_w);
+ }
+
while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
val = inw(ioaddr + regEepromData_0_w);
*** [Ken]
***/
static void
-a3c90x_disable(struct dev *dev __unused)
-{
- /* reset and disable merge */
+a3c90x_disable ( struct nic *nic __unused ) {
a3c90x_reset();
/* Disable the receiver and transmitter. */
outw(cmdRxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
*** initialization. If this routine is called, the pci functions did find the
*** card. We just have to init it here.
***/
-static int a3c90x_probe(struct dev *dev, struct pci_device *pci)
-{
- struct nic *nic = (struct nic *)dev;
+static int a3c90x_probe ( struct nic *nic, struct pci_device *pci ) {
+
int i, c;
unsigned short eeprom[0x21];
unsigned int cfg;
unsigned int mstat;
unsigned short linktype;
#define HWADDR_OFFSET 10
-
+
if (pci->ioaddr == 0)
return 0;
adjust_pci_device(pci);
- nic->ioaddr = pci->ioaddr & ~3;
+ pci_fill_nic ( nic, pci );
+
+ nic->ioaddr = pci->ioaddr;
nic->irqno = 0;
+ INF_3C90X.is3c556 = (pci->device == 0x6055);
INF_3C90X.IOAddr = pci->ioaddr & ~3;
INF_3C90X.CurrentWindow = 255;
switch (a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, 0x03))
INF_3C90X.HWAddr[3] = eeprom[HWADDR_OFFSET + 1]&0xFF;
INF_3C90X.HWAddr[4] = eeprom[HWADDR_OFFSET + 2]>>8;
INF_3C90X.HWAddr[5] = eeprom[HWADDR_OFFSET + 2]&0xFF;
- printf("MAC Address = %!\n", INF_3C90X.HWAddr);
+
+ DBG ( "MAC Address = %s\n", eth_ntoa ( INF_3C90X.HWAddr ) );
+
+ /** 3C556: Invert MII power **/
+ if (INF_3C90X.is3c556) {
+ unsigned int tmp;
+ a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
+ tmp = inw(INF_3C90X.IOAddr + regResetOptions_2_w);
+ tmp |= 0x4000;
+ outw(tmp, INF_3C90X.IOAddr + regResetOptions_2_w);
+ }
/* Test if the link is good, if not continue */
a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winDiagnostics4);
cmdAcknowledgeInterrupt, 0x661);
/** Set our exported functions **/
- dev->disable = a3c90x_disable;
- nic->poll = a3c90x_poll;
- nic->transmit = a3c90x_transmit;
- nic->irq = a3c90x_irq;
-
+ nic->nic_op = &a3c90x_operations;
return 1;
}
+static struct nic_operations a3c90x_operations = {
+ .connect = dummy_connect,
+ .poll = a3c90x_poll,
+ .transmit = a3c90x_transmit,
+ .irq = a3c90x_irq,
-static struct pci_id a3c90x_nics[] = {
+};
+
+static struct pci_device_id a3c90x_nics[] = {
/* Original 90x revisions: */
+PCI_ROM(0x10b7, 0x6055, "3c556", "3C556"), /* Huricane */
PCI_ROM(0x10b7, 0x9000, "3c905-tpo", "3Com900-TPO"), /* 10 Base TPO */
PCI_ROM(0x10b7, 0x9001, "3c905-t4", "3Com900-Combo"), /* 10/100 T4 */
PCI_ROM(0x10b7, 0x9050, "3c905-tpo100", "3Com905-TX"), /* 100 Base TX / 10/100 TPO */
PCI_ROM(0x10b7, 0x1202, "3c982b", "3Com982B"),
};
-static struct pci_driver a3c90x_driver __pci_driver = {
- .type = NIC_DRIVER,
- .name = "3C90X",
- .probe = a3c90x_probe,
- .ids = a3c90x_nics,
- .id_count = sizeof(a3c90x_nics)/sizeof(a3c90x_nics[0]),
- .class = 0,
-};
+PCI_DRIVER ( a3c90x_driver, a3c90x_nics, PCI_NO_CLASS );
+
+DRIVER ( "3C90X", nic_driver, pci_driver, a3c90x_driver,
+ a3c90x_probe, a3c90x_disable );