*
* (C) Copyright TOSHIBA CORPORATION 2004-2005
* All Rights Reserved.
- *
- * Revision History:
- * 1.13 64-bit proof.
- * 1.14 Do not round-up transmit length.
- * 1.15 Define TC35815_DMA_SYNC_ONDEMAND, cleanup.
- * 1.16 Fix free_page bug introduced in 1.15
- * 1.17 Add mii/ethtool ioctl support.
- * Remove workaround for early TX4938. Cleanup.
- * 1.20 Kernel 2.6.
- * 1.21 Fix receive packet length (omit CRC).
- * Call netif_carrier_on/netif_carrier_off.
- * Add kernel/module options (speed, duplex, doforce).
- * Do not try "force link mode" by default.
- * Reconfigure CAM on restarting.
- * Reset PHY on restarting.
- * Add workaround for 100MHalf HUB.
- * 1.22 Minor fix.
- * 1.23 Minor cleanup.
- * 1.24 Remove tc35815_setup since new stype option
- * ("tc35815.speed=10", etc.) can be used for 2.6 kernel.
- * 1.25 TX4939 support.
- * 1.26 Minor cleanup.
- * 1.27 Move TX4939 PCFG.SPEEDn control code out from this driver.
- * Cleanup init_dev_addr. (NETDEV_REGISTER event notifier
- * can overwrite dev_addr)
- * support ETHTOOL_GPERMADDR.
- * 1.28 Minor cleanup.
- * 1.29 support netpoll.
- * 1.30 Minor cleanup.
- * 1.31 NAPI support. (disabled by default)
- * Use DMA_RxAlign_2 if possible.
- * Do not use PackedBuffer.
- * Cleanup.
- * 1.32 Fix free buffer management on non-PackedBuffer mode.
- * 1.33 Fix netpoll build.
- * 1.34 Fix netpoll locking. "BH rule" for NAPI is not enough with
- * netpoll, hard_start_xmit might be called from irq context.
- * PM support.
- * 1.35 Fix an usage of streaming DMA API.
*/
#ifdef TC35815_NAPI
-#define DRV_VERSION "1.35-NAPI"
+#define DRV_VERSION "1.36-NAPI"
#else
-#define DRV_VERSION "1.35"
+#define DRV_VERSION "1.36"
#endif
static const char *version = "tc35815.c:v" DRV_VERSION "\n";
#define MODNAME "tc35815"
#include <linux/pci.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/byteorder.h>
skb = dev_alloc_skb(RX_BUF_SIZE);
if (!skb)
return NULL;
- skb->dev = dev;
*dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(*dma_handle)) {
static void tc_mdio_write(struct net_device *dev, int phy_id, int location,
int val);
-static void __devinit tc35815_init_dev_addr (struct net_device *dev)
+#ifdef CONFIG_CPU_TX49XX
+/*
+ * Find a platform_device providing a MAC address. The platform code
+ * should provide a "tc35815-mac" device with a MAC address in its
+ * platform_data.
+ */
+static int __devinit tc35815_mac_match(struct device *dev, void *data)
+{
+ struct platform_device *plat_dev = to_platform_device(dev);
+ struct pci_dev *pci_dev = data;
+ unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn;
+ return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id;
+}
+
+static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
+{
+ struct tc35815_local *lp = dev->priv;
+ struct device *pd = bus_find_device(&platform_bus_type, NULL,
+ lp->pci_dev, tc35815_mac_match);
+ if (pd) {
+ if (pd->platform_data)
+ memcpy(dev->dev_addr, pd->platform_data, ETH_ALEN);
+ put_device(pd);
+ return is_valid_ether_addr(dev->dev_addr) ? 0 : -ENODEV;
+ }
+ return -ENODEV;
+}
+#else
+static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
+{
+ return -ENODEV;
+}
+#endif
+
+static int __devinit tc35815_init_dev_addr (struct net_device *dev)
{
struct tc35815_regs __iomem *tr =
(struct tc35815_regs __iomem *)dev->base_addr;
int i;
- /* dev_addr will be overwritten on NETDEV_REGISTER event */
while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
;
for (i = 0; i < 6; i += 2) {
dev->dev_addr[i] = data & 0xff;
dev->dev_addr[i+1] = data >> 8;
}
+ if (!is_valid_ether_addr(dev->dev_addr))
+ return tc35815_read_plat_dev_addr(dev);
+ return 0;
}
static int __devinit tc35815_init_one (struct pci_dev *pdev,
tc35815_chip_reset(dev);
/* Retrieve the ethernet address. */
- tc35815_init_dev_addr(dev);
+ if (tc35815_init_dev_addr(dev)) {
+ dev_warn(&pdev->dev, "not valid ether addr\n");
+ random_ether_addr(dev->dev_addr);
+ }
rc = register_netdev (dev);
if (rc)