Soft reset (S_RESET) resets value of CSR0 to default. The default value for CSR0 is 0x0004 (STOP bit is set) [2 p.23]. At first, assume we in word i/o mode and try to read 0x14. After this try to read 0x18 if CSR0 hasn't been set to default value. After S_RESET the controller will be in word i/o mode [1 p.101]. We need to perform 32bit write access to the i/o location at 0x10 to switch the controller to dword i/o mode [1 p.104]. Zero is safe value for this operation [1 p.104]. DWIO bit of BCR18 indicates that the controller is working in dword mode, if it isn't set something wrong occurred. [1] Am79C970A [2] PCnet Family Software Design Considerations --- src/pcnet.c | 19 ++++++++++++++++++- 1 files changed, 18 insertions(+), 1 deletions(-) diff --git a/src/pcnet.c b/src/pcnet.c index 480a67f..2372ec3 100644 --- a/src/pcnet.c +++ b/src/pcnet.c @@ -182,6 +182,21 @@ static unsigned long pcnet_dummy_bcr_read32(void __iomem *ioaddr, return ioread32(ioaddr + PCNET_IO32_BDP) & 0xffff; } +/* resets the controller and switches to 32bit mode */ +static int pcnet_dummy_reset(void __iomem *ioaddr) +{ + int err = 0; + ioread16(ioaddr + PCNET_IO_RESET); + if (pcnet_dummy_csr_read16(ioaddr, CSR0) != CSR0_STOP) + ioread32(ioaddr + PCNET_IO32_RESET); + iowrite32(0, ioaddr + PCNET_IO_RDP); + if (!(pcnet_dummy_bcr_read32(ioaddr, BCR18) & BCR18_DWIO)) { + printk(KERN_ERR DRV_NAME ": cannot switch controller to 32bit mode\n"); + err = -ENODEV; + } + return err; +} + static int pcnet_dummy_open(struct net_device *ndev) { return 0; @@ -236,7 +251,6 @@ static int __devinit pcnet_dummy_init_netdev(struct pci_dev *pdev, #endif /* HAVE_NET_DEVICE_OPS */ /* registers net_device and returns err */ - /* TODO: reset the chip at the end */ return 0; } @@ -272,6 +286,9 @@ static int __devinit pcnet_dummy_init_one(struct pci_dev *pdev, goto out_res; pci_set_drvdata(pdev, ndev); + if (pcnet_dummy_reset(ioaddr)) + goto out_res_unmap; + if (pcnet_dummy_init_netdev(pdev, (unsigned long)ioaddr)) goto out_res_unmap; -- 1.7.5.rc3