Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 6590
b: refs/heads/master
c: 830fb7d
h: refs/heads/master
v: v3
  • Loading branch information
Francois Romieu authored and Jeff Garzik committed Jul 30, 2005
1 parent d7002b7 commit e7dae2a
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 40292fb0f041362bca2f6ad975acedce4f6e3f3e
refs/heads/master: 830fb7d23217ae748df0b16d4d419110810036b7
154 changes: 138 additions & 16 deletions trunk/drivers/net/sis190.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ enum sis190_eeprom_access_register_bits {
EEWOP = 0x00000100 // unused
};

/* EEPROM Addresses */
enum sis190_eeprom_address {
EEPROMSignature = 0x00,
EEPROMCLK = 0x01, // unused
EEPROMInfo = 0x02,
EEPROMMACAddr = 0x03
};

struct sis190_private {
void __iomem *mmio_addr;
struct pci_dev *pci_dev;
Expand Down Expand Up @@ -1240,6 +1248,125 @@ static void sis190_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}

static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
struct net_device *dev)
{
struct sis190_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
u16 sig;
int i;

net_probe(tp, KERN_INFO "%s: Read MAC address from EEPROM\n",
pci_name(pdev));

/* Check to see if there is a sane EEPROM */
sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);

if ((sig == 0xffff) || (sig == 0x0000)) {
net_probe(tp, KERN_INFO "%s: Error EEPROM read %x.\n",
pci_name(pdev), sig);
return -EIO;
}

/* Get MAC address from EEPROM */
for (i = 0; i < MAC_ADDR_LEN / 2; i++) {
u16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);

((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
}

return 0;
}

/**
* sis190_get_mac_addr_from_apc - Get MAC address for SiS965 model
* @pdev: PCI device
* @dev: network device to get address for
*
* SiS965 model, use APC CMOS RAM to store MAC address.
* APC CMOS RAM is accessed through ISA bridge.
* MAC address is read into @net_dev->dev_addr.
*/
static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
struct net_device *dev)
{
struct sis190_private *tp = netdev_priv(dev);
struct pci_dev *isa_bridge;
u8 reg, tmp8;
int i;

net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n",
pci_name(pdev));

isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
if (!isa_bridge) {
net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
pci_name(pdev));
return -EIO;
}

/* Enable port 78h & 79h to access APC Registers. */
pci_read_config_byte(isa_bridge, 0x48, &tmp8);
reg = (tmp8 & ~0x02);
pci_write_config_byte(isa_bridge, 0x48, reg);
udelay(50);
pci_read_config_byte(isa_bridge, 0x48, &reg);

for (i = 0; i < MAC_ADDR_LEN; i++) {
outb(0x9 + i, 0x78);
dev->dev_addr[i] = inb(0x79);
}

outb(0x12, 0x78);
reg = inb(0x79);

/* Restore the value to ISA Bridge */
pci_write_config_byte(isa_bridge, 0x48, tmp8);
pci_dev_put(isa_bridge);

return 0;
}

/**
* sis190_init_rxfilter - Initialize the Rx filter
* @dev: network device to initialize
*
* Set receive filter address to our MAC address
* and enable packet filtering.
*/
static inline void sis190_init_rxfilter(struct net_device *dev)
{
struct sis190_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
u16 ctl;
int i;

ctl = SIS_R16(RxMacControl);
/*
* Disable packet filtering before setting filter.
* Note: SiS's driver writes 32 bits but RxMacControl is 16 bits
* only and followed by RxMacAddr (6 bytes). Strange. -- FR
*/
SIS_W16(RxMacControl, ctl & ~0x0f00);

for (i = 0; i < MAC_ADDR_LEN; i++)
SIS_W8(RxMacAddr + i, dev->dev_addr[i]);

SIS_W16(RxMacControl, ctl);
SIS_PCI_COMMIT();
}

static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
{
u8 from;

pci_read_config_byte(pdev, 0x73, &from);

return (from & 0x00000001) ?
sis190_get_mac_addr_from_apc(pdev, dev) :
sis190_get_mac_addr_from_eeprom(pdev, dev);
}

static void sis190_set_speed_auto(struct net_device *dev)
{
struct sis190_private *tp = netdev_priv(dev);
Expand Down Expand Up @@ -1355,7 +1482,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
struct sis190_private *tp;
struct net_device *dev;
void __iomem *ioaddr;
int i, rc;
int rc;

if (!printed_version) {
net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n");
Expand All @@ -1371,18 +1498,11 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
tp = netdev_priv(dev);
ioaddr = tp->mmio_addr;

/* Get MAC address */
/* Read node address from the EEPROM */

if (SIS_R32(ROMControl) & 0x4) {
for (i = 0; i < 3; i++) {
SIS_W16(RxMacAddr + 2*i,
sis190_read_eeprom(ioaddr, 3 + i));
}
}
rc = sis190_get_mac_addr(pdev, dev);
if (rc < 0)
goto err_release_board;

for (i = 0; i < MAC_ADDR_LEN; i++)
dev->dev_addr[i] = SIS_R8(RxMacAddr + i);
sis190_init_rxfilter(dev);

INIT_WORK(&tp->phy_task, sis190_phy_task, dev);

Expand All @@ -1403,10 +1523,8 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,

spin_lock_init(&tp->lock);
rc = register_netdev(dev);
if (rc < 0) {
sis190_release_board(pdev);
goto out;
}
if (rc < 0)
goto err_release_board;

pci_set_drvdata(pdev, dev);

Expand All @@ -1423,6 +1541,10 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
sis190_set_speed_auto(dev);
out:
return rc;

err_release_board:
sis190_release_board(pdev);
goto out;
}

static void __devexit sis190_remove_one(struct pci_dev *pdev)
Expand Down

0 comments on commit e7dae2a

Please sign in to comment.