mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6: (180 commits) leo: disable cursor when leaving graphics mode cg6: disable cursor when leaving graphics mode sparc32: sun4m interrupt mask cleanup drivers/rtc/Kconfig: don't build rtc-cmos.o on sparc32 sparc: arch/sparc/kernel/pmc.c -- extra #include? sparc32: Add more extensive documentation of sun4m interrupts. sparc32: Kill irq_rcvreg from sun4m_irq.c sparc32: Delete master_l10_limit. sparc32: Use PROM device probing for sun4c timers. sparc32: Use PROM device probing for sun4c interrupt register. sparc32: Delete claim_ticker14(). sparc32: Stop calling claim_ticker14() from sun4c_irq.c sparc32: Kill clear_profile_irq btfixup entry. sparc32: Call sun4m_clear_profile_irq() directly from sun4m_smp.c sparc32: Remove #if 0'd code from sun4c_irq.c sparc32: Remove some SMP ifdefs in sun4d_irq.c sparc32: Use PROM infrastructure for probing and mapping sun4d timers. sparc32: Use PROM device probing for sun4m irq registers. sparc32: Use PROM device probing for sun4m timer registers. sparc: Fix user_regset 'n' field values. ...
This commit is contained in:
commit
0710483959
233 changed files with 8453 additions and 15194 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* myri_sbus.c: MyriCOM MyriNET SBUS card driver.
|
||||
*
|
||||
* Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1996, 1999, 2006, 2008 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
static char version[] =
|
||||
|
|
@ -22,6 +22,9 @@ static char version[] =
|
|||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <net/dst.h>
|
||||
#include <net/arp.h>
|
||||
|
|
@ -33,7 +36,6 @@ static char version[] =
|
|||
#include <asm/dma.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/openprom.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/auxio.h>
|
||||
|
|
@ -243,7 +245,8 @@ static void myri_clean_rings(struct myri_eth *mp)
|
|||
u32 dma_addr;
|
||||
|
||||
dma_addr = sbus_readl(&rxd->myri_scatters[0].addr);
|
||||
sbus_unmap_single(mp->myri_sdev, dma_addr, RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE);
|
||||
dma_unmap_single(&mp->myri_op->dev, dma_addr,
|
||||
RX_ALLOC_SIZE, DMA_FROM_DEVICE);
|
||||
dev_kfree_skb(mp->rx_skbs[i]);
|
||||
mp->rx_skbs[i] = NULL;
|
||||
}
|
||||
|
|
@ -259,7 +262,9 @@ static void myri_clean_rings(struct myri_eth *mp)
|
|||
u32 dma_addr;
|
||||
|
||||
dma_addr = sbus_readl(&txd->myri_gathers[0].addr);
|
||||
sbus_unmap_single(mp->myri_sdev, dma_addr, (skb->len + 3) & ~3, SBUS_DMA_TODEVICE);
|
||||
dma_unmap_single(&mp->myri_op->dev, dma_addr,
|
||||
(skb->len + 3) & ~3,
|
||||
DMA_TO_DEVICE);
|
||||
dev_kfree_skb(mp->tx_skbs[i]);
|
||||
mp->tx_skbs[i] = NULL;
|
||||
}
|
||||
|
|
@ -288,7 +293,9 @@ static void myri_init_rings(struct myri_eth *mp, int from_irq)
|
|||
skb->dev = dev;
|
||||
skb_put(skb, RX_ALLOC_SIZE);
|
||||
|
||||
dma_addr = sbus_map_single(mp->myri_sdev, skb->data, RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE);
|
||||
dma_addr = dma_map_single(&mp->myri_op->dev,
|
||||
skb->data, RX_ALLOC_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
sbus_writel(dma_addr, &rxd[i].myri_scatters[0].addr);
|
||||
sbus_writel(RX_ALLOC_SIZE, &rxd[i].myri_scatters[0].len);
|
||||
sbus_writel(i, &rxd[i].ctx);
|
||||
|
|
@ -344,7 +351,8 @@ static void myri_tx(struct myri_eth *mp, struct net_device *dev)
|
|||
|
||||
DTX(("SKB[%d] ", entry));
|
||||
dma_addr = sbus_readl(&sq->myri_txd[entry].myri_gathers[0].addr);
|
||||
sbus_unmap_single(mp->myri_sdev, dma_addr, skb->len, SBUS_DMA_TODEVICE);
|
||||
dma_unmap_single(&mp->myri_op->dev, dma_addr,
|
||||
skb->len, DMA_TO_DEVICE);
|
||||
dev_kfree_skb(skb);
|
||||
mp->tx_skbs[entry] = NULL;
|
||||
dev->stats.tx_packets++;
|
||||
|
|
@ -423,9 +431,9 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
|
|||
|
||||
/* Check for errors. */
|
||||
DRX(("rxd[%d]: %p len[%d] csum[%08x] ", entry, rxd, len, csum));
|
||||
sbus_dma_sync_single_for_cpu(mp->myri_sdev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE);
|
||||
dma_sync_single_for_cpu(&mp->myri_op->dev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE, DMA_FROM_DEVICE);
|
||||
if (len < (ETH_HLEN + MYRI_PAD_LEN) || (skb->data[0] != MYRI_PAD_LEN)) {
|
||||
DRX(("ERROR["));
|
||||
dev->stats.rx_errors++;
|
||||
|
|
@ -442,10 +450,10 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
|
|||
drops++;
|
||||
DRX(("DROP "));
|
||||
dev->stats.rx_dropped++;
|
||||
sbus_dma_sync_single_for_device(mp->myri_sdev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_sync_single_for_device(&mp->myri_op->dev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len);
|
||||
sbus_writel(index, &rxd->ctx);
|
||||
sbus_writel(1, &rxd->num_sg);
|
||||
|
|
@ -464,17 +472,17 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
|
|||
DRX(("skb_alloc(FAILED) "));
|
||||
goto drop_it;
|
||||
}
|
||||
sbus_unmap_single(mp->myri_sdev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_unmap_single(&mp->myri_op->dev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
mp->rx_skbs[index] = new_skb;
|
||||
new_skb->dev = dev;
|
||||
skb_put(new_skb, RX_ALLOC_SIZE);
|
||||
dma_addr = sbus_map_single(mp->myri_sdev,
|
||||
new_skb->data,
|
||||
RX_ALLOC_SIZE,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_addr = dma_map_single(&mp->myri_op->dev,
|
||||
new_skb->data,
|
||||
RX_ALLOC_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
sbus_writel(dma_addr, &rxd->myri_scatters[0].addr);
|
||||
sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len);
|
||||
sbus_writel(index, &rxd->ctx);
|
||||
|
|
@ -500,10 +508,10 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
|
|||
|
||||
/* Reuse original ring buffer. */
|
||||
DRX(("reuse "));
|
||||
sbus_dma_sync_single_for_device(mp->myri_sdev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_sync_single_for_device(&mp->myri_op->dev,
|
||||
sbus_readl(&rxd->myri_scatters[0].addr),
|
||||
RX_ALLOC_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
sbus_writel(RX_ALLOC_SIZE, &rxd->myri_scatters[0].len);
|
||||
sbus_writel(index, &rxd->ctx);
|
||||
sbus_writel(1, &rxd->num_sg);
|
||||
|
|
@ -652,7 +660,8 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
sbus_writew((skb->data[4] << 8) | skb->data[5], &txd->addr[3]);
|
||||
}
|
||||
|
||||
dma_addr = sbus_map_single(mp->myri_sdev, skb->data, len, SBUS_DMA_TODEVICE);
|
||||
dma_addr = dma_map_single(&mp->myri_op->dev, skb->data,
|
||||
len, DMA_TO_DEVICE);
|
||||
sbus_writel(dma_addr, &txd->myri_gathers[0].addr);
|
||||
sbus_writel(len, &txd->myri_gathers[0].len);
|
||||
sbus_writel(1, &txd->num_sg);
|
||||
|
|
@ -891,30 +900,30 @@ static const struct header_ops myri_header_ops = {
|
|||
.cache_update = myri_header_cache_update,
|
||||
};
|
||||
|
||||
static int __devinit myri_ether_init(struct sbus_dev *sdev)
|
||||
static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match)
|
||||
{
|
||||
static int num;
|
||||
struct device_node *dp = op->node;
|
||||
static unsigned version_printed;
|
||||
struct net_device *dev;
|
||||
struct myri_eth *mp;
|
||||
unsigned char prop_buf[32];
|
||||
int i;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
struct myri_eth *mp;
|
||||
const void *prop;
|
||||
static int num;
|
||||
int i, len;
|
||||
|
||||
DET(("myri_ether_init(%p,%d):\n", sdev, num));
|
||||
DET(("myri_ether_init(%p,%d):\n", op, num));
|
||||
dev = alloc_etherdev(sizeof(struct myri_eth));
|
||||
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (version_printed++ == 0)
|
||||
printk(version);
|
||||
|
||||
SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
|
||||
SET_NETDEV_DEV(dev, &op->dev);
|
||||
|
||||
mp = (struct myri_eth *) dev->priv;
|
||||
mp = netdev_priv(dev);
|
||||
spin_lock_init(&mp->irq_lock);
|
||||
mp->myri_sdev = sdev;
|
||||
mp->myri_op = op;
|
||||
|
||||
/* Clean out skb arrays. */
|
||||
for (i = 0; i < (RX_RING_SIZE + 1); i++)
|
||||
|
|
@ -924,55 +933,44 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
|
|||
mp->tx_skbs[i] = NULL;
|
||||
|
||||
/* First check for EEPROM information. */
|
||||
i = prom_getproperty(sdev->prom_node, "myrinet-eeprom-info",
|
||||
(char *)&mp->eeprom, sizeof(struct myri_eeprom));
|
||||
DET(("prom_getprop(myrinet-eeprom-info) returns %d\n", i));
|
||||
if (i == 0 || i == -1) {
|
||||
prop = of_get_property(dp, "myrinet-eeprom-info", &len);
|
||||
|
||||
if (prop)
|
||||
memcpy(&mp->eeprom, prop, sizeof(struct myri_eeprom));
|
||||
if (!prop) {
|
||||
/* No eeprom property, must cook up the values ourselves. */
|
||||
DET(("No EEPROM: "));
|
||||
mp->eeprom.bus_type = BUS_TYPE_SBUS;
|
||||
mp->eeprom.cpuvers = prom_getintdefault(sdev->prom_node,"cpu_version",0);
|
||||
mp->eeprom.cval = prom_getintdefault(sdev->prom_node,"clock_value",0);
|
||||
mp->eeprom.ramsz = prom_getintdefault(sdev->prom_node,"sram_size",0);
|
||||
DET(("cpuvers[%d] cval[%d] ramsz[%d]\n", mp->eeprom.cpuvers,
|
||||
mp->eeprom.cval, mp->eeprom.ramsz));
|
||||
if (mp->eeprom.cpuvers == 0) {
|
||||
DET(("EEPROM: cpuvers was zero, setting to %04x\n",CPUVERS_2_3));
|
||||
mp->eeprom.cpuvers =
|
||||
of_getintprop_default(dp, "cpu_version", 0);
|
||||
mp->eeprom.cval =
|
||||
of_getintprop_default(dp, "clock_value", 0);
|
||||
mp->eeprom.ramsz = of_getintprop_default(dp, "sram_size", 0);
|
||||
if (!mp->eeprom.cpuvers)
|
||||
mp->eeprom.cpuvers = CPUVERS_2_3;
|
||||
}
|
||||
if (mp->eeprom.cpuvers < CPUVERS_3_0) {
|
||||
DET(("EEPROM: cpuvers < CPUVERS_3_0, clockval set to zero.\n"));
|
||||
if (mp->eeprom.cpuvers < CPUVERS_3_0)
|
||||
mp->eeprom.cval = 0;
|
||||
}
|
||||
if (mp->eeprom.ramsz == 0) {
|
||||
DET(("EEPROM: ramsz == 0, setting to 128k\n"));
|
||||
if (!mp->eeprom.ramsz)
|
||||
mp->eeprom.ramsz = (128 * 1024);
|
||||
}
|
||||
i = prom_getproperty(sdev->prom_node, "myrinet-board-id",
|
||||
&prop_buf[0], 10);
|
||||
DET(("EEPROM: prom_getprop(myrinet-board-id) returns %d\n", i));
|
||||
if ((i != 0) && (i != -1))
|
||||
memcpy(&mp->eeprom.id[0], &prop_buf[0], 6);
|
||||
|
||||
prop = of_get_property(dp, "myrinet-board-id", &len);
|
||||
if (prop)
|
||||
memcpy(&mp->eeprom.id[0], prop, 6);
|
||||
else
|
||||
set_boardid_from_idprom(mp, num);
|
||||
i = prom_getproperty(sdev->prom_node, "fpga_version",
|
||||
&mp->eeprom.fvers[0], 32);
|
||||
DET(("EEPROM: prom_getprop(fpga_version) returns %d\n", i));
|
||||
if (i == 0 || i == -1)
|
||||
|
||||
prop = of_get_property(dp, "fpga_version", &len);
|
||||
if (prop)
|
||||
memcpy(&mp->eeprom.fvers[0], prop, 32);
|
||||
else
|
||||
memset(&mp->eeprom.fvers[0], 0, 32);
|
||||
|
||||
if (mp->eeprom.cpuvers == CPUVERS_4_1) {
|
||||
DET(("EEPROM: cpuvers CPUVERS_4_1, "));
|
||||
if (mp->eeprom.ramsz == (128 * 1024)) {
|
||||
DET(("ramsize 128k, setting to 256k, "));
|
||||
if (mp->eeprom.ramsz == (128 * 1024))
|
||||
mp->eeprom.ramsz = (256 * 1024);
|
||||
}
|
||||
if ((mp->eeprom.cval==0x40414041)||(mp->eeprom.cval==0x90449044)){
|
||||
DET(("changing cval from %08x to %08x ",
|
||||
mp->eeprom.cval, 0x50e450e4));
|
||||
if ((mp->eeprom.cval == 0x40414041) ||
|
||||
(mp->eeprom.cval == 0x90449044))
|
||||
mp->eeprom.cval = 0x50e450e4;
|
||||
}
|
||||
DET(("\n"));
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_DETECT
|
||||
|
|
@ -991,8 +989,8 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
|
|||
* XXX only a valid version for PCI cards? Ask feldy...
|
||||
*/
|
||||
DET(("Mapping regs for cpuvers < CPUVERS_4_0\n"));
|
||||
mp->regs = sbus_ioremap(&sdev->resource[0], 0,
|
||||
mp->reg_size, "MyriCOM Regs");
|
||||
mp->regs = of_ioremap(&op->resource[0], 0,
|
||||
mp->reg_size, "MyriCOM Regs");
|
||||
if (!mp->regs) {
|
||||
printk("MyriCOM: Cannot map MyriCOM registers.\n");
|
||||
goto err;
|
||||
|
|
@ -1001,13 +999,12 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
|
|||
mp->lregs = mp->lanai + (0x10000 * 2);
|
||||
} else {
|
||||
DET(("Mapping regs for cpuvers >= CPUVERS_4_0\n"));
|
||||
mp->cregs = sbus_ioremap(&sdev->resource[0], 0,
|
||||
PAGE_SIZE, "MyriCOM Control Regs");
|
||||
mp->lregs = sbus_ioremap(&sdev->resource[0], (256 * 1024),
|
||||
mp->cregs = of_ioremap(&op->resource[0], 0,
|
||||
PAGE_SIZE, "MyriCOM Control Regs");
|
||||
mp->lregs = of_ioremap(&op->resource[0], (256 * 1024),
|
||||
PAGE_SIZE, "MyriCOM LANAI Regs");
|
||||
mp->lanai =
|
||||
sbus_ioremap(&sdev->resource[0], (512 * 1024),
|
||||
mp->eeprom.ramsz, "MyriCOM SRAM");
|
||||
mp->lanai = of_ioremap(&op->resource[0], (512 * 1024),
|
||||
mp->eeprom.ramsz, "MyriCOM SRAM");
|
||||
}
|
||||
DET(("Registers mapped: cregs[%p] lregs[%p] lanai[%p]\n",
|
||||
mp->cregs, mp->lregs, mp->lanai));
|
||||
|
|
@ -1039,16 +1036,15 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
|
|||
myri_reset_on(mp->cregs);
|
||||
|
||||
/* Get the supported DVMA burst sizes from our SBUS. */
|
||||
mp->myri_bursts = prom_getintdefault(mp->myri_sdev->bus->prom_node,
|
||||
"burst-sizes", 0x00);
|
||||
|
||||
if (!sbus_can_burst64(sdev))
|
||||
mp->myri_bursts = of_getintprop_default(dp->parent,
|
||||
"burst-sizes", 0x00);
|
||||
if (!sbus_can_burst64())
|
||||
mp->myri_bursts &= ~(DMA_BURST64);
|
||||
|
||||
DET(("MYRI bursts %02x\n", mp->myri_bursts));
|
||||
|
||||
/* Encode SBUS interrupt level in second control register. */
|
||||
i = prom_getint(sdev->prom_node, "interrupts");
|
||||
i = of_getintprop_default(dp, "interrupts", 0);
|
||||
if (i == 0)
|
||||
i = 4;
|
||||
DET(("prom_getint(interrupts)==%d, irqlvl set to %04x\n",
|
||||
|
|
@ -1063,7 +1059,7 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
|
|||
dev->tx_timeout = &myri_tx_timeout;
|
||||
dev->watchdog_timeo = 5*HZ;
|
||||
dev->set_multicast_list = &myri_set_multicast;
|
||||
dev->irq = sdev->irqs[0];
|
||||
dev->irq = op->irqs[0];
|
||||
|
||||
/* Register interrupt handler now. */
|
||||
DET(("Requesting MYRIcom IRQ line.\n"));
|
||||
|
|
@ -1088,7 +1084,7 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
|
|||
goto err_free_irq;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&sdev->ofdev.dev, mp);
|
||||
dev_set_drvdata(&op->dev, mp);
|
||||
|
||||
num++;
|
||||
|
||||
|
|
@ -1105,17 +1101,9 @@ err:
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match)
|
||||
static int __devexit myri_sbus_remove(struct of_device *op)
|
||||
{
|
||||
struct sbus_dev *sdev = to_sbus_device(&dev->dev);
|
||||
|
||||
return myri_ether_init(sdev);
|
||||
}
|
||||
|
||||
static int __devexit myri_sbus_remove(struct of_device *dev)
|
||||
{
|
||||
struct myri_eth *mp = dev_get_drvdata(&dev->dev);
|
||||
struct myri_eth *mp = dev_get_drvdata(&op->dev);
|
||||
struct net_device *net_dev = mp->dev;
|
||||
|
||||
unregister_netdev(net_dev);
|
||||
|
|
@ -1123,21 +1111,21 @@ static int __devexit myri_sbus_remove(struct of_device *dev)
|
|||
free_irq(net_dev->irq, net_dev);
|
||||
|
||||
if (mp->eeprom.cpuvers < CPUVERS_4_0) {
|
||||
sbus_iounmap(mp->regs, mp->reg_size);
|
||||
of_iounmap(&op->resource[0], mp->regs, mp->reg_size);
|
||||
} else {
|
||||
sbus_iounmap(mp->cregs, PAGE_SIZE);
|
||||
sbus_iounmap(mp->lregs, (256 * 1024));
|
||||
sbus_iounmap(mp->lanai, (512 * 1024));
|
||||
of_iounmap(&op->resource[0], mp->cregs, PAGE_SIZE);
|
||||
of_iounmap(&op->resource[0], mp->lregs, (256 * 1024));
|
||||
of_iounmap(&op->resource[0], mp->lanai, (512 * 1024));
|
||||
}
|
||||
|
||||
free_netdev(net_dev);
|
||||
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id myri_sbus_match[] = {
|
||||
static const struct of_device_id myri_sbus_match[] = {
|
||||
{
|
||||
.name = "MYRICOM,mlanai",
|
||||
},
|
||||
|
|
@ -1158,7 +1146,7 @@ static struct of_platform_driver myri_sbus_driver = {
|
|||
|
||||
static int __init myri_sbus_init(void)
|
||||
{
|
||||
return of_register_driver(&myri_sbus_driver, &sbus_bus_type);
|
||||
return of_register_driver(&myri_sbus_driver, &of_bus_type);
|
||||
}
|
||||
|
||||
static void __exit myri_sbus_exit(void)
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ struct myri_eth {
|
|||
struct myri_eeprom eeprom; /* Local copy of EEPROM. */
|
||||
unsigned int reg_size; /* Size of register space. */
|
||||
unsigned int shmem_base; /* Offset to shared ram. */
|
||||
struct sbus_dev *myri_sdev; /* Our SBUS device struct. */
|
||||
struct of_device *myri_op; /* Our OF device struct. */
|
||||
};
|
||||
|
||||
/* We use this to acquire receive skb's that we can DMA directly into. */
|
||||
|
|
|
|||
|
|
@ -9130,7 +9130,7 @@ static int __devexit niu_of_remove(struct of_device *op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id niu_match[] = {
|
||||
static const struct of_device_id niu_match[] = {
|
||||
{
|
||||
.name = "network",
|
||||
.compatible = "SUNW,niusl",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/* $Id: sunbmac.c,v 1.30 2002/01/15 06:48:55 davem Exp $
|
||||
* sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters.
|
||||
/* sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters.
|
||||
*
|
||||
* Copyright (C) 1997, 1998, 1999, 2003 David S. Miller (davem@redhat.com)
|
||||
* Copyright (C) 1997, 1998, 1999, 2003, 2008 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -23,6 +22,9 @@
|
|||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/auxio.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
|
@ -32,15 +34,14 @@
|
|||
#include <asm/openprom.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include "sunbmac.h"
|
||||
|
||||
#define DRV_NAME "sunbmac"
|
||||
#define DRV_VERSION "2.0"
|
||||
#define DRV_RELDATE "11/24/03"
|
||||
#define DRV_AUTHOR "David S. Miller (davem@redhat.com)"
|
||||
#define DRV_VERSION "2.1"
|
||||
#define DRV_RELDATE "August 26, 2008"
|
||||
#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"
|
||||
|
||||
static char version[] =
|
||||
DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
|
||||
|
|
@ -96,8 +97,8 @@ static int qec_global_reset(void __iomem *gregs)
|
|||
|
||||
static void qec_init(struct bigmac *bp)
|
||||
{
|
||||
struct of_device *qec_op = bp->qec_op;
|
||||
void __iomem *gregs = bp->gregs;
|
||||
struct sbus_dev *qec_sdev = bp->qec_sdev;
|
||||
u8 bsizes = bp->bigmac_bursts;
|
||||
u32 regval;
|
||||
|
||||
|
|
@ -112,13 +113,13 @@ static void qec_init(struct bigmac *bp)
|
|||
sbus_writel(GLOB_PSIZE_2048, gregs + GLOB_PSIZE);
|
||||
|
||||
/* All of memsize is given to bigmac. */
|
||||
sbus_writel(qec_sdev->reg_addrs[1].reg_size,
|
||||
sbus_writel(resource_size(&qec_op->resource[1]),
|
||||
gregs + GLOB_MSIZE);
|
||||
|
||||
/* Half to the transmitter, half to the receiver. */
|
||||
sbus_writel(qec_sdev->reg_addrs[1].reg_size >> 1,
|
||||
sbus_writel(resource_size(&qec_op->resource[1]) >> 1,
|
||||
gregs + GLOB_TSIZE);
|
||||
sbus_writel(qec_sdev->reg_addrs[1].reg_size >> 1,
|
||||
sbus_writel(resource_size(&qec_op->resource[1]) >> 1,
|
||||
gregs + GLOB_RSIZE);
|
||||
}
|
||||
|
||||
|
|
@ -239,9 +240,10 @@ static void bigmac_init_rings(struct bigmac *bp, int from_irq)
|
|||
skb_reserve(skb, 34);
|
||||
|
||||
bb->be_rxd[i].rx_addr =
|
||||
sbus_map_single(bp->bigmac_sdev, skb->data,
|
||||
RX_BUF_ALLOC_SIZE - 34,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_map_single(&bp->bigmac_op->dev,
|
||||
skb->data,
|
||||
RX_BUF_ALLOC_SIZE - 34,
|
||||
DMA_FROM_DEVICE);
|
||||
bb->be_rxd[i].rx_flags =
|
||||
(RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
|
||||
}
|
||||
|
|
@ -776,9 +778,9 @@ static void bigmac_tx(struct bigmac *bp)
|
|||
skb = bp->tx_skbs[elem];
|
||||
bp->enet_stats.tx_packets++;
|
||||
bp->enet_stats.tx_bytes += skb->len;
|
||||
sbus_unmap_single(bp->bigmac_sdev,
|
||||
this->tx_addr, skb->len,
|
||||
SBUS_DMA_TODEVICE);
|
||||
dma_unmap_single(&bp->bigmac_op->dev,
|
||||
this->tx_addr, skb->len,
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
DTX(("skb(%p) ", skb));
|
||||
bp->tx_skbs[elem] = NULL;
|
||||
|
|
@ -831,18 +833,19 @@ static void bigmac_rx(struct bigmac *bp)
|
|||
drops++;
|
||||
goto drop_it;
|
||||
}
|
||||
sbus_unmap_single(bp->bigmac_sdev,
|
||||
this->rx_addr,
|
||||
RX_BUF_ALLOC_SIZE - 34,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_unmap_single(&bp->bigmac_op->dev,
|
||||
this->rx_addr,
|
||||
RX_BUF_ALLOC_SIZE - 34,
|
||||
DMA_FROM_DEVICE);
|
||||
bp->rx_skbs[elem] = new_skb;
|
||||
new_skb->dev = bp->dev;
|
||||
skb_put(new_skb, ETH_FRAME_LEN);
|
||||
skb_reserve(new_skb, 34);
|
||||
this->rx_addr = sbus_map_single(bp->bigmac_sdev,
|
||||
new_skb->data,
|
||||
RX_BUF_ALLOC_SIZE - 34,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
this->rx_addr =
|
||||
dma_map_single(&bp->bigmac_op->dev,
|
||||
new_skb->data,
|
||||
RX_BUF_ALLOC_SIZE - 34,
|
||||
DMA_FROM_DEVICE);
|
||||
this->rx_flags =
|
||||
(RXD_OWN | ((RX_BUF_ALLOC_SIZE - 34) & RXD_LENGTH));
|
||||
|
||||
|
|
@ -857,13 +860,13 @@ static void bigmac_rx(struct bigmac *bp)
|
|||
}
|
||||
skb_reserve(copy_skb, 2);
|
||||
skb_put(copy_skb, len);
|
||||
sbus_dma_sync_single_for_cpu(bp->bigmac_sdev,
|
||||
this->rx_addr, len,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_sync_single_for_cpu(&bp->bigmac_op->dev,
|
||||
this->rx_addr, len,
|
||||
DMA_FROM_DEVICE);
|
||||
skb_copy_to_linear_data(copy_skb, (unsigned char *)skb->data, len);
|
||||
sbus_dma_sync_single_for_device(bp->bigmac_sdev,
|
||||
this->rx_addr, len,
|
||||
SBUS_DMA_FROMDEVICE);
|
||||
dma_sync_single_for_device(&bp->bigmac_op->dev,
|
||||
this->rx_addr, len,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
/* Reuse original ring buffer. */
|
||||
this->rx_flags =
|
||||
|
|
@ -959,7 +962,8 @@ static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
u32 mapping;
|
||||
|
||||
len = skb->len;
|
||||
mapping = sbus_map_single(bp->bigmac_sdev, skb->data, len, SBUS_DMA_TODEVICE);
|
||||
mapping = dma_map_single(&bp->bigmac_op->dev, skb->data,
|
||||
len, DMA_TO_DEVICE);
|
||||
|
||||
/* Avoid a race... */
|
||||
spin_lock_irq(&bp->lock);
|
||||
|
|
@ -1051,12 +1055,8 @@ static void bigmac_set_multicast(struct net_device *dev)
|
|||
/* Ethtool support... */
|
||||
static void bigmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct bigmac *bp = dev->priv;
|
||||
|
||||
strcpy(info->driver, "sunbmac");
|
||||
strcpy(info->version, "2.0");
|
||||
sprintf(info->bus_info, "SBUS:%d",
|
||||
bp->qec_sdev->slot);
|
||||
}
|
||||
|
||||
static u32 bigmac_get_link(struct net_device *dev)
|
||||
|
|
@ -1075,14 +1075,15 @@ static const struct ethtool_ops bigmac_ethtool_ops = {
|
|||
.get_link = bigmac_get_link,
|
||||
};
|
||||
|
||||
static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
||||
static int __devinit bigmac_ether_init(struct of_device *op,
|
||||
struct of_device *qec_op)
|
||||
{
|
||||
struct net_device *dev;
|
||||
static int version_printed;
|
||||
struct bigmac *bp;
|
||||
struct net_device *dev;
|
||||
u8 bsizes, bsizes_more;
|
||||
int i;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
struct bigmac *bp;
|
||||
int i;
|
||||
|
||||
/* Get a new device struct for this interface. */
|
||||
dev = alloc_etherdev(sizeof(struct bigmac));
|
||||
|
|
@ -1092,32 +1093,21 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
|||
if (version_printed++ == 0)
|
||||
printk(KERN_INFO "%s", version);
|
||||
|
||||
dev->base_addr = (long) qec_sdev;
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = idprom->id_ethaddr[i];
|
||||
|
||||
/* Setup softc, with backpointers to QEC and BigMAC SBUS device structs. */
|
||||
bp = dev->priv;
|
||||
bp->qec_sdev = qec_sdev;
|
||||
bp->bigmac_sdev = qec_sdev->child;
|
||||
bp = netdev_priv(dev);
|
||||
bp->qec_op = qec_op;
|
||||
bp->bigmac_op = op;
|
||||
|
||||
SET_NETDEV_DEV(dev, &bp->bigmac_sdev->ofdev.dev);
|
||||
SET_NETDEV_DEV(dev, &op->dev);
|
||||
|
||||
spin_lock_init(&bp->lock);
|
||||
|
||||
/* Verify the registers we expect, are actually there. */
|
||||
if ((bp->bigmac_sdev->num_registers != 3) ||
|
||||
(bp->qec_sdev->num_registers != 2)) {
|
||||
printk(KERN_ERR "BIGMAC: Device does not have 2 and 3 regs, it has %d and %d.\n",
|
||||
bp->qec_sdev->num_registers,
|
||||
bp->bigmac_sdev->num_registers);
|
||||
printk(KERN_ERR "BIGMAC: Would you like that for here or to go?\n");
|
||||
goto fail_and_cleanup;
|
||||
}
|
||||
|
||||
/* Map in QEC global control registers. */
|
||||
bp->gregs = sbus_ioremap(&bp->qec_sdev->resource[0], 0,
|
||||
GLOB_REG_SIZE, "BigMAC QEC GLobal Regs");
|
||||
bp->gregs = of_ioremap(&qec_op->resource[0], 0,
|
||||
GLOB_REG_SIZE, "BigMAC QEC GLobal Regs");
|
||||
if (!bp->gregs) {
|
||||
printk(KERN_ERR "BIGMAC: Cannot map QEC global registers.\n");
|
||||
goto fail_and_cleanup;
|
||||
|
|
@ -1134,13 +1124,8 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
|||
goto fail_and_cleanup;
|
||||
|
||||
/* Get supported SBUS burst sizes. */
|
||||
bsizes = prom_getintdefault(bp->qec_sdev->prom_node,
|
||||
"burst-sizes",
|
||||
0xff);
|
||||
|
||||
bsizes_more = prom_getintdefault(bp->qec_sdev->bus->prom_node,
|
||||
"burst-sizes",
|
||||
0xff);
|
||||
bsizes = of_getintprop_default(qec_op->node, "burst-sizes", 0xff);
|
||||
bsizes_more = of_getintprop_default(qec_op->node, "burst-sizes", 0xff);
|
||||
|
||||
bsizes &= 0xff;
|
||||
if (bsizes_more != 0xff)
|
||||
|
|
@ -1154,16 +1139,16 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
|||
qec_init(bp);
|
||||
|
||||
/* Map in the BigMAC channel registers. */
|
||||
bp->creg = sbus_ioremap(&bp->bigmac_sdev->resource[0], 0,
|
||||
CREG_REG_SIZE, "BigMAC QEC Channel Regs");
|
||||
bp->creg = of_ioremap(&op->resource[0], 0,
|
||||
CREG_REG_SIZE, "BigMAC QEC Channel Regs");
|
||||
if (!bp->creg) {
|
||||
printk(KERN_ERR "BIGMAC: Cannot map QEC channel registers.\n");
|
||||
goto fail_and_cleanup;
|
||||
}
|
||||
|
||||
/* Map in the BigMAC control registers. */
|
||||
bp->bregs = sbus_ioremap(&bp->bigmac_sdev->resource[1], 0,
|
||||
BMAC_REG_SIZE, "BigMAC Primary Regs");
|
||||
bp->bregs = of_ioremap(&op->resource[1], 0,
|
||||
BMAC_REG_SIZE, "BigMAC Primary Regs");
|
||||
if (!bp->bregs) {
|
||||
printk(KERN_ERR "BIGMAC: Cannot map BigMAC primary registers.\n");
|
||||
goto fail_and_cleanup;
|
||||
|
|
@ -1172,8 +1157,8 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
|||
/* Map in the BigMAC transceiver registers, this is how you poke at
|
||||
* the BigMAC's PHY.
|
||||
*/
|
||||
bp->tregs = sbus_ioremap(&bp->bigmac_sdev->resource[2], 0,
|
||||
TCVR_REG_SIZE, "BigMAC Transceiver Regs");
|
||||
bp->tregs = of_ioremap(&op->resource[2], 0,
|
||||
TCVR_REG_SIZE, "BigMAC Transceiver Regs");
|
||||
if (!bp->tregs) {
|
||||
printk(KERN_ERR "BIGMAC: Cannot map BigMAC transceiver registers.\n");
|
||||
goto fail_and_cleanup;
|
||||
|
|
@ -1183,17 +1168,17 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
|||
bigmac_stop(bp);
|
||||
|
||||
/* Allocate transmit/receive descriptor DVMA block. */
|
||||
bp->bmac_block = sbus_alloc_consistent(bp->bigmac_sdev,
|
||||
PAGE_SIZE,
|
||||
&bp->bblock_dvma);
|
||||
bp->bmac_block = dma_alloc_coherent(&bp->bigmac_op->dev,
|
||||
PAGE_SIZE,
|
||||
&bp->bblock_dvma, GFP_ATOMIC);
|
||||
if (bp->bmac_block == NULL || bp->bblock_dvma == 0) {
|
||||
printk(KERN_ERR "BIGMAC: Cannot allocate consistent DMA.\n");
|
||||
goto fail_and_cleanup;
|
||||
}
|
||||
|
||||
/* Get the board revision of this BigMAC. */
|
||||
bp->board_rev = prom_getintdefault(bp->bigmac_sdev->prom_node,
|
||||
"board-version", 1);
|
||||
bp->board_rev = of_getintprop_default(bp->bigmac_op->node,
|
||||
"board-version", 1);
|
||||
|
||||
/* Init auto-negotiation timer state. */
|
||||
init_timer(&bp->bigmac_timer);
|
||||
|
|
@ -1217,7 +1202,7 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
|||
dev->watchdog_timeo = 5*HZ;
|
||||
|
||||
/* Finish net device registration. */
|
||||
dev->irq = bp->bigmac_sdev->irqs[0];
|
||||
dev->irq = bp->bigmac_op->irqs[0];
|
||||
dev->dma = 0;
|
||||
|
||||
if (register_netdev(dev)) {
|
||||
|
|
@ -1225,7 +1210,7 @@ static int __devinit bigmac_ether_init(struct sbus_dev *qec_sdev)
|
|||
goto fail_and_cleanup;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&bp->bigmac_sdev->ofdev.dev, bp);
|
||||
dev_set_drvdata(&bp->bigmac_op->dev, bp);
|
||||
|
||||
printk(KERN_INFO "%s: BigMAC 100baseT Ethernet %s\n",
|
||||
dev->name, print_mac(mac, dev->dev_addr));
|
||||
|
|
@ -1236,66 +1221,67 @@ fail_and_cleanup:
|
|||
/* Something went wrong, undo whatever we did so far. */
|
||||
/* Free register mappings if any. */
|
||||
if (bp->gregs)
|
||||
sbus_iounmap(bp->gregs, GLOB_REG_SIZE);
|
||||
of_iounmap(&qec_op->resource[0], bp->gregs, GLOB_REG_SIZE);
|
||||
if (bp->creg)
|
||||
sbus_iounmap(bp->creg, CREG_REG_SIZE);
|
||||
of_iounmap(&op->resource[0], bp->creg, CREG_REG_SIZE);
|
||||
if (bp->bregs)
|
||||
sbus_iounmap(bp->bregs, BMAC_REG_SIZE);
|
||||
of_iounmap(&op->resource[1], bp->bregs, BMAC_REG_SIZE);
|
||||
if (bp->tregs)
|
||||
sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
|
||||
of_iounmap(&op->resource[2], bp->tregs, TCVR_REG_SIZE);
|
||||
|
||||
if (bp->bmac_block)
|
||||
sbus_free_consistent(bp->bigmac_sdev,
|
||||
PAGE_SIZE,
|
||||
bp->bmac_block,
|
||||
bp->bblock_dvma);
|
||||
dma_free_coherent(&bp->bigmac_op->dev,
|
||||
PAGE_SIZE,
|
||||
bp->bmac_block,
|
||||
bp->bblock_dvma);
|
||||
|
||||
/* This also frees the co-located 'dev->priv' */
|
||||
free_netdev(dev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* QEC can be the parent of either QuadEthernet or
|
||||
* a BigMAC. We want the latter.
|
||||
/* QEC can be the parent of either QuadEthernet or a BigMAC. We want
|
||||
* the latter.
|
||||
*/
|
||||
static int __devinit bigmac_sbus_probe(struct of_device *dev, const struct of_device_id *match)
|
||||
static int __devinit bigmac_sbus_probe(struct of_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct sbus_dev *sdev = to_sbus_device(&dev->dev);
|
||||
struct device_node *dp = dev->node;
|
||||
struct device *parent = op->dev.parent;
|
||||
struct of_device *qec_op;
|
||||
|
||||
if (!strcmp(dp->name, "be"))
|
||||
sdev = sdev->parent;
|
||||
qec_op = to_of_device(parent);
|
||||
|
||||
return bigmac_ether_init(sdev);
|
||||
return bigmac_ether_init(op, qec_op);
|
||||
}
|
||||
|
||||
static int __devexit bigmac_sbus_remove(struct of_device *dev)
|
||||
static int __devexit bigmac_sbus_remove(struct of_device *op)
|
||||
{
|
||||
struct bigmac *bp = dev_get_drvdata(&dev->dev);
|
||||
struct bigmac *bp = dev_get_drvdata(&op->dev);
|
||||
struct device *parent = op->dev.parent;
|
||||
struct net_device *net_dev = bp->dev;
|
||||
struct of_device *qec_op;
|
||||
|
||||
qec_op = to_of_device(parent);
|
||||
|
||||
unregister_netdev(net_dev);
|
||||
|
||||
sbus_iounmap(bp->gregs, GLOB_REG_SIZE);
|
||||
sbus_iounmap(bp->creg, CREG_REG_SIZE);
|
||||
sbus_iounmap(bp->bregs, BMAC_REG_SIZE);
|
||||
sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
|
||||
sbus_free_consistent(bp->bigmac_sdev,
|
||||
PAGE_SIZE,
|
||||
bp->bmac_block,
|
||||
bp->bblock_dvma);
|
||||
of_iounmap(&qec_op->resource[0], bp->gregs, GLOB_REG_SIZE);
|
||||
of_iounmap(&op->resource[0], bp->creg, CREG_REG_SIZE);
|
||||
of_iounmap(&op->resource[1], bp->bregs, BMAC_REG_SIZE);
|
||||
of_iounmap(&op->resource[2], bp->tregs, TCVR_REG_SIZE);
|
||||
dma_free_coherent(&op->dev,
|
||||
PAGE_SIZE,
|
||||
bp->bmac_block,
|
||||
bp->bblock_dvma);
|
||||
|
||||
free_netdev(net_dev);
|
||||
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id bigmac_sbus_match[] = {
|
||||
{
|
||||
.name = "qec",
|
||||
},
|
||||
static const struct of_device_id bigmac_sbus_match[] = {
|
||||
{
|
||||
.name = "be",
|
||||
},
|
||||
|
|
@ -1313,7 +1299,7 @@ static struct of_platform_driver bigmac_sbus_driver = {
|
|||
|
||||
static int __init bigmac_init(void)
|
||||
{
|
||||
return of_register_driver(&bigmac_sbus_driver, &sbus_bus_type);
|
||||
return of_register_driver(&bigmac_sbus_driver, &of_bus_type);
|
||||
}
|
||||
|
||||
static void __exit bigmac_exit(void)
|
||||
|
|
|
|||
|
|
@ -329,8 +329,8 @@ struct bigmac {
|
|||
unsigned int timer_ticks;
|
||||
|
||||
struct net_device_stats enet_stats;
|
||||
struct sbus_dev *qec_sdev;
|
||||
struct sbus_dev *bigmac_sdev;
|
||||
struct of_device *qec_op;
|
||||
struct of_device *bigmac_op;
|
||||
struct net_device *dev;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* "Happy Meal Ethernet" found on SunSwift SBUS cards.
|
||||
*
|
||||
* Copyright (C) 1996, 1998, 1999, 2002, 2003,
|
||||
2006 David S. Miller (davem@davemloft.net)
|
||||
* 2006, 2008 David S. Miller (davem@davemloft.net)
|
||||
*
|
||||
* Changes :
|
||||
* 2000/11/11 Willy Tarreau <willy AT meta-x.org>
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
|
|
@ -41,8 +42,9 @@
|
|||
#include <asm/byteorder.h>
|
||||
|
||||
#ifdef CONFIG_SPARC
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/openprom.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/prom.h>
|
||||
|
|
@ -60,8 +62,8 @@
|
|||
#include "sunhme.h"
|
||||
|
||||
#define DRV_NAME "sunhme"
|
||||
#define DRV_VERSION "3.00"
|
||||
#define DRV_RELDATE "June 23, 2006"
|
||||
#define DRV_VERSION "3.10"
|
||||
#define DRV_RELDATE "August 26, 2008"
|
||||
#define DRV_AUTHOR "David S. Miller ([email protected])"
|
||||
|
||||
static char version[] =
|
||||
|
|
@ -251,13 +253,13 @@ static u32 pci_hme_read_desc32(hme32 *p)
|
|||
#define hme_read_desc32(__hp, __p) \
|
||||
((__hp)->read_desc32(__p))
|
||||
#define hme_dma_map(__hp, __ptr, __size, __dir) \
|
||||
((__hp)->dma_map((__hp)->happy_dev, (__ptr), (__size), (__dir)))
|
||||
((__hp)->dma_map((__hp)->dma_dev, (__ptr), (__size), (__dir)))
|
||||
#define hme_dma_unmap(__hp, __addr, __size, __dir) \
|
||||
((__hp)->dma_unmap((__hp)->happy_dev, (__addr), (__size), (__dir)))
|
||||
((__hp)->dma_unmap((__hp)->dma_dev, (__addr), (__size), (__dir)))
|
||||
#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
|
||||
((__hp)->dma_sync_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir)))
|
||||
((__hp)->dma_sync_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir)))
|
||||
#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
|
||||
((__hp)->dma_sync_for_device((__hp)->happy_dev, (__addr), (__size), (__dir)))
|
||||
((__hp)->dma_sync_for_device((__hp)->dma_dev, (__addr), (__size), (__dir)))
|
||||
#else
|
||||
#ifdef CONFIG_SBUS
|
||||
/* SBUS only compilation */
|
||||
|
|
@ -277,13 +279,13 @@ do { (__txd)->tx_addr = (__force hme32)(u32)(__addr); \
|
|||
} while(0)
|
||||
#define hme_read_desc32(__hp, __p) ((__force u32)(hme32)*(__p))
|
||||
#define hme_dma_map(__hp, __ptr, __size, __dir) \
|
||||
sbus_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir))
|
||||
dma_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir))
|
||||
#define hme_dma_unmap(__hp, __addr, __size, __dir) \
|
||||
sbus_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir))
|
||||
dma_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir))
|
||||
#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
|
||||
sbus_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir))
|
||||
dma_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir))
|
||||
#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
|
||||
sbus_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir))
|
||||
dma_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir))
|
||||
#else
|
||||
/* PCI only compilation */
|
||||
#define hme_write32(__hp, __reg, __val) \
|
||||
|
|
@ -305,36 +307,17 @@ static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p)
|
|||
return le32_to_cpup((__le32 *)p);
|
||||
}
|
||||
#define hme_dma_map(__hp, __ptr, __size, __dir) \
|
||||
pci_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir))
|
||||
pci_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir))
|
||||
#define hme_dma_unmap(__hp, __addr, __size, __dir) \
|
||||
pci_unmap_single((__hp)->happy_dev, (__addr), (__size), (__dir))
|
||||
pci_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir))
|
||||
#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
|
||||
pci_dma_sync_single_for_cpu((__hp)->happy_dev, (__addr), (__size), (__dir))
|
||||
pci_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir))
|
||||
#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
|
||||
pci_dma_sync_single_for_device((__hp)->happy_dev, (__addr), (__size), (__dir))
|
||||
pci_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SBUS_DMA_BIDIRECTIONAL
|
||||
# define DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL
|
||||
#else
|
||||
# define DMA_BIDIRECTIONAL 0
|
||||
#endif
|
||||
|
||||
#ifdef SBUS_DMA_FROMDEVICE
|
||||
# define DMA_FROMDEVICE SBUS_DMA_FROMDEVICE
|
||||
#else
|
||||
# define DMA_TODEVICE 1
|
||||
#endif
|
||||
|
||||
#ifdef SBUS_DMA_TODEVICE
|
||||
# define DMA_TODEVICE SBUS_DMA_TODEVICE
|
||||
#else
|
||||
# define DMA_FROMDEVICE 2
|
||||
#endif
|
||||
|
||||
|
||||
/* Oh yes, the MIF BitBang is mighty fun to program. BitBucket is more like it. */
|
||||
static void BB_PUT_BIT(struct happy_meal *hp, void __iomem *tregs, int bit)
|
||||
{
|
||||
|
|
@ -1224,7 +1207,8 @@ static void happy_meal_clean_rings(struct happy_meal *hp)
|
|||
|
||||
rxd = &hp->happy_block->happy_meal_rxd[i];
|
||||
dma_addr = hme_read_desc32(hp, &rxd->rx_addr);
|
||||
hme_dma_unmap(hp, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE);
|
||||
dma_unmap_single(hp->dma_dev, dma_addr,
|
||||
RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
|
||||
dev_kfree_skb_any(skb);
|
||||
hp->rx_skbs[i] = NULL;
|
||||
}
|
||||
|
|
@ -1242,10 +1226,10 @@ static void happy_meal_clean_rings(struct happy_meal *hp)
|
|||
for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
|
||||
txd = &hp->happy_block->happy_meal_txd[i];
|
||||
dma_addr = hme_read_desc32(hp, &txd->tx_addr);
|
||||
hme_dma_unmap(hp, dma_addr,
|
||||
(hme_read_desc32(hp, &txd->tx_flags)
|
||||
& TXFLAG_SIZE),
|
||||
DMA_TODEVICE);
|
||||
dma_unmap_single(hp->dma_dev, dma_addr,
|
||||
(hme_read_desc32(hp, &txd->tx_flags)
|
||||
& TXFLAG_SIZE),
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
if (frag != skb_shinfo(skb)->nr_frags)
|
||||
i++;
|
||||
|
|
@ -1287,7 +1271,8 @@ static void happy_meal_init_rings(struct happy_meal *hp)
|
|||
skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
|
||||
hme_write_rxd(hp, &hb->happy_meal_rxd[i],
|
||||
(RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16)),
|
||||
hme_dma_map(hp, skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE));
|
||||
dma_map_single(hp->dma_dev, skb->data, RX_BUF_ALLOC_SIZE,
|
||||
DMA_FROM_DEVICE));
|
||||
skb_reserve(skb, RX_OFFSET);
|
||||
}
|
||||
|
||||
|
|
@ -1593,7 +1578,7 @@ static int happy_meal_init(struct happy_meal *hp)
|
|||
if ((hp->happy_bursts & DMA_BURST64) &&
|
||||
((hp->happy_flags & HFLAG_PCI) != 0
|
||||
#ifdef CONFIG_SBUS
|
||||
|| sbus_can_burst64(hp->happy_dev)
|
||||
|| sbus_can_burst64()
|
||||
#endif
|
||||
|| 0)) {
|
||||
u32 gcfg = GREG_CFG_BURST64;
|
||||
|
|
@ -1603,11 +1588,13 @@ static int happy_meal_init(struct happy_meal *hp)
|
|||
* do not. -DaveM
|
||||
*/
|
||||
#ifdef CONFIG_SBUS
|
||||
if ((hp->happy_flags & HFLAG_PCI) == 0 &&
|
||||
sbus_can_dma_64bit(hp->happy_dev)) {
|
||||
sbus_set_sbus64(hp->happy_dev,
|
||||
hp->happy_bursts);
|
||||
gcfg |= GREG_CFG_64BIT;
|
||||
if ((hp->happy_flags & HFLAG_PCI) == 0) {
|
||||
struct of_device *op = hp->happy_dev;
|
||||
if (sbus_can_dma_64bit()) {
|
||||
sbus_set_sbus64(&op->dev,
|
||||
hp->happy_bursts);
|
||||
gcfg |= GREG_CFG_64BIT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1966,7 +1953,7 @@ static void happy_meal_tx(struct happy_meal *hp)
|
|||
dma_len = hme_read_desc32(hp, &this->tx_flags);
|
||||
|
||||
dma_len &= TXFLAG_SIZE;
|
||||
hme_dma_unmap(hp, dma_addr, dma_len, DMA_TODEVICE);
|
||||
dma_unmap_single(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE);
|
||||
|
||||
elem = NEXT_TX(elem);
|
||||
this = &txbase[elem];
|
||||
|
|
@ -2044,13 +2031,14 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
|
|||
drops++;
|
||||
goto drop_it;
|
||||
}
|
||||
hme_dma_unmap(hp, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE);
|
||||
dma_unmap_single(hp->dma_dev, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
|
||||
hp->rx_skbs[elem] = new_skb;
|
||||
new_skb->dev = dev;
|
||||
skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
|
||||
hme_write_rxd(hp, this,
|
||||
(RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
|
||||
hme_dma_map(hp, new_skb->data, RX_BUF_ALLOC_SIZE, DMA_FROMDEVICE));
|
||||
dma_map_single(hp->dma_dev, new_skb->data, RX_BUF_ALLOC_SIZE,
|
||||
DMA_FROM_DEVICE));
|
||||
skb_reserve(new_skb, RX_OFFSET);
|
||||
|
||||
/* Trim the original skb for the netif. */
|
||||
|
|
@ -2065,10 +2053,9 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
|
|||
|
||||
skb_reserve(copy_skb, 2);
|
||||
skb_put(copy_skb, len);
|
||||
hme_dma_sync_for_cpu(hp, dma_addr, len, DMA_FROMDEVICE);
|
||||
dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
|
||||
skb_copy_from_linear_data(skb, copy_skb->data, len);
|
||||
hme_dma_sync_for_device(hp, dma_addr, len, DMA_FROMDEVICE);
|
||||
|
||||
dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
|
||||
/* Reuse original ring buffer. */
|
||||
hme_write_rxd(hp, this,
|
||||
(RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
|
||||
|
|
@ -2300,7 +2287,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
u32 mapping, len;
|
||||
|
||||
len = skb->len;
|
||||
mapping = hme_dma_map(hp, skb->data, len, DMA_TODEVICE);
|
||||
mapping = dma_map_single(hp->dma_dev, skb->data, len, DMA_TO_DEVICE);
|
||||
tx_flags |= (TXFLAG_SOP | TXFLAG_EOP);
|
||||
hme_write_txd(hp, &hp->happy_block->happy_meal_txd[entry],
|
||||
(tx_flags | (len & TXFLAG_SIZE)),
|
||||
|
|
@ -2314,7 +2301,8 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
* Otherwise we could race with the device.
|
||||
*/
|
||||
first_len = skb_headlen(skb);
|
||||
first_mapping = hme_dma_map(hp, skb->data, first_len, DMA_TODEVICE);
|
||||
first_mapping = dma_map_single(hp->dma_dev, skb->data, first_len,
|
||||
DMA_TO_DEVICE);
|
||||
entry = NEXT_TX(entry);
|
||||
|
||||
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
|
||||
|
|
@ -2322,10 +2310,9 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
u32 len, mapping, this_txflags;
|
||||
|
||||
len = this_frag->size;
|
||||
mapping = hme_dma_map(hp,
|
||||
((void *) page_address(this_frag->page) +
|
||||
this_frag->page_offset),
|
||||
len, DMA_TODEVICE);
|
||||
mapping = dma_map_page(hp->dma_dev, this_frag->page,
|
||||
this_frag->page_offset, len,
|
||||
DMA_TO_DEVICE);
|
||||
this_txflags = tx_flags;
|
||||
if (frag == skb_shinfo(skb)->nr_frags - 1)
|
||||
this_txflags |= TXFLAG_EOP;
|
||||
|
|
@ -2493,9 +2480,12 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info
|
|||
}
|
||||
#ifdef CONFIG_SBUS
|
||||
else {
|
||||
struct sbus_dev *sdev = hp->happy_dev;
|
||||
sprintf(info->bus_info, "SBUS:%d",
|
||||
sdev->slot);
|
||||
const struct linux_prom_registers *regs;
|
||||
struct of_device *op = hp->happy_dev;
|
||||
regs = of_get_property(op->node, "regs", NULL);
|
||||
if (regs)
|
||||
sprintf(info->bus_info, "SBUS:%d",
|
||||
regs->which_io);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -2521,63 +2511,21 @@ static const struct ethtool_ops hme_ethtool_ops = {
|
|||
static int hme_version_printed;
|
||||
|
||||
#ifdef CONFIG_SBUS
|
||||
void __devinit quattro_get_ranges(struct quattro *qp)
|
||||
{
|
||||
struct sbus_dev *sdev = qp->quattro_dev;
|
||||
int err;
|
||||
|
||||
err = prom_getproperty(sdev->prom_node,
|
||||
"ranges",
|
||||
(char *)&qp->ranges[0],
|
||||
sizeof(qp->ranges));
|
||||
if (err == 0 || err == -1) {
|
||||
qp->nranges = 0;
|
||||
return;
|
||||
}
|
||||
qp->nranges = (err / sizeof(struct linux_prom_ranges));
|
||||
}
|
||||
|
||||
static void __devinit quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp)
|
||||
{
|
||||
struct sbus_dev *sdev = hp->happy_dev;
|
||||
int rng;
|
||||
|
||||
for (rng = 0; rng < qp->nranges; rng++) {
|
||||
struct linux_prom_ranges *rngp = &qp->ranges[rng];
|
||||
int reg;
|
||||
|
||||
for (reg = 0; reg < 5; reg++) {
|
||||
if (sdev->reg_addrs[reg].which_io ==
|
||||
rngp->ot_child_space)
|
||||
break;
|
||||
}
|
||||
if (reg == 5)
|
||||
continue;
|
||||
|
||||
sdev->reg_addrs[reg].which_io = rngp->ot_parent_space;
|
||||
sdev->reg_addrs[reg].phys_addr += rngp->ot_parent_base;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a happy meal sbus device, find it's quattro parent.
|
||||
* If none exist, allocate and return a new one.
|
||||
*
|
||||
* Return NULL on failure.
|
||||
*/
|
||||
static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev)
|
||||
static struct quattro * __devinit quattro_sbus_find(struct of_device *child)
|
||||
{
|
||||
struct sbus_dev *sdev;
|
||||
struct device *parent = child->dev.parent;
|
||||
struct of_device *op;
|
||||
struct quattro *qp;
|
||||
int i;
|
||||
|
||||
for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
|
||||
for (i = 0, sdev = qp->quattro_dev;
|
||||
(sdev != NULL) && (i < 4);
|
||||
sdev = sdev->next, i++) {
|
||||
if (sdev == goal_sdev)
|
||||
return qp;
|
||||
}
|
||||
}
|
||||
op = to_of_device(parent);
|
||||
qp = dev_get_drvdata(&op->dev);
|
||||
if (qp)
|
||||
return qp;
|
||||
|
||||
qp = kmalloc(sizeof(struct quattro), GFP_KERNEL);
|
||||
if (qp != NULL) {
|
||||
|
|
@ -2586,10 +2534,11 @@ static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev)
|
|||
for (i = 0; i < 4; i++)
|
||||
qp->happy_meals[i] = NULL;
|
||||
|
||||
qp->quattro_dev = goal_sdev;
|
||||
qp->quattro_dev = child;
|
||||
qp->next = qfe_sbus_list;
|
||||
qfe_sbus_list = qp;
|
||||
quattro_get_ranges(qp);
|
||||
|
||||
dev_set_drvdata(&op->dev, qp);
|
||||
}
|
||||
return qp;
|
||||
}
|
||||
|
|
@ -2602,10 +2551,10 @@ static void __init quattro_sbus_register_irqs(void)
|
|||
struct quattro *qp;
|
||||
|
||||
for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
|
||||
struct sbus_dev *sdev = qp->quattro_dev;
|
||||
struct of_device *op = qp->quattro_dev;
|
||||
int err;
|
||||
|
||||
err = request_irq(sdev->irqs[0],
|
||||
err = request_irq(op->irqs[0],
|
||||
quattro_sbus_interrupt,
|
||||
IRQF_SHARED, "Quattro",
|
||||
qp);
|
||||
|
|
@ -2621,9 +2570,9 @@ static void quattro_sbus_free_irqs(void)
|
|||
struct quattro *qp;
|
||||
|
||||
for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
|
||||
struct sbus_dev *sdev = qp->quattro_dev;
|
||||
struct of_device *op = qp->quattro_dev;
|
||||
|
||||
free_irq(sdev->irqs[0], qp);
|
||||
free_irq(op->irqs[0], qp);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SBUS */
|
||||
|
|
@ -2660,9 +2609,9 @@ static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev)
|
|||
#endif /* CONFIG_PCI */
|
||||
|
||||
#ifdef CONFIG_SBUS
|
||||
static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
|
||||
static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
|
||||
{
|
||||
struct device_node *dp = sdev->ofdev.node;
|
||||
struct device_node *dp = op->node, *sbus_dp;
|
||||
struct quattro *qp = NULL;
|
||||
struct happy_meal *hp;
|
||||
struct net_device *dev;
|
||||
|
|
@ -2671,7 +2620,7 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
|
|||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
if (is_qfe) {
|
||||
qp = quattro_sbus_find(sdev);
|
||||
qp = quattro_sbus_find(op);
|
||||
if (qp == NULL)
|
||||
goto err_out;
|
||||
for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
|
||||
|
|
@ -2685,7 +2634,7 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
|
|||
dev = alloc_etherdev(sizeof(struct happy_meal));
|
||||
if (!dev)
|
||||
goto err_out;
|
||||
SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
|
||||
SET_NETDEV_DEV(dev, &op->dev);
|
||||
|
||||
if (hme_version_printed++ == 0)
|
||||
printk(KERN_INFO "%s", version);
|
||||
|
|
@ -2713,56 +2662,50 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
|
|||
memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
|
||||
}
|
||||
|
||||
hp = dev->priv;
|
||||
hp = netdev_priv(dev);
|
||||
|
||||
hp->happy_dev = sdev;
|
||||
hp->happy_dev = op;
|
||||
hp->dma_dev = &op->dev;
|
||||
|
||||
spin_lock_init(&hp->happy_lock);
|
||||
|
||||
err = -ENODEV;
|
||||
if (sdev->num_registers != 5) {
|
||||
printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n",
|
||||
sdev->num_registers);
|
||||
goto err_out_free_netdev;
|
||||
}
|
||||
|
||||
if (qp != NULL) {
|
||||
hp->qfe_parent = qp;
|
||||
hp->qfe_ent = qfe_slot;
|
||||
qp->happy_meals[qfe_slot] = dev;
|
||||
quattro_apply_ranges(qp, hp);
|
||||
}
|
||||
|
||||
hp->gregs = sbus_ioremap(&sdev->resource[0], 0,
|
||||
GREG_REG_SIZE, "HME Global Regs");
|
||||
hp->gregs = of_ioremap(&op->resource[0], 0,
|
||||
GREG_REG_SIZE, "HME Global Regs");
|
||||
if (!hp->gregs) {
|
||||
printk(KERN_ERR "happymeal: Cannot map global registers.\n");
|
||||
goto err_out_free_netdev;
|
||||
}
|
||||
|
||||
hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
|
||||
ETX_REG_SIZE, "HME TX Regs");
|
||||
hp->etxregs = of_ioremap(&op->resource[1], 0,
|
||||
ETX_REG_SIZE, "HME TX Regs");
|
||||
if (!hp->etxregs) {
|
||||
printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n");
|
||||
goto err_out_iounmap;
|
||||
}
|
||||
|
||||
hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
|
||||
ERX_REG_SIZE, "HME RX Regs");
|
||||
hp->erxregs = of_ioremap(&op->resource[2], 0,
|
||||
ERX_REG_SIZE, "HME RX Regs");
|
||||
if (!hp->erxregs) {
|
||||
printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n");
|
||||
goto err_out_iounmap;
|
||||
}
|
||||
|
||||
hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
|
||||
BMAC_REG_SIZE, "HME BIGMAC Regs");
|
||||
hp->bigmacregs = of_ioremap(&op->resource[3], 0,
|
||||
BMAC_REG_SIZE, "HME BIGMAC Regs");
|
||||
if (!hp->bigmacregs) {
|
||||
printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n");
|
||||
goto err_out_iounmap;
|
||||
}
|
||||
|
||||
hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
|
||||
TCVR_REG_SIZE, "HME Tranceiver Regs");
|
||||
hp->tcvregs = of_ioremap(&op->resource[4], 0,
|
||||
TCVR_REG_SIZE, "HME Tranceiver Regs");
|
||||
if (!hp->tcvregs) {
|
||||
printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n");
|
||||
goto err_out_iounmap;
|
||||
|
|
@ -2781,13 +2724,18 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
|
|||
if (qp != NULL)
|
||||
hp->happy_flags |= HFLAG_QUATTRO;
|
||||
|
||||
sbus_dp = to_of_device(op->dev.parent)->node;
|
||||
if (is_qfe)
|
||||
sbus_dp = to_of_device(op->dev.parent->parent)->node;
|
||||
|
||||
/* Get the supported DVMA burst sizes from our Happy SBUS. */
|
||||
hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node,
|
||||
hp->happy_bursts = of_getintprop_default(sbus_dp,
|
||||
"burst-sizes", 0x00);
|
||||
|
||||
hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
|
||||
PAGE_SIZE,
|
||||
&hp->hblock_dvma);
|
||||
hp->happy_block = dma_alloc_coherent(hp->dma_dev,
|
||||
PAGE_SIZE,
|
||||
&hp->hblock_dvma,
|
||||
GFP_ATOMIC);
|
||||
err = -ENOMEM;
|
||||
if (!hp->happy_block) {
|
||||
printk(KERN_ERR "happymeal: Cannot allocate descriptors.\n");
|
||||
|
|
@ -2816,19 +2764,13 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
|
|||
/* Happy Meal can do it all... */
|
||||
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
|
||||
|
||||
dev->irq = sdev->irqs[0];
|
||||
dev->irq = op->irqs[0];
|
||||
|
||||
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
|
||||
/* Hook up PCI register/dma accessors. */
|
||||
/* Hook up SBUS register/descriptor accessors. */
|
||||
hp->read_desc32 = sbus_hme_read_desc32;
|
||||
hp->write_txd = sbus_hme_write_txd;
|
||||
hp->write_rxd = sbus_hme_write_rxd;
|
||||
hp->dma_map = (u32 (*)(void *, void *, long, int))sbus_map_single;
|
||||
hp->dma_unmap = (void (*)(void *, u32, long, int))sbus_unmap_single;
|
||||
hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int))
|
||||
sbus_dma_sync_single_for_cpu;
|
||||
hp->dma_sync_for_device = (void (*)(void *, u32, long, int))
|
||||
sbus_dma_sync_single_for_device;
|
||||
hp->read32 = sbus_hme_read32;
|
||||
hp->write32 = sbus_hme_write32;
|
||||
#endif
|
||||
|
|
@ -2843,10 +2785,10 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
|
|||
if (register_netdev(hp->dev)) {
|
||||
printk(KERN_ERR "happymeal: Cannot register net device, "
|
||||
"aborting.\n");
|
||||
goto err_out_free_consistent;
|
||||
goto err_out_free_coherent;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&sdev->ofdev.dev, hp);
|
||||
dev_set_drvdata(&op->dev, hp);
|
||||
|
||||
if (qfe_slot != -1)
|
||||
printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
|
||||
|
|
@ -2859,23 +2801,23 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe
|
|||
|
||||
return 0;
|
||||
|
||||
err_out_free_consistent:
|
||||
sbus_free_consistent(hp->happy_dev,
|
||||
PAGE_SIZE,
|
||||
hp->happy_block,
|
||||
hp->hblock_dvma);
|
||||
err_out_free_coherent:
|
||||
dma_free_coherent(hp->dma_dev,
|
||||
PAGE_SIZE,
|
||||
hp->happy_block,
|
||||
hp->hblock_dvma);
|
||||
|
||||
err_out_iounmap:
|
||||
if (hp->gregs)
|
||||
sbus_iounmap(hp->gregs, GREG_REG_SIZE);
|
||||
of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
|
||||
if (hp->etxregs)
|
||||
sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
|
||||
of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
|
||||
if (hp->erxregs)
|
||||
sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
|
||||
of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
|
||||
if (hp->bigmacregs)
|
||||
sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
|
||||
of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
|
||||
if (hp->tcvregs)
|
||||
sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
|
||||
of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
|
||||
|
||||
err_out_free_netdev:
|
||||
free_netdev(dev);
|
||||
|
|
@ -3035,6 +2977,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
|
|||
memset(hp, 0, sizeof(*hp));
|
||||
|
||||
hp->happy_dev = pdev;
|
||||
hp->dma_dev = &pdev->dev;
|
||||
|
||||
spin_lock_init(&hp->happy_lock);
|
||||
|
||||
|
|
@ -3121,7 +3064,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
|
|||
#endif
|
||||
|
||||
hp->happy_block = (struct hmeal_init_block *)
|
||||
pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma);
|
||||
dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &hp->hblock_dvma, GFP_KERNEL);
|
||||
|
||||
err = -ENODEV;
|
||||
if (!hp->happy_block) {
|
||||
|
|
@ -3151,16 +3094,10 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
|
|||
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
|
||||
|
||||
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
|
||||
/* Hook up PCI register/dma accessors. */
|
||||
/* Hook up PCI register/descriptor accessors. */
|
||||
hp->read_desc32 = pci_hme_read_desc32;
|
||||
hp->write_txd = pci_hme_write_txd;
|
||||
hp->write_rxd = pci_hme_write_rxd;
|
||||
hp->dma_map = (u32 (*)(void *, void *, long, int))pci_map_single;
|
||||
hp->dma_unmap = (void (*)(void *, u32, long, int))pci_unmap_single;
|
||||
hp->dma_sync_for_cpu = (void (*)(void *, u32, long, int))
|
||||
pci_dma_sync_single_for_cpu;
|
||||
hp->dma_sync_for_device = (void (*)(void *, u32, long, int))
|
||||
pci_dma_sync_single_for_device;
|
||||
hp->read32 = pci_hme_read32;
|
||||
hp->write32 = pci_hme_write32;
|
||||
#endif
|
||||
|
|
@ -3231,10 +3168,8 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
|
|||
|
||||
unregister_netdev(net_dev);
|
||||
|
||||
pci_free_consistent(hp->happy_dev,
|
||||
PAGE_SIZE,
|
||||
hp->happy_block,
|
||||
hp->hblock_dvma);
|
||||
dma_free_coherent(hp->dma_dev, PAGE_SIZE,
|
||||
hp->happy_block, hp->hblock_dvma);
|
||||
iounmap(hp->gregs);
|
||||
pci_release_regions(hp->happy_dev);
|
||||
|
||||
|
|
@ -3279,46 +3214,45 @@ static void happy_meal_pci_exit(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_SBUS
|
||||
static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match)
|
||||
static int __devinit hme_sbus_probe(struct of_device *op, const struct of_device_id *match)
|
||||
{
|
||||
struct sbus_dev *sdev = to_sbus_device(&dev->dev);
|
||||
struct device_node *dp = dev->node;
|
||||
struct device_node *dp = op->node;
|
||||
const char *model = of_get_property(dp, "model", NULL);
|
||||
int is_qfe = (match->data != NULL);
|
||||
|
||||
if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe"))
|
||||
is_qfe = 1;
|
||||
|
||||
return happy_meal_sbus_probe_one(sdev, is_qfe);
|
||||
return happy_meal_sbus_probe_one(op, is_qfe);
|
||||
}
|
||||
|
||||
static int __devexit hme_sbus_remove(struct of_device *dev)
|
||||
static int __devexit hme_sbus_remove(struct of_device *op)
|
||||
{
|
||||
struct happy_meal *hp = dev_get_drvdata(&dev->dev);
|
||||
struct happy_meal *hp = dev_get_drvdata(&op->dev);
|
||||
struct net_device *net_dev = hp->dev;
|
||||
|
||||
unregister_netdev(net_dev);
|
||||
|
||||
/* XXX qfe parent interrupt... */
|
||||
|
||||
sbus_iounmap(hp->gregs, GREG_REG_SIZE);
|
||||
sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
|
||||
sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
|
||||
sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
|
||||
sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
|
||||
sbus_free_consistent(hp->happy_dev,
|
||||
PAGE_SIZE,
|
||||
hp->happy_block,
|
||||
hp->hblock_dvma);
|
||||
of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
|
||||
of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
|
||||
of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
|
||||
of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
|
||||
of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
|
||||
dma_free_coherent(hp->dma_dev,
|
||||
PAGE_SIZE,
|
||||
hp->happy_block,
|
||||
hp->hblock_dvma);
|
||||
|
||||
free_netdev(net_dev);
|
||||
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id hme_sbus_match[] = {
|
||||
static const struct of_device_id hme_sbus_match[] = {
|
||||
{
|
||||
.name = "SUNW,hme",
|
||||
},
|
||||
|
|
@ -3346,7 +3280,7 @@ static int __init happy_meal_sbus_init(void)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = of_register_driver(&hme_sbus_driver, &sbus_bus_type);
|
||||
err = of_register_driver(&hme_sbus_driver, &of_bus_type);
|
||||
if (!err)
|
||||
quattro_sbus_register_irqs();
|
||||
|
||||
|
|
|
|||
|
|
@ -405,14 +405,11 @@ struct happy_meal {
|
|||
u32 (*read_desc32)(hme32 *);
|
||||
void (*write_txd)(struct happy_meal_txd *, u32, u32);
|
||||
void (*write_rxd)(struct happy_meal_rxd *, u32, u32);
|
||||
u32 (*dma_map)(void *, void *, long, int);
|
||||
void (*dma_unmap)(void *, u32, long, int);
|
||||
void (*dma_sync_for_cpu)(void *, u32, long, int);
|
||||
void (*dma_sync_for_device)(void *, u32, long, int);
|
||||
#endif
|
||||
|
||||
/* This is either a sbus_dev or a pci_dev. */
|
||||
/* This is either an of_device or a pci_dev. */
|
||||
void *happy_dev;
|
||||
struct device *dma_dev;
|
||||
|
||||
spinlock_t happy_lock;
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ static char lancestr[] = "LANCE";
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
|
|
@ -98,7 +101,6 @@ static char lancestr[] = "LANCE";
|
|||
#include <asm/pgtable.h>
|
||||
#include <asm/byteorder.h> /* Used by the checksum routines */
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/auxio.h> /* For tpe-link-test? setting */
|
||||
#include <asm/irq.h>
|
||||
|
|
@ -248,7 +250,7 @@ struct lance_private {
|
|||
int rx_new, tx_new;
|
||||
int rx_old, tx_old;
|
||||
|
||||
struct sbus_dma *ledma; /* If set this points to ledma */
|
||||
struct of_device *ledma; /* If set this points to ledma */
|
||||
char tpe; /* cable-selection is TPE */
|
||||
char auto_select; /* cable-selection by carrier */
|
||||
char burst_sizes; /* ledma SBus burst sizes */
|
||||
|
|
@ -263,7 +265,8 @@ struct lance_private {
|
|||
char *name;
|
||||
dma_addr_t init_block_dvma;
|
||||
struct net_device *dev; /* Backpointer */
|
||||
struct sbus_dev *sdev;
|
||||
struct of_device *op;
|
||||
struct of_device *lebuffer;
|
||||
struct timer_list multicast_timer;
|
||||
};
|
||||
|
||||
|
|
@ -1272,27 +1275,29 @@ static void lance_set_multicast_retry(unsigned long _opaque)
|
|||
static void lance_free_hwresources(struct lance_private *lp)
|
||||
{
|
||||
if (lp->lregs)
|
||||
sbus_iounmap(lp->lregs, LANCE_REG_SIZE);
|
||||
of_iounmap(&lp->op->resource[0], lp->lregs, LANCE_REG_SIZE);
|
||||
if (lp->dregs) {
|
||||
struct of_device *ledma = lp->ledma;
|
||||
|
||||
of_iounmap(&ledma->resource[0], lp->dregs,
|
||||
resource_size(&ledma->resource[0]));
|
||||
}
|
||||
if (lp->init_block_iomem) {
|
||||
sbus_iounmap(lp->init_block_iomem,
|
||||
sizeof(struct lance_init_block));
|
||||
of_iounmap(&lp->lebuffer->resource[0], lp->init_block_iomem,
|
||||
sizeof(struct lance_init_block));
|
||||
} else if (lp->init_block_mem) {
|
||||
sbus_free_consistent(lp->sdev,
|
||||
sizeof(struct lance_init_block),
|
||||
lp->init_block_mem,
|
||||
lp->init_block_dvma);
|
||||
dma_free_coherent(&lp->op->dev,
|
||||
sizeof(struct lance_init_block),
|
||||
lp->init_block_mem,
|
||||
lp->init_block_dvma);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ethtool support... */
|
||||
static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct lance_private *lp = netdev_priv(dev);
|
||||
|
||||
strcpy(info->driver, "sunlance");
|
||||
strcpy(info->version, "2.02");
|
||||
sprintf(info->bus_info, "SBUS:%d",
|
||||
lp->sdev->slot);
|
||||
}
|
||||
|
||||
static u32 sparc_lance_get_link(struct net_device *dev)
|
||||
|
|
@ -1308,16 +1313,16 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = {
|
|||
.get_link = sparc_lance_get_link,
|
||||
};
|
||||
|
||||
static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
|
||||
struct sbus_dma *ledma,
|
||||
struct sbus_dev *lebuffer)
|
||||
static int __devinit sparc_lance_probe_one(struct of_device *op,
|
||||
struct of_device *ledma,
|
||||
struct of_device *lebuffer)
|
||||
{
|
||||
struct device_node *dp = op->node;
|
||||
static unsigned version_printed;
|
||||
struct device_node *dp = sdev->ofdev.node;
|
||||
struct net_device *dev;
|
||||
struct lance_private *lp;
|
||||
int i;
|
||||
struct net_device *dev;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
int i;
|
||||
|
||||
dev = alloc_etherdev(sizeof(struct lance_private) + 8);
|
||||
if (!dev)
|
||||
|
|
@ -1338,14 +1343,27 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
|
|||
dev->dev_addr[i] = idprom->id_ethaddr[i];
|
||||
|
||||
/* Get the IO region */
|
||||
lp->lregs = sbus_ioremap(&sdev->resource[0], 0,
|
||||
LANCE_REG_SIZE, lancestr);
|
||||
lp->lregs = of_ioremap(&op->resource[0], 0,
|
||||
LANCE_REG_SIZE, lancestr);
|
||||
if (!lp->lregs) {
|
||||
printk(KERN_ERR "SunLance: Cannot map registers.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
lp->sdev = sdev;
|
||||
lp->ledma = ledma;
|
||||
if (lp->ledma) {
|
||||
lp->dregs = of_ioremap(&ledma->resource[0], 0,
|
||||
resource_size(&ledma->resource[0]),
|
||||
"ledma");
|
||||
if (!lp->dregs) {
|
||||
printk(KERN_ERR "SunLance: Cannot map "
|
||||
"ledma registers.\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
lp->op = op;
|
||||
lp->lebuffer = lebuffer;
|
||||
if (lebuffer) {
|
||||
/* sanity check */
|
||||
if (lebuffer->resource[0].start & 7) {
|
||||
|
|
@ -1353,8 +1371,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
|
|||
goto fail;
|
||||
}
|
||||
lp->init_block_iomem =
|
||||
sbus_ioremap(&lebuffer->resource[0], 0,
|
||||
sizeof(struct lance_init_block), "lebuffer");
|
||||
of_ioremap(&lebuffer->resource[0], 0,
|
||||
sizeof(struct lance_init_block), "lebuffer");
|
||||
if (!lp->init_block_iomem) {
|
||||
printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
|
||||
goto fail;
|
||||
|
|
@ -1366,9 +1384,10 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
|
|||
lp->tx = lance_tx_pio;
|
||||
} else {
|
||||
lp->init_block_mem =
|
||||
sbus_alloc_consistent(sdev, sizeof(struct lance_init_block),
|
||||
&lp->init_block_dvma);
|
||||
if (!lp->init_block_mem || lp->init_block_dvma == 0) {
|
||||
dma_alloc_coherent(&op->dev,
|
||||
sizeof(struct lance_init_block),
|
||||
&lp->init_block_dvma, GFP_ATOMIC);
|
||||
if (!lp->init_block_mem) {
|
||||
printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -1383,13 +1402,13 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
|
|||
LE_C3_BCON));
|
||||
|
||||
lp->name = lancestr;
|
||||
lp->ledma = ledma;
|
||||
|
||||
lp->burst_sizes = 0;
|
||||
if (lp->ledma) {
|
||||
struct device_node *ledma_dp = ledma->sdev->ofdev.node;
|
||||
const char *prop;
|
||||
struct device_node *ledma_dp = ledma->node;
|
||||
struct device_node *sbus_dp;
|
||||
unsigned int sbmask;
|
||||
const char *prop;
|
||||
u32 csr;
|
||||
|
||||
/* Find burst-size property for ledma */
|
||||
|
|
@ -1397,7 +1416,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
|
|||
"burst-sizes", 0);
|
||||
|
||||
/* ledma may be capable of fast bursts, but sbus may not. */
|
||||
sbmask = of_getintprop_default(ledma_dp, "burst-sizes",
|
||||
sbus_dp = ledma_dp->parent;
|
||||
sbmask = of_getintprop_default(sbus_dp, "burst-sizes",
|
||||
DMA_BURSTBITS);
|
||||
lp->burst_sizes &= sbmask;
|
||||
|
||||
|
|
@ -1435,8 +1455,6 @@ no_link_test:
|
|||
lp->tpe = 1;
|
||||
}
|
||||
|
||||
lp->dregs = ledma->regs;
|
||||
|
||||
/* Reset ledma */
|
||||
csr = sbus_readl(lp->dregs + DMA_CSR);
|
||||
sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR);
|
||||
|
|
@ -1446,7 +1464,7 @@ no_link_test:
|
|||
lp->dregs = NULL;
|
||||
|
||||
lp->dev = dev;
|
||||
SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
|
||||
SET_NETDEV_DEV(dev, &op->dev);
|
||||
dev->open = &lance_open;
|
||||
dev->stop = &lance_close;
|
||||
dev->hard_start_xmit = &lance_start_xmit;
|
||||
|
|
@ -1455,9 +1473,7 @@ no_link_test:
|
|||
dev->set_multicast_list = &lance_set_multicast;
|
||||
dev->ethtool_ops = &sparc_lance_ethtool_ops;
|
||||
|
||||
dev->irq = sdev->irqs[0];
|
||||
|
||||
dev->dma = 0;
|
||||
dev->irq = op->irqs[0];
|
||||
|
||||
/* We cannot sleep if the chip is busy during a
|
||||
* multicast list update event, because such events
|
||||
|
|
@ -1473,7 +1489,7 @@ no_link_test:
|
|||
goto fail;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&sdev->ofdev.dev, lp);
|
||||
dev_set_drvdata(&op->dev, lp);
|
||||
|
||||
printk(KERN_INFO "%s: LANCE %s\n",
|
||||
dev->name, print_mac(mac, dev->dev_addr));
|
||||
|
|
@ -1486,80 +1502,25 @@ fail:
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* On 4m, find the associated dma for the lance chip */
|
||||
static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev)
|
||||
static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match)
|
||||
{
|
||||
struct sbus_dma *p;
|
||||
|
||||
for_each_dvma(p) {
|
||||
if (p->sdev == sdev)
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SUN4
|
||||
|
||||
#include <asm/sun4paddr.h>
|
||||
#include <asm/machines.h>
|
||||
|
||||
/* Find all the lance cards on the system and initialize them */
|
||||
static struct sbus_dev sun4_sdev;
|
||||
static int __devinit sparc_lance_init(void)
|
||||
{
|
||||
if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
|
||||
(idprom->id_machtype == (SM_SUN4|SM_4_470))) {
|
||||
memset(&sun4_sdev, 0, sizeof(struct sbus_dev));
|
||||
sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
|
||||
sun4_sdev.irqs[0] = 6;
|
||||
return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int __exit sunlance_sun4_remove(void)
|
||||
{
|
||||
struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
|
||||
struct net_device *net_dev = lp->dev;
|
||||
|
||||
unregister_netdev(net_dev);
|
||||
|
||||
lance_free_hwresources(lp);
|
||||
|
||||
free_netdev(net_dev);
|
||||
|
||||
dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_SUN4 */
|
||||
|
||||
static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
|
||||
{
|
||||
struct sbus_dev *sdev = to_sbus_device(&dev->dev);
|
||||
struct of_device *parent = to_of_device(op->dev.parent);
|
||||
struct device_node *parent_dp = parent->node;
|
||||
int err;
|
||||
|
||||
if (sdev->parent) {
|
||||
struct of_device *parent = &sdev->parent->ofdev;
|
||||
|
||||
if (!strcmp(parent->node->name, "ledma")) {
|
||||
struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev));
|
||||
|
||||
err = sparc_lance_probe_one(sdev, ledma, NULL);
|
||||
} else if (!strcmp(parent->node->name, "lebuffer")) {
|
||||
err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev));
|
||||
} else
|
||||
err = sparc_lance_probe_one(sdev, NULL, NULL);
|
||||
if (!strcmp(parent_dp->name, "ledma")) {
|
||||
err = sparc_lance_probe_one(op, parent, NULL);
|
||||
} else if (!strcmp(parent_dp->name, "lebuffer")) {
|
||||
err = sparc_lance_probe_one(op, NULL, parent);
|
||||
} else
|
||||
err = sparc_lance_probe_one(sdev, NULL, NULL);
|
||||
err = sparc_lance_probe_one(op, NULL, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit sunlance_sbus_remove(struct of_device *dev)
|
||||
static int __devexit sunlance_sbus_remove(struct of_device *op)
|
||||
{
|
||||
struct lance_private *lp = dev_get_drvdata(&dev->dev);
|
||||
struct lance_private *lp = dev_get_drvdata(&op->dev);
|
||||
struct net_device *net_dev = lp->dev;
|
||||
|
||||
unregister_netdev(net_dev);
|
||||
|
|
@ -1568,12 +1529,12 @@ static int __devexit sunlance_sbus_remove(struct of_device *dev)
|
|||
|
||||
free_netdev(net_dev);
|
||||
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id sunlance_sbus_match[] = {
|
||||
static const struct of_device_id sunlance_sbus_match[] = {
|
||||
{
|
||||
.name = "le",
|
||||
},
|
||||
|
|
@ -1593,17 +1554,12 @@ static struct of_platform_driver sunlance_sbus_driver = {
|
|||
/* Find all the lance cards on the system and initialize them */
|
||||
static int __init sparc_lance_init(void)
|
||||
{
|
||||
return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type);
|
||||
return of_register_driver(&sunlance_sbus_driver, &of_bus_type);
|
||||
}
|
||||
#endif /* !CONFIG_SUN4 */
|
||||
|
||||
static void __exit sparc_lance_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_SUN4
|
||||
sunlance_sun4_remove();
|
||||
#else
|
||||
of_unregister_driver(&sunlance_sbus_driver);
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(sparc_lance_init);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* controller out there can be most efficiently programmed
|
||||
* if you make it look like a LANCE.
|
||||
*
|
||||
* Copyright (C) 1996, 1999, 2003, 2006 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1996, 1999, 2003, 2006, 2008 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -24,13 +24,15 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/sbus.h>
|
||||
#include <asm/openprom.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/auxio.h>
|
||||
|
|
@ -40,8 +42,8 @@
|
|||
#include "sunqe.h"
|
||||
|
||||
#define DRV_NAME "sunqe"
|
||||
#define DRV_VERSION "4.0"
|
||||
#define DRV_RELDATE "June 23, 2006"
|
||||
#define DRV_VERSION "4.1"
|
||||
#define DRV_RELDATE "August 27, 2008"
|
||||
#define DRV_AUTHOR "David S. Miller ([email protected])"
|
||||
|
||||
static char version[] =
|
||||
|
|
@ -690,12 +692,18 @@ static void qe_set_multicast(struct net_device *dev)
|
|||
/* Ethtool support... */
|
||||
static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
||||
{
|
||||
const struct linux_prom_registers *regs;
|
||||
struct sunqe *qep = dev->priv;
|
||||
struct of_device *op;
|
||||
|
||||
strcpy(info->driver, "sunqe");
|
||||
strcpy(info->version, "3.0");
|
||||
sprintf(info->bus_info, "SBUS:%d",
|
||||
qep->qe_sdev->slot);
|
||||
|
||||
op = qep->op;
|
||||
regs = of_get_property(op->node, "reg", NULL);
|
||||
if (regs)
|
||||
sprintf(info->bus_info, "SBUS:%d", regs->which_io);
|
||||
|
||||
}
|
||||
|
||||
static u32 qe_get_link(struct net_device *dev)
|
||||
|
|
@ -717,11 +725,11 @@ static const struct ethtool_ops qe_ethtool_ops = {
|
|||
};
|
||||
|
||||
/* This is only called once at boot time for each card probed. */
|
||||
static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
|
||||
static void qec_init_once(struct sunqec *qecp, struct of_device *op)
|
||||
{
|
||||
u8 bsizes = qecp->qec_bursts;
|
||||
|
||||
if (sbus_can_burst64(qsdev) && (bsizes & DMA_BURST64)) {
|
||||
if (sbus_can_burst64() && (bsizes & DMA_BURST64)) {
|
||||
sbus_writel(GLOB_CTRL_B64, qecp->gregs + GLOB_CTRL);
|
||||
} else if (bsizes & DMA_BURST32) {
|
||||
sbus_writel(GLOB_CTRL_B32, qecp->gregs + GLOB_CTRL);
|
||||
|
|
@ -735,15 +743,15 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
|
|||
sbus_writel(GLOB_PSIZE_2048, qecp->gregs + GLOB_PSIZE);
|
||||
|
||||
/* Set the local memsize register, divided up to one piece per QE channel. */
|
||||
sbus_writel((qsdev->reg_addrs[1].reg_size >> 2),
|
||||
sbus_writel((resource_size(&op->resource[1]) >> 2),
|
||||
qecp->gregs + GLOB_MSIZE);
|
||||
|
||||
/* Divide up the local QEC memory amongst the 4 QE receiver and
|
||||
* transmitter FIFOs. Basically it is (total / 2 / num_channels).
|
||||
*/
|
||||
sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1,
|
||||
sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1,
|
||||
qecp->gregs + GLOB_TSIZE);
|
||||
sbus_writel((qsdev->reg_addrs[1].reg_size >> 2) >> 1,
|
||||
sbus_writel((resource_size(&op->resource[1]) >> 2) >> 1,
|
||||
qecp->gregs + GLOB_RSIZE);
|
||||
}
|
||||
|
||||
|
|
@ -767,24 +775,21 @@ static u8 __devinit qec_get_burst(struct device_node *dp)
|
|||
return bsizes;
|
||||
}
|
||||
|
||||
static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev)
|
||||
static struct sunqec * __devinit get_qec(struct of_device *child)
|
||||
{
|
||||
struct sbus_dev *qec_sdev = child_sdev->parent;
|
||||
struct of_device *op = to_of_device(child->dev.parent);
|
||||
struct sunqec *qecp;
|
||||
|
||||
for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) {
|
||||
if (qecp->qec_sdev == qec_sdev)
|
||||
break;
|
||||
}
|
||||
qecp = dev_get_drvdata(&op->dev);
|
||||
if (!qecp) {
|
||||
qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL);
|
||||
if (qecp) {
|
||||
u32 ctrl;
|
||||
|
||||
qecp->qec_sdev = qec_sdev;
|
||||
qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0,
|
||||
GLOB_REG_SIZE,
|
||||
"QEC Global Registers");
|
||||
qecp->op = op;
|
||||
qecp->gregs = of_ioremap(&op->resource[0], 0,
|
||||
GLOB_REG_SIZE,
|
||||
"QEC Global Registers");
|
||||
if (!qecp->gregs)
|
||||
goto fail;
|
||||
|
||||
|
|
@ -799,16 +804,18 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev)
|
|||
if (qec_global_reset(qecp->gregs))
|
||||
goto fail;
|
||||
|
||||
qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node);
|
||||
qecp->qec_bursts = qec_get_burst(op->node);
|
||||
|
||||
qec_init_once(qecp, qec_sdev);
|
||||
qec_init_once(qecp, op);
|
||||
|
||||
if (request_irq(qec_sdev->irqs[0], &qec_interrupt,
|
||||
if (request_irq(op->irqs[0], &qec_interrupt,
|
||||
IRQF_SHARED, "qec", (void *) qecp)) {
|
||||
printk(KERN_ERR "qec: Can't register irq.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&op->dev, qecp);
|
||||
|
||||
qecp->next_module = root_qec_dev;
|
||||
root_qec_dev = qecp;
|
||||
}
|
||||
|
|
@ -818,17 +825,17 @@ static struct sunqec * __devinit get_qec(struct sbus_dev *child_sdev)
|
|||
|
||||
fail:
|
||||
if (qecp->gregs)
|
||||
sbus_iounmap(qecp->gregs, GLOB_REG_SIZE);
|
||||
of_iounmap(&op->resource[0], qecp->gregs, GLOB_REG_SIZE);
|
||||
kfree(qecp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __devinit qec_ether_init(struct sbus_dev *sdev)
|
||||
static int __devinit qec_ether_init(struct of_device *op)
|
||||
{
|
||||
static unsigned version_printed;
|
||||
struct net_device *dev;
|
||||
struct sunqe *qe;
|
||||
struct sunqec *qecp;
|
||||
struct sunqe *qe;
|
||||
int i, res;
|
||||
|
||||
if (version_printed++ == 0)
|
||||
|
|
@ -842,49 +849,42 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
|
|||
|
||||
qe = netdev_priv(dev);
|
||||
|
||||
i = of_getintprop_default(sdev->ofdev.node, "channel#", -1);
|
||||
if (i == -1) {
|
||||
struct sbus_dev *td = sdev->parent->child;
|
||||
i = 0;
|
||||
while (td != sdev) {
|
||||
td = td->next;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
res = -ENODEV;
|
||||
|
||||
i = of_getintprop_default(op->node, "channel#", -1);
|
||||
if (i == -1)
|
||||
goto fail;
|
||||
qe->channel = i;
|
||||
spin_lock_init(&qe->lock);
|
||||
|
||||
res = -ENODEV;
|
||||
qecp = get_qec(sdev);
|
||||
qecp = get_qec(op);
|
||||
if (!qecp)
|
||||
goto fail;
|
||||
|
||||
qecp->qes[qe->channel] = qe;
|
||||
qe->dev = dev;
|
||||
qe->parent = qecp;
|
||||
qe->qe_sdev = sdev;
|
||||
qe->op = op;
|
||||
|
||||
res = -ENOMEM;
|
||||
qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0,
|
||||
CREG_REG_SIZE, "QEC Channel Registers");
|
||||
qe->qcregs = of_ioremap(&op->resource[0], 0,
|
||||
CREG_REG_SIZE, "QEC Channel Registers");
|
||||
if (!qe->qcregs) {
|
||||
printk(KERN_ERR "qe: Cannot map channel registers.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0,
|
||||
MREGS_REG_SIZE, "QE MACE Registers");
|
||||
qe->mregs = of_ioremap(&op->resource[1], 0,
|
||||
MREGS_REG_SIZE, "QE MACE Registers");
|
||||
if (!qe->mregs) {
|
||||
printk(KERN_ERR "qe: Cannot map MACE registers.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
qe->qe_block = sbus_alloc_consistent(qe->qe_sdev,
|
||||
PAGE_SIZE,
|
||||
&qe->qblock_dvma);
|
||||
qe->buffers = sbus_alloc_consistent(qe->qe_sdev,
|
||||
sizeof(struct sunqe_buffers),
|
||||
&qe->buffers_dvma);
|
||||
qe->qe_block = dma_alloc_coherent(&op->dev, PAGE_SIZE,
|
||||
&qe->qblock_dvma, GFP_ATOMIC);
|
||||
qe->buffers = dma_alloc_coherent(&op->dev, sizeof(struct sunqe_buffers),
|
||||
&qe->buffers_dvma, GFP_ATOMIC);
|
||||
if (qe->qe_block == NULL || qe->qblock_dvma == 0 ||
|
||||
qe->buffers == NULL || qe->buffers_dvma == 0)
|
||||
goto fail;
|
||||
|
|
@ -892,7 +892,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
|
|||
/* Stop this QE. */
|
||||
qe_stop(qe);
|
||||
|
||||
SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
|
||||
SET_NETDEV_DEV(dev, &op->dev);
|
||||
|
||||
dev->open = qe_open;
|
||||
dev->stop = qe_close;
|
||||
|
|
@ -900,7 +900,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
|
|||
dev->set_multicast_list = qe_set_multicast;
|
||||
dev->tx_timeout = qe_tx_timeout;
|
||||
dev->watchdog_timeo = 5*HZ;
|
||||
dev->irq = sdev->irqs[0];
|
||||
dev->irq = op->irqs[0];
|
||||
dev->dma = 0;
|
||||
dev->ethtool_ops = &qe_ethtool_ops;
|
||||
|
||||
|
|
@ -908,7 +908,7 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
|
|||
if (res)
|
||||
goto fail;
|
||||
|
||||
dev_set_drvdata(&sdev->ofdev.dev, qe);
|
||||
dev_set_drvdata(&op->dev, qe);
|
||||
|
||||
printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel);
|
||||
for (i = 0; i < 6; i++)
|
||||
|
|
@ -922,58 +922,50 @@ static int __devinit qec_ether_init(struct sbus_dev *sdev)
|
|||
|
||||
fail:
|
||||
if (qe->qcregs)
|
||||
sbus_iounmap(qe->qcregs, CREG_REG_SIZE);
|
||||
of_iounmap(&op->resource[0], qe->qcregs, CREG_REG_SIZE);
|
||||
if (qe->mregs)
|
||||
sbus_iounmap(qe->mregs, MREGS_REG_SIZE);
|
||||
of_iounmap(&op->resource[1], qe->mregs, MREGS_REG_SIZE);
|
||||
if (qe->qe_block)
|
||||
sbus_free_consistent(qe->qe_sdev,
|
||||
PAGE_SIZE,
|
||||
qe->qe_block,
|
||||
qe->qblock_dvma);
|
||||
dma_free_coherent(&op->dev, PAGE_SIZE,
|
||||
qe->qe_block, qe->qblock_dvma);
|
||||
if (qe->buffers)
|
||||
sbus_free_consistent(qe->qe_sdev,
|
||||
sizeof(struct sunqe_buffers),
|
||||
qe->buffers,
|
||||
qe->buffers_dvma);
|
||||
dma_free_coherent(&op->dev,
|
||||
sizeof(struct sunqe_buffers),
|
||||
qe->buffers,
|
||||
qe->buffers_dvma);
|
||||
|
||||
free_netdev(dev);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int __devinit qec_sbus_probe(struct of_device *dev, const struct of_device_id *match)
|
||||
static int __devinit qec_sbus_probe(struct of_device *op, const struct of_device_id *match)
|
||||
{
|
||||
struct sbus_dev *sdev = to_sbus_device(&dev->dev);
|
||||
|
||||
return qec_ether_init(sdev);
|
||||
return qec_ether_init(op);
|
||||
}
|
||||
|
||||
static int __devexit qec_sbus_remove(struct of_device *dev)
|
||||
static int __devexit qec_sbus_remove(struct of_device *op)
|
||||
{
|
||||
struct sunqe *qp = dev_get_drvdata(&dev->dev);
|
||||
struct sunqe *qp = dev_get_drvdata(&op->dev);
|
||||
struct net_device *net_dev = qp->dev;
|
||||
|
||||
unregister_netdev(net_dev);
|
||||
|
||||
sbus_iounmap(qp->qcregs, CREG_REG_SIZE);
|
||||
sbus_iounmap(qp->mregs, MREGS_REG_SIZE);
|
||||
sbus_free_consistent(qp->qe_sdev,
|
||||
PAGE_SIZE,
|
||||
qp->qe_block,
|
||||
qp->qblock_dvma);
|
||||
sbus_free_consistent(qp->qe_sdev,
|
||||
sizeof(struct sunqe_buffers),
|
||||
qp->buffers,
|
||||
qp->buffers_dvma);
|
||||
of_iounmap(&op->resource[0], qp->qcregs, CREG_REG_SIZE);
|
||||
of_iounmap(&op->resource[1], qp->mregs, MREGS_REG_SIZE);
|
||||
dma_free_coherent(&op->dev, PAGE_SIZE,
|
||||
qp->qe_block, qp->qblock_dvma);
|
||||
dma_free_coherent(&op->dev, sizeof(struct sunqe_buffers),
|
||||
qp->buffers, qp->buffers_dvma);
|
||||
|
||||
free_netdev(net_dev);
|
||||
|
||||
dev_set_drvdata(&dev->dev, NULL);
|
||||
dev_set_drvdata(&op->dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id qec_sbus_match[] = {
|
||||
static const struct of_device_id qec_sbus_match[] = {
|
||||
{
|
||||
.name = "qe",
|
||||
},
|
||||
|
|
@ -991,7 +983,7 @@ static struct of_platform_driver qec_sbus_driver = {
|
|||
|
||||
static int __init qec_init(void)
|
||||
{
|
||||
return of_register_driver(&qec_sbus_driver, &sbus_bus_type);
|
||||
return of_register_driver(&qec_sbus_driver, &of_bus_type);
|
||||
}
|
||||
|
||||
static void __exit qec_exit(void)
|
||||
|
|
@ -1000,11 +992,11 @@ static void __exit qec_exit(void)
|
|||
|
||||
while (root_qec_dev) {
|
||||
struct sunqec *next = root_qec_dev->next_module;
|
||||
struct of_device *op = root_qec_dev->op;
|
||||
|
||||
free_irq(root_qec_dev->qec_sdev->irqs[0],
|
||||
(void *) root_qec_dev);
|
||||
sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE);
|
||||
|
||||
free_irq(op->irqs[0], (void *) root_qec_dev);
|
||||
of_iounmap(&op->resource[0], root_qec_dev->gregs,
|
||||
GLOB_REG_SIZE);
|
||||
kfree(root_qec_dev);
|
||||
|
||||
root_qec_dev = next;
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ struct sunqec {
|
|||
void __iomem *gregs; /* QEC Global Registers */
|
||||
struct sunqe *qes[4]; /* Each child MACE */
|
||||
unsigned int qec_bursts; /* Support burst sizes */
|
||||
struct sbus_dev *qec_sdev; /* QEC's SBUS device */
|
||||
struct of_device *op; /* QEC's OF device */
|
||||
struct sunqec *next_module; /* List of all QECs in system */
|
||||
};
|
||||
|
||||
|
|
@ -342,7 +342,7 @@ struct sunqe {
|
|||
__u32 buffers_dvma; /* DVMA visible address. */
|
||||
struct sunqec *parent;
|
||||
u8 mconfig; /* Base MACE mconfig value */
|
||||
struct sbus_dev *qe_sdev; /* QE's SBUS device struct */
|
||||
struct of_device *op; /* QE's OF device struct */
|
||||
struct net_device *dev; /* QE's netdevice struct */
|
||||
int channel; /* Who am I? */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* sunvnet.c: Sun LDOM Virtual Network Driver.
|
||||
*
|
||||
* Copyright (C) 2007 David S. Miller <davem@davemloft.net>
|
||||
* Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -1260,7 +1260,7 @@ static int vnet_port_remove(struct vio_dev *vdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct vio_device_id vnet_port_match[] = {
|
||||
static const struct vio_device_id vnet_port_match[] = {
|
||||
{
|
||||
.type = "vnet-port",
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue