Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 388f7ef7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

parents d5eebf42 560c22fe
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -812,7 +812,7 @@ config SMC91X
	tristate "SMC 91C9x/91C1xxx support"
	select CRC32
	select MII
	depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH)
	depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00)
	help
	  This is a driver for SMC's 91x series of Ethernet chipsets,
	  including the SMC91C94 and the SMC91C111. Say Y if you want it
+138 −93
Original line number Diff line number Diff line
@@ -97,6 +97,9 @@
 *			   in the second (and later) nv_open call
 *	0.43: 10 Aug 2005: Add support for tx checksum.
 *	0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
 *	0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check
 *	0.46: 20 Oct 2005: Add irq optimization modes.
 *	0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.
 *
 * Known bugs:
 * We suspect that on some hardware no TX done interrupts are generated.
@@ -108,7 +111,7 @@
 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
 * superfluous timer interrupts from the nic.
 */
#define FORCEDETH_VERSION		"0.44"
#define FORCEDETH_VERSION		"0.47"
#define DRV_NAME			"forcedeth"

#include <linux/module.h>
@@ -163,7 +166,8 @@ enum {
#define NVREG_IRQ_LINK			0x0040
#define NVREG_IRQ_TX_ERROR		0x0080
#define NVREG_IRQ_TX1			0x0100
#define NVREG_IRQMASK_WANTED		0x00df
#define NVREG_IRQMASK_THROUGHPUT	0x00df
#define NVREG_IRQMASK_CPU		0x0040

#define NVREG_IRQ_UNKNOWN	(~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \
					NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \
@@ -177,7 +181,8 @@ enum {
 * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
 */
	NvRegPollingInterval = 0x00c,
#define NVREG_POLL_DEFAULT	970
#define NVREG_POLL_DEFAULT_THROUGHPUT	970
#define NVREG_POLL_DEFAULT_CPU	13
	NvRegMisc1 = 0x080,
#define NVREG_MISC1_HD		0x02
#define NVREG_MISC1_FORCE	0x3b0f3c
@@ -538,6 +543,25 @@ struct fe_priv {
 */
static int max_interrupt_work = 5;

/*
 * Optimization can be either throuput mode or cpu mode
 * 
 * Throughput Mode: Every tx and rx packet will generate an interrupt.
 * CPU Mode: Interrupts are controlled by a timer.
 */
#define NV_OPTIMIZATION_MODE_THROUGHPUT 0
#define NV_OPTIMIZATION_MODE_CPU        1
static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;

/*
 * Poll interval for timer irq
 *
 * This interval determines how frequent an interrupt is generated.
 * The is value is determined by [(time_in_micro_secs * 100) / (2^10)]
 * Min = 0, and Max = 65535
 */
static int poll_interval = -1;

static inline struct fe_priv *get_nvpriv(struct net_device *dev)
{
	return netdev_priv(dev);
@@ -1328,6 +1352,7 @@ static void nv_rx_process(struct net_device *dev)
			if (!(Flags & NV_RX_DESCRIPTORVALID))
				goto next_pkt;

			if (Flags & NV_RX_ERROR) {
				if (Flags & NV_RX_MISSEDFRAME) {
					np->stats.rx_missed_errors++;
					np->stats.rx_errors++;
@@ -1360,10 +1385,12 @@ static void nv_rx_process(struct net_device *dev)
						len--;
					}
				}
			}
		} else {
			if (!(Flags & NV_RX2_DESCRIPTORVALID))
				goto next_pkt;

			if (Flags & NV_RX2_ERROR) {
				if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
					np->stats.rx_errors++;
					goto next_pkt;
@@ -1391,6 +1418,7 @@ static void nv_rx_process(struct net_device *dev)
						len--;
					}
				}
			}
			Flags &= NV_RX2_CHECKSUMMASK;
			if (Flags == NV_RX2_CHECKSUMOK1 ||
					Flags == NV_RX2_CHECKSUMOK2 ||
@@ -1612,6 +1640,17 @@ static void nv_set_multicast(struct net_device *dev)
	spin_unlock_irq(&np->lock);
}

/**
 * nv_update_linkspeed: Setup the MAC according to the link partner
 * @dev: Network device to be configured
 *
 * The function queries the PHY and checks if there is a link partner.
 * If yes, then it sets up the MAC accordingly. Otherwise, the MAC is
 * set to 10 MBit HD.
 *
 * The function returns 0 if there is no link partner and 1 if there is
 * a good link partner.
 */
static int nv_update_linkspeed(struct net_device *dev)
{
	struct fe_priv *np = netdev_priv(dev);
@@ -1751,13 +1790,11 @@ set_speed:
static void nv_linkchange(struct net_device *dev)
{
	if (nv_update_linkspeed(dev)) {
		if (netif_carrier_ok(dev)) {
			nv_stop_rx(dev);
		} else {
		if (!netif_carrier_ok(dev)) {
			netif_carrier_on(dev);
			printk(KERN_INFO "%s: link up.\n", dev->name);
		}
			nv_start_rx(dev);
		}
	} else {
		if (netif_carrier_ok(dev)) {
			netif_carrier_off(dev);
@@ -1799,13 +1836,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
		if (!(events & np->irqmask))
			break;

		if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_ERR)) {
		spin_lock(&np->lock);
		nv_tx_done(dev);
		spin_unlock(&np->lock);
		}
		
		if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) {
		nv_rx_process(dev);
		if (nv_alloc_rx(dev)) {
			spin_lock(&np->lock);
@@ -1813,7 +1847,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
				mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
			spin_unlock(&np->lock);
		}
		}
		
		if (events & NVREG_IRQ_LINK) {
			spin_lock(&np->lock);
@@ -2216,7 +2249,14 @@ static int nv_open(struct net_device *dev)
	writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed);
	writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
	writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
	writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);
	if (poll_interval == -1) {
		if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)
			writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + NvRegPollingInterval);
		else
			writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval);
	}
	else
		writel(poll_interval & 0xFFFF, base + NvRegPollingInterval);
	writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
	writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING,
			base + NvRegAdapterControl);
@@ -2501,7 +2541,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
	} else {
		np->tx_flags = NV_TX2_VALID;
	}
	np->irqmask = NVREG_IRQMASK_WANTED;
	if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)
		np->irqmask = NVREG_IRQMASK_THROUGHPUT;
	else
		np->irqmask = NVREG_IRQMASK_CPU;

	if (id->driver_data & DEV_NEED_TIMERIRQ)
		np->irqmask |= NVREG_IRQ_TIMER;
	if (id->driver_data & DEV_NEED_LINKTIMER) {
@@ -2514,16 +2558,17 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
	}

	/* find a suitable phy */
	for (i = 1; i < 32; i++) {
	for (i = 1; i <= 32; i++) {
		int id1, id2;
		int phyaddr = i & 0x1F;

		spin_lock_irq(&np->lock);
		id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);
		id1 = mii_rw(dev, phyaddr, MII_PHYSID1, MII_READ);
		spin_unlock_irq(&np->lock);
		if (id1 < 0 || id1 == 0xffff)
			continue;
		spin_lock_irq(&np->lock);
		id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);
		id2 = mii_rw(dev, phyaddr, MII_PHYSID2, MII_READ);
		spin_unlock_irq(&np->lock);
		if (id2 < 0 || id2 == 0xffff)
			continue;
@@ -2531,23 +2576,19 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
		id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT;
		id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT;
		dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
				pci_name(pci_dev), id1, id2, i);
		np->phyaddr = i;
			pci_name(pci_dev), id1, id2, phyaddr);
		np->phyaddr = phyaddr;
		np->phy_oui = id1 | id2;
		break;
	}
	if (i == 32) {
		/* PHY in isolate mode? No phy attached and user wants to
		 * test loopback? Very odd, but can be correct.
		 */
	if (i == 33) {
		printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",
		       pci_name(pci_dev));
		goto out_freering;
	}
	
	if (i != 32) {
	/* reset it */
	phy_init(dev);
	}

	/* set default link speed settings */
	np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
@@ -2689,6 +2730,10 @@ static void __exit exit_nic(void)

module_param(max_interrupt_work, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
module_param(optimization_mode, int, 0);
MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer.");
module_param(poll_interval, int, 0);
MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");

MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
+1 −1
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ int gfar_mdio_probe(struct device *dev)
	if (NULL == dev)
		return -EINVAL;

	new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);

	if (NULL == new_bus)
		return -ENOMEM;
+4 −6
Original line number Diff line number Diff line
@@ -72,8 +72,6 @@ static void dump_tx_desc(int dbg_lvl, struct net_device *dev, int i);
static void dump_rx_desc(int dbg_lvl, struct net_device *dev, int i);
static void dump_skb(int dbg_lvl, struct net_device *dev,
		     struct sk_buff *skb);
static void dump_hw_addr(int dbg_lvl, struct net_device *dev,
			 const char* pfx, unsigned char* addr_str);
static void update_stats(struct gt96100_private *gp);
static void abort(struct net_device *dev, u32 abort_bits);
static void hard_stop(struct net_device *dev);
@@ -334,13 +332,13 @@ dump_MII(int dbg_lvl, struct net_device *dev)

static void
dump_hw_addr(int dbg_lvl, struct net_device *dev, const char* pfx,
	     unsigned char* addr_str)
	     const char* func, unsigned char* addr_str)
{
	int i;
	char buf[100], octet[5];
    
	if (dbg_lvl <= GT96100_DEBUG) {
		strcpy(buf, pfx);
		sprintf(buf, pfx, func);
		for (i = 0; i < 6; i++) {
			sprintf(octet, "%2.2x%s",
				addr_str[i], i<5 ? ":" : "\n");
@@ -708,7 +706,7 @@ static int __init gt96100_probe1(struct pci_dev *pci, int port_num)

	info("%s found at 0x%x, irq %d\n",
	     chip_name(gp->chip_rev), gtif->iobase, gtif->irq);
	dump_hw_addr(0, dev, "HW Address ", dev->dev_addr);
	dump_hw_addr(0, dev, "%s: HW Address ", __FUNCTION__, dev->dev_addr);
	info("%s chip revision=%d\n", chip_name(gp->chip_rev), gp->chip_rev);
	info("%s ethernet port %d\n", chip_name(gp->chip_rev), gp->port_num);
	info("external PHY ID1=0x%04x, ID2=0x%04x\n", phy_id1, phy_id2);
@@ -1488,7 +1486,7 @@ gt96100_set_rx_mode(struct net_device *dev)
		gt96100_add_hash_entry(dev, dev->dev_addr);

		for (mcptr = dev->mc_list; mcptr; mcptr = mcptr->next) {
			dump_hw_addr(2, dev, __FUNCTION__ ": addr=",
			dump_hw_addr(2, dev, "%s: addr=", __FUNCTION__,
				     mcptr->dmi_addr);
			gt96100_add_hash_entry(dev, mcptr->dmi_addr);
		}
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@

#include "ibmveth.h"

#define DEBUG 1
#undef DEBUG

#define ibmveth_printk(fmt, args...) \
  printk(KERN_INFO "%s: " fmt, __FILE__, ## args)
Loading