diff options
author | florian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-12-06 22:40:31 +0000 |
---|---|---|
committer | florian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-12-06 22:40:31 +0000 |
commit | c6ca447d981870459b98e76e358af12e9f90d89b (patch) | |
tree | 9e8b624c8c50ba04347c16cc2d85879efb93ae4d /target/linux/adm8668/patches-3.3/005-tulip_platform.patch | |
parent | 905be8bf46d188b6369d48ccdd3f6a18b84506b8 (diff) |
[adm8668] patch the tulip driver to accept a platform variant
Isolate the PCI specific parts and group them under CONFIG_TULIP_PCI
CONFIG_TULIP_PLATFORM can be enabled for a platform style Tulip driver.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34557 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/adm8668/patches-3.3/005-tulip_platform.patch')
-rw-r--r-- | target/linux/adm8668/patches-3.3/005-tulip_platform.patch | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/target/linux/adm8668/patches-3.3/005-tulip_platform.patch b/target/linux/adm8668/patches-3.3/005-tulip_platform.patch new file mode 100644 index 0000000000..c9aa5e5813 --- /dev/null +++ b/target/linux/adm8668/patches-3.3/005-tulip_platform.patch @@ -0,0 +1,451 @@ +--- a/drivers/net/ethernet/dec/tulip/Kconfig ++++ b/drivers/net/ethernet/dec/tulip/Kconfig +@@ -60,6 +60,14 @@ config TULIP_PCI + To compile this driver as a module, choose M here. The module will + be called tulip. + ++config TULIP_PLATFORM ++ tristate "DECchip Tulip (dc2114x) Platform support" ++ depends on HAS_IOMEM ++ select TULIP ++ select CRC32 ++ ---help--- ++ This driver is for the platform variant. ++ + config TULIP_MWI + bool "New bus configuration (EXPERIMENTAL)" + depends on TULIP_PCI && EXPERIMENTAL +--- a/drivers/net/ethernet/dec/tulip/tulip_core.c ++++ b/drivers/net/ethernet/dec/tulip/tulip_core.c +@@ -27,6 +27,8 @@ + #include <linux/init.h> + #include <linux/interrupt.h> + #include <linux/etherdevice.h> ++#include <linux/platform_device.h> ++#include <linux/platform_data/tulip.h> + #include <linux/delay.h> + #include <linux/mii.h> + #include <linux/crc32.h> +@@ -204,6 +206,9 @@ struct tulip_chip_table tulip_tbl[] = { + { "Conexant LANfinity", 256, 0x0001ebef, + HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task }, + ++ { "Infineon ADM8668", 256, 0x0001a451, ++ MC_HASH_ONLY | COMET_MAC_ADDR, tulip_timer, tulip_media_task, }, ++ + }; + + #ifdef CONFIG_TULIP_PCI +@@ -395,6 +400,7 @@ static void tulip_up(struct net_device * + i = 0; + if (tp->mtable == NULL) + goto media_picked; ++ + if (dev->if_port) { + int looking_for = tulip_media_cap[dev->if_port] & MediaIsMII ? 11 : + (dev->if_port == 12 ? 0 : dev->if_port); +@@ -488,6 +494,10 @@ media_picked: + iowrite32(ioread32(ioaddr + 0x88) | 1, ioaddr + 0x88); + dev->if_port = tp->mii_cnt ? 11 : 0; + tp->csr6 = 0x00040000; ++ } else if (tp->chip_id == ADM8668) { ++ /* Enable automatic Tx underrun recovery. */ ++ iowrite32(ioread32(ioaddr + 0x88) | 1, ioaddr + 0x88); ++ tp->csr6 = 0x00040000; + } else if (tp->chip_id == AX88140) { + tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100; + } else +@@ -657,6 +667,10 @@ static void tulip_init_ring(struct net_d + mapping = pci_map_single(tp->pdev, skb->data, + PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ mapping = dma_map_single(&tp->pldev->dev, skb->data, ++ PKT_BUF_SZ, DMA_FROM_DEVICE); ++#endif + tp->rx_buffers[i].mapping = mapping; + skb->dev = dev; /* Mark as being used by this device. */ + tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */ +@@ -694,6 +708,11 @@ tulip_start_xmit(struct sk_buff *skb, st + mapping = pci_map_single(tp->pdev, skb->data, + skb->len, PCI_DMA_TODEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ mapping = dma_map_single(&tp->pldev->dev, skb->data, ++ skb->len, ++ DMA_TO_DEVICE); ++#endif + tp->tx_buffers[entry].mapping = mapping; + tp->tx_ring[entry].buffer1 = cpu_to_le32(mapping); + +@@ -757,6 +776,11 @@ static void tulip_clean_tx_ring(struct t + tp->tx_buffers[entry].skb->len, + PCI_DMA_TODEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ dma_unmap_single(&tp->pldev->dev, tp->tx_buffers[entry].mapping, ++ tp->tx_buffers[entry].skb->len, ++ DMA_TO_DEVICE); ++#endif + + /* Free the original skb. */ + dev_kfree_skb_irq(tp->tx_buffers[entry].skb); +@@ -834,6 +858,10 @@ static void tulip_free_ring (struct net_ + pci_unmap_single(tp->pdev, mapping, PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ dma_unmap_single(&tp->pldev->dev, mapping, PKT_BUF_SZ, ++ DMA_FROM_DEVICE); ++#endif + dev_kfree_skb (skb); + } + } +@@ -846,6 +874,10 @@ static void tulip_free_ring (struct net_ + pci_unmap_single(tp->pdev, tp->tx_buffers[i].mapping, + skb->len, PCI_DMA_TODEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ dma_unmap_single(&tp->pldev->dev, tp->tx_buffers[i].mapping, ++ skb->len, DMA_TO_DEVICE); ++#endif + dev_kfree_skb (skb); + } + tp->tx_buffers[i].skb = NULL; +@@ -900,6 +932,9 @@ static void tulip_get_drvinfo(struct net + #ifdef CONFIG_TULIP_PCI + strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ strlcpy(info->bus_info, "platform", sizeof(info->bus_info)); ++#endif + } + + +@@ -915,6 +950,9 @@ static int tulip_ethtool_set_wol(struct + #ifdef CONFIG_TULIP_PCI + device_set_wakeup_enable(&tp->pdev->dev, tp->wolinfo.wolopts); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ device_set_wakeup_enable(&tp->pldev->dev, tp->wolinfo.wolopts); ++#endif + return 0; + } + +@@ -1193,9 +1231,9 @@ static void set_rx_mode(struct net_devic + + } + ++#ifdef CONFIG_TULIP_PCI + tp->tx_buffers[entry].skb = NULL; + tp->tx_buffers[entry].mapping = +-#ifdef CONFIG_TULIP_PCI + pci_map_single(tp->pdev, tp->setup_frame, + sizeof(tp->setup_frame), + PCI_DMA_TODEVICE); +@@ -1219,6 +1257,9 @@ static void set_rx_mode(struct net_devic + spin_unlock_irqrestore(&tp->lock, flags); + } + ++ if (tp->chip_id == ADM8668) ++ csr6 |= (1 << 9); /* force 100Mbps full duplex */ ++ + iowrite32(csr6, ioaddr + CSR6); + } + +@@ -1991,6 +2032,124 @@ static void __devexit tulip_remove_one ( + } + #endif /* CONFIG_TULIP_PCI */ + ++#ifdef CONFIG_TULIP_PLATFORM ++static int __devinit tulip_probe(struct platform_device *pdev) ++{ ++ struct tulip_private *tp; ++ struct tulip_platform_data *pdata; ++ struct net_device *dev; ++ struct resource *res; ++ void __iomem *ioaddr; ++ int irq; ++ ++ if (pdev->id < 0 || pdev->id >= MAX_UNITS) ++ return -EINVAL; ++ ++ if (!(res = platform_get_resource(pdev, IORESOURCE_IRQ, 0))) ++ return -ENODEV; ++ irq = res->start; ++ if (!(res = platform_get_resource(pdev, IORESOURCE_MEM, 0))) ++ return -ENODEV; ++ if (!(ioaddr = ioremap(res->start, res->end - res->start))) ++ return -ENODEV; ++ ++ pdata = pdev->dev.platform_data; ++ if (!pdata) ++ return -ENODEV; ++ ++ if (!(dev = alloc_etherdev(sizeof (*tp)))) ++ return -ENOMEM; ++ ++ /* setup net dev */ ++ dev->base_addr = (unsigned long)res->start; ++ dev->irq = irq; ++ SET_NETDEV_DEV(dev, &pdev->dev); ++ ++ /* tulip private struct */ ++ tp = netdev_priv(dev); ++ tp->dev = dev; ++ tp->base_addr = ioaddr; ++ tp->csr0 = 0; ++ tp->pldev = pdev; ++ tp->rx_ring = dma_alloc_coherent(&pdev->dev, ++ sizeof(struct tulip_rx_desc) * RX_RING_SIZE + ++ sizeof(struct tulip_tx_desc) * TX_RING_SIZE, ++ &tp->rx_ring_dma, GFP_KERNEL); ++ if (!tp->rx_ring) ++ return -ENODEV; ++ tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE); ++ tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE; ++ ++ tp->chip_id = pdata->chip_id; ++ tp->flags = tulip_tbl[tp->chip_id].flags; ++ ++ spin_lock_init(&tp->lock); ++ spin_lock_init(&tp->mii_lock); ++ ++ init_timer(&tp->timer); ++ tp->timer.data = (unsigned long)dev; ++ tp->timer.function = tulip_tbl[tp->chip_id].media_timer; ++ ++ INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task); ++ ++ /* Stop the chip's Tx and Rx processes. */ ++ tulip_stop_rxtx(tp); ++ ++ /* Clear the missed-packet counter. */ ++ ioread32(ioaddr + CSR8); ++ ++ if (!is_valid_ether_addr(pdata->mac)) { ++ dev_info(&pdev->dev, "generating random ethernet MAC\n"); ++ random_ether_addr(dev->dev_addr); ++ } else ++ memcpy(dev->dev_addr, pdata->mac, ETH_ALEN); ++ ++ /* The Tulip-specific entries in the device structure. */ ++ dev->netdev_ops = &tulip_netdev_ops; ++ dev->watchdog_timeo = TX_TIMEOUT; ++ netif_napi_add(dev, &tp->napi, tulip_poll, 16); ++ SET_ETHTOOL_OPS(dev, &ops); ++ ++ if (register_netdev(dev)) ++ goto err_out_free_ring; ++ ++ dev_info(&dev->dev, ++ "tulip_platform (%s) at MMIO %#lx %pM, IRQ %d\n", ++ tulip_tbl[tp->chip_id].chip_name, ++ (unsigned long)dev->base_addr, dev->dev_addr, irq); ++ ++ platform_set_drvdata(pdev, dev); ++ return 0; ++ ++err_out_free_ring: ++ dma_free_coherent(&pdev->dev, ++ sizeof (struct tulip_rx_desc) * RX_RING_SIZE + ++ sizeof (struct tulip_tx_desc) * TX_RING_SIZE, ++ tp->rx_ring, tp->rx_ring_dma); ++ return -ENODEV; ++} ++ ++static int __devexit tulip_remove(struct platform_device *pdev) ++{ ++ struct net_device *dev = platform_get_drvdata (pdev); ++ struct tulip_private *tp; ++ ++ if (!dev) ++ return -ENODEV; ++ ++ tp = netdev_priv(dev); ++ unregister_netdev(dev); ++ dma_free_coherent(&pdev->dev, ++ sizeof (struct tulip_rx_desc) * RX_RING_SIZE + ++ sizeof (struct tulip_tx_desc) * TX_RING_SIZE, ++ tp->rx_ring, tp->rx_ring_dma); ++ iounmap(tp->base_addr); ++ free_netdev(dev); ++ platform_set_drvdata(pdev, NULL); ++ return 0; ++} ++#endif ++ + #ifdef CONFIG_NET_POLL_CONTROLLER + /* + * Polling 'interrupt' - used by things like netconsole to send skbs +@@ -2021,6 +2180,17 @@ static struct pci_driver tulip_pci_drive + }; + #endif + ++#ifdef CONFIG_TULIP_PLATFORM ++static struct platform_driver tulip_platform_driver = { ++ .probe = tulip_probe, ++ .remove = __devexit_p(tulip_remove), ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = DRV_NAME, ++ }, ++}; ++#endif ++ + + static int __init tulip_init (void) + { +@@ -2037,6 +2207,9 @@ static int __init tulip_init (void) + #ifdef CONFIG_TULIP_PCI + ret = pci_register_driver(&tulip_pci_driver); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ ret = platform_driver_register(&tulip_platform_driver); ++#endif + return ret; + } + +@@ -2046,6 +2219,9 @@ static void __exit tulip_cleanup (void) + #ifdef CONFIG_TULIP_PCI + pci_unregister_driver (&tulip_pci_driver); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ platform_driver_unregister (&tulip_platform_driver); ++#endif + } + + +--- a/drivers/net/ethernet/dec/tulip/tulip.h ++++ b/drivers/net/ethernet/dec/tulip/tulip.h +@@ -21,6 +21,8 @@ + #include <linux/timer.h> + #include <linux/delay.h> + #include <linux/pci.h> ++#include <linux/platform_device.h> ++#include <linux/platform_data/tulip.h> + #include <asm/io.h> + #include <asm/irq.h> + #include <asm/unaligned.h> +@@ -69,28 +71,6 @@ enum tbl_flag { + }; + + +-/* chip types. careful! order is VERY IMPORTANT here, as these +- * are used throughout the driver as indices into arrays */ +-/* Note 21142 == 21143. */ +-enum chips { +- DC21040 = 0, +- DC21041 = 1, +- DC21140 = 2, +- DC21142 = 3, DC21143 = 3, +- LC82C168, +- MX98713, +- MX98715, +- MX98725, +- AX88140, +- PNIC2, +- COMET, +- COMPEX9881, +- I21145, +- DM910X, +- CONEXANT, +-}; +- +- + enum MediaIs { + MediaIsFD = 1, + MediaAlwaysFD = 2, +@@ -446,7 +426,12 @@ struct tulip_private { + struct mediatable *mtable; + int cur_index; /* Current media index. */ + int saved_if_port; ++#ifdef CONFIG_TULIP_PCI + struct pci_dev *pdev; ++#endif ++#ifdef CONFIG_TULIP_PLATFORM ++ struct platform_device *pldev; ++#endif + int ttimer; + int susp_rx; + unsigned long nir; +--- a/drivers/net/ethernet/dec/tulip/interrupt.c ++++ b/drivers/net/ethernet/dec/tulip/interrupt.c +@@ -76,6 +76,10 @@ int tulip_refill_rx(struct net_device *d + mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ mapping = dma_map_single(&tp->pldev->dev, skb->data, PKT_BUF_SZ, ++ DMA_FROM_DEVICE); ++#endif + tp->rx_buffers[entry].mapping = mapping; + + skb->dev = dev; /* Mark as being used by this device. */ +@@ -198,8 +202,7 @@ int tulip_poll(struct napi_struct *napi, + dev->stats.rx_fifo_errors++; + } + } else { +- struct sk_buff *skb; +- ++ struct sk_buff *skb; + /* Check if the packet is long enough to accept without copying + to a minimally-sized skbuff. */ + if (pkt_len < tulip_rx_copybreak && +@@ -242,6 +245,10 @@ int tulip_poll(struct napi_struct *napi, + pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping, + PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ dma_unmap_single(&tp->pldev->dev, tp->rx_buffers[entry].mapping, ++ PKT_BUF_SZ, DMA_FROM_DEVICE); ++#endif + + tp->rx_buffers[entry].skb = NULL; + tp->rx_buffers[entry].mapping = 0; +@@ -635,6 +642,11 @@ irqreturn_t tulip_interrupt(int irq, voi + tp->tx_buffers[entry].skb->len, + PCI_DMA_TODEVICE); + #endif ++#ifdef CONFIG_TULIP_PLATFORM ++ dma_unmap_single(&tp->pldev->dev, tp->tx_buffers[entry].mapping, ++ tp->tx_buffers[entry].skb->len, ++ DMA_TO_DEVICE); ++#endif + + /* Free the original skb. */ + dev_kfree_skb_irq(tp->tx_buffers[entry].skb); +--- /dev/null ++++ b/include/linux/platform_data/tulip.h +@@ -0,0 +1,31 @@ ++#ifndef _LINUX_TULIP_PDATA_H ++#define _LINUX_TULIP_PDATA_H ++ ++/* chip types. careful! order is VERY IMPORTANT here, as these ++ * are used throughout the driver as indices into arrays */ ++/* Note 21142 == 21143. */ ++enum chips { ++ DC21040 = 0, ++ DC21041 = 1, ++ DC21140 = 2, ++ DC21142 = 3, DC21143 = 3, ++ LC82C168, ++ MX98713, ++ MX98715, ++ MX98725, ++ AX88140, ++ PNIC2, ++ COMET, ++ COMPEX9881, ++ I21145, ++ DM910X, ++ CONEXANT, ++ ADM8668, ++}; ++ ++struct tulip_platform_data { ++ u8 mac[6]; ++ enum chips chip_id; ++}; ++ ++#endif |