pasemi_mac: Stop using the pci config space accessors for register read/writes

Move away from using the pci config access functions for simple register
access.  Our device has all of the registers in the config space (hey,
from the hardware point of view it looks reasonable :-), so we need to
somehow get to it. Newer firmwares have it in the device tree such that
we can just get it and ioremap it there (in case it ever moves in future
products). For now, provide a hardcoded fallback for older firmwares.

[ Resolved napi_struct conflicts... -DaveM ]

Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Olof Johansson 2007-09-15 13:44:07 -07:00 committed by David S. Miller
parent a85b94222d
commit b6e05a1b67
2 changed files with 94 additions and 41 deletions

View file

@ -83,44 +83,35 @@ static struct pasdma_status *dma_status;
static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg) static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
{ {
unsigned int val; return in_le32(mac->iob_regs+reg);
pci_read_config_dword(mac->iob_pdev, reg, &val);
return val;
} }
static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val) unsigned int val)
{ {
pci_write_config_dword(mac->iob_pdev, reg, val); out_le32(mac->iob_regs+reg, val);
} }
static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
{ {
unsigned int val; return in_le32(mac->regs+reg);
pci_read_config_dword(mac->pdev, reg, &val);
return val;
} }
static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val) unsigned int val)
{ {
pci_write_config_dword(mac->pdev, reg, val); out_le32(mac->regs+reg, val);
} }
static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
{ {
unsigned int val; return in_le32(mac->dma_regs+reg);
pci_read_config_dword(mac->dma_pdev, reg, &val);
return val;
} }
static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val) unsigned int val)
{ {
pci_write_config_dword(mac->dma_pdev, reg, val); out_le32(mac->dma_regs+reg, val);
} }
static int pasemi_get_mac_addr(struct pasemi_mac *mac) static int pasemi_get_mac_addr(struct pasemi_mac *mac)
@ -585,7 +576,6 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
} }
mac->tx->next_to_clean += count; mac->tx->next_to_clean += count;
spin_unlock_irqrestore(&mac->tx->lock, flags); spin_unlock_irqrestore(&mac->tx->lock, flags);
netif_wake_queue(mac->netdev); netif_wake_queue(mac->netdev);
return count; return count;
@ -1071,6 +1061,73 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
return pkts; return pkts;
} }
static void __iomem * __devinit map_onedev(struct pci_dev *p, int index)
{
struct device_node *dn;
void __iomem *ret;
dn = pci_device_to_OF_node(p);
if (!dn)
goto fallback;
ret = of_iomap(dn, index);
if (!ret)
goto fallback;
return ret;
fallback:
/* This is hardcoded and ugly, but we have some firmware versions
* that don't provide the register space in the device tree. Luckily
* they are at well-known locations so we can just do the math here.
*/
return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
}
static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac)
{
struct resource res;
struct device_node *dn;
int err;
mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
if (!mac->dma_pdev) {
dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
return -ENODEV;
}
mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
if (!mac->iob_pdev) {
dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
return -ENODEV;
}
mac->regs = map_onedev(mac->pdev, 0);
mac->dma_regs = map_onedev(mac->dma_pdev, 0);
mac->iob_regs = map_onedev(mac->iob_pdev, 0);
if (!mac->regs || !mac->dma_regs || !mac->iob_regs) {
dev_err(&mac->pdev->dev, "Can't map registers\n");
return -ENODEV;
}
/* The dma status structure is located in the I/O bridge, and
* is cache coherent.
*/
if (!dma_status) {
dn = pci_device_to_OF_node(mac->iob_pdev);
if (dn)
err = of_address_to_resource(dn, 1, &res);
if (!dn || err) {
/* Fallback for old firmware */
res.start = 0xfd800000;
res.end = res.start + 0x1000;
}
dma_status = __ioremap(res.start, res.end-res.start, 0);
}
return 0;
}
static int __devinit static int __devinit
pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
@ -1099,26 +1156,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mac->pdev = pdev; mac->pdev = pdev;
mac->netdev = dev; mac->netdev = dev;
mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64); netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
dev->features = NETIF_F_HW_CSUM; dev->features = NETIF_F_HW_CSUM;
if (!mac->dma_pdev) {
dev_err(&pdev->dev, "Can't find DMA Controller\n");
err = -ENODEV;
goto out_free_netdev;
}
mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
if (!mac->iob_pdev) {
dev_err(&pdev->dev, "Can't find I/O Bridge\n");
err = -ENODEV;
goto out_put_dma_pdev;
}
/* These should come out of the device tree eventually */ /* These should come out of the device tree eventually */
mac->dma_txch = index; mac->dma_txch = index;
mac->dma_rxch = index; mac->dma_rxch = index;
@ -1157,12 +1199,9 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->get_stats = pasemi_mac_get_stats; dev->get_stats = pasemi_mac_get_stats;
dev->set_multicast_list = pasemi_mac_set_rx_mode; dev->set_multicast_list = pasemi_mac_set_rx_mode;
/* The dma status structure is located in the I/O bridge, and err = pasemi_mac_map_regs(mac);
* is cache coherent. if (err)
*/ goto out;
if (!dma_status)
/* XXXOJN This should come from the device tree */
dma_status = __ioremap(0xfd800000, 0x1000, 0);
mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
@ -1189,10 +1228,17 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return err; return err;
out: out:
pci_dev_put(mac->iob_pdev); if (mac->iob_pdev)
out_put_dma_pdev: pci_dev_put(mac->iob_pdev);
pci_dev_put(mac->dma_pdev); if (mac->dma_pdev)
out_free_netdev: pci_dev_put(mac->dma_pdev);
if (mac->dma_regs)
iounmap(mac->dma_regs);
if (mac->iob_regs)
iounmap(mac->iob_regs);
if (mac->regs)
iounmap(mac->regs);
free_netdev(dev); free_netdev(dev);
out_disable_device: out_disable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
@ -1216,6 +1262,10 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev)
pci_dev_put(mac->dma_pdev); pci_dev_put(mac->dma_pdev);
pci_dev_put(mac->iob_pdev); pci_dev_put(mac->iob_pdev);
iounmap(mac->regs);
iounmap(mac->dma_regs);
iounmap(mac->iob_regs);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
free_netdev(netdev); free_netdev(netdev);
} }

View file

@ -52,6 +52,9 @@ struct pasemi_mac_rxring {
struct pasemi_mac { struct pasemi_mac {
struct net_device *netdev; struct net_device *netdev;
void __iomem *regs;
void __iomem *dma_regs;
void __iomem *iob_regs;
struct pci_dev *pdev; struct pci_dev *pdev;
struct pci_dev *dma_pdev; struct pci_dev *dma_pdev;
struct pci_dev *iob_pdev; struct pci_dev *iob_pdev;