summaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* unify flush_work/flush_work_keventd and rename it to cancel_work_syncOleg Nesterov2007-05-091-1/+1
| | | | | | | | | | | | | | | | | | | | flush_work(wq, work) doesn't need the first parameter, we can use cwq->wq (this was possible from the very beginnig, I missed this). So we can unify flush_work_keventd and flush_work. Also, rename flush_work() to cancel_work_sync() and fix all callers. Perhaps this is not the best name, but "flush_work" is really bad. (akpm: this is why the earlier patches bypassed maintainers) Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Jeff Garzik <jeff@garzik.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Jens Axboe <jens.axboe@oracle.com> Cc: Tejun Heo <htejun@gmail.com> Cc: Auke Kok <auke-jan.h.kok@intel.com>, Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* tg3: use flush_work_keventd()Andrew Morton2007-05-091-10/+1
| | | | | | | | | | | | | | | | | Convert tg3 over to flush_work_keventd(). Remove nasty now-unneeded deadlock avoidance logic. (akpm: bypassed maintainers, sorry. There are other patches which depend on this) Cc: "Maciej W. Rozycki" <macro@linux-mips.org> Cc: David Howells <dhowells@redhat.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Michael Chan <mchan@broadcom.com> Cc: Jeff Garzik <jeff@garzik.org> Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* [TG3]: Update version and reldate.Michael Chan2007-05-071-2/+2
| | | | | | | Update version to 3.76. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Eliminate spurious interrupts.Michael Chan2007-05-071-2/+10
| | | | | | | | | | | | | | | Spurious interrupts are often encountered especially on systems using the 8259 PIC mode. This is because the I/O write to deassert the interrupt is posted and won't get to the chip immediately. As a result, the IRQ may remain asserted after the IRQ handler exits, causing spurious interrupts. Flush the interrupt mailbox in non-MSI handlers to de-assert the IRQ immediately. This seems to be the most straight forward approach after discussion with Jeff Garzik and David Miller. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Add ASPM workaround.Matt Carlson2007-05-071-0/+24
| | | | | | | | | | | This patch adds workaround to fix performance problems caused by slow PCIE L1->L0 transitions on ICH8 platforms. Changed all magic numbers to constants as suggested by Jeff Garzik. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Add TG3_FLAG_SUPPORT_MSI flag.Michael Chan2007-05-051-9/+15
| | | | | | | | | | And fix up the code to always allow MSI on 5714 A2. Call tg3_find_peer() earlier because we need that information before we can determine whether we can set TG3_FLAG_SUPPORT_MSI or not. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Eliminate the TG3_FLAG_5701_REG_WRITE_BUG flag.Matt Carlson2007-05-051-12/+12
| | | | | | | | | | | This patch removes the use of the TG3_FLAG_5701_REG_WRITE_BUG flag. It's logic is only used to set a function pointer and thus the logic can be collapsed and the flag removed. [ Comment tidy by Christoph Hellwig. -DaveM ] Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com>
* [TG3]: Eliminate the TG3_FLAG_GOT_SERDES_FLOWCTL flag.Michael Chan2007-05-051-8/+2
| | | | | | | This flag does not do anything useful. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Remove reset during MAC address changes.Michael Chan2007-05-051-17/+18
| | | | | | | | | | | | | | | | | | The reset was added a while back so that ASF could re-init whatever MAC address it wanted to use after the MAC address was changed. Instead of resetting, we can just keep MAC address 1 unchanged during MAC address changes if MAC address 1 is different from MAC address 0. This fixes 2 problems: 1. Bonding calls set_mac_address in contexts that cannot sleep. It no longer sleeps with the chip reset removed. 2. When ASF shares the same MAC address as the NIC, it needs to always do that even when the MAC address is changed. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: WoL fixes.Gary Zambrano2007-05-051-10/+15
| | | | | | | | | | Change TG3_FLAG_SERDES_WOL_CAP to TG3_FLAG_WOL_CAP to make it easier to manage WoL. This flag is now used consistently during ethtool WoL setup and power setting changes. Signed-off-by: Gary Zambrano <zambrano@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Clear GPIO mask before storing.Gary Zambrano2007-05-051-0/+1
| | | | | | | | | The GPIO settings may change during reset and so the stored values in tp->grc_local_ctrl should be cleared first. Signed-off-by: Gary Zambrano <zambrano@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Improve NVRAM sizing.Matt Carlson2007-05-051-16/+23
| | | | | | | | | | | | | | This patch changes the NVRAM sizing procedure so that the driver can take advantage of devices with 1:1 NVRAM strapping configurations. This is useful in cases where the traditional NVRAM sizing method fails. In the event that the flash size cannot be determined, the largest known NVRAM size is used. The patch also removes support for 5755 NVRAM devices that are not supported by Broadcom and adds explicit sizing for this device. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Fix TSO bugs.Matt Carlson2007-05-051-6/+3
| | | | | | | | | | | | | | | 1. Remove the check for skb->len greater than MTU when doing TSO. When the destination has a smaller MSS than the source, a TSO packet may be smaller than the MTU and we still need to process it as a TSO packet. 2. On 5705A3 devices with TSO enabled, the DMA engine can hang due to a hardware bug. This patch avoids the hanging condition by reducing the DMA burst size. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6Linus Torvalds2007-04-271-18/+13
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: (67 commits) [SCSI] SUNESP: Complete driver rewrite to version 2.0 [SPARC64]: Convert PCI over to generic struct iommu/strbuf. [SPARC]: device_node name constification fallout [SPARC64]: Convert SBUS over to generic iommu/strbuf structs. [SPARC64]: Add generic iommu and strbuf structs to iommu.h [SPARC64]: Consolidate {sbus,pci}_iommu_arena. [SPARC]: Make device_node name and type const [SPARC64]: constify some paramaters of OF routines [TIGON3]: of_get_property() returns const. [SPARC64]: Fix PCI rework to adhere to of_get_property() const return. [SPARC64]: Document and fix calculation of pages_avail. [SPARC64]: Make sure pbm->prom_node is setup easly enough in psycho.c [SPARC64]: Use bootmem_bootmap_pages() in choose_bootmap_pfn(). [SPARC64]: Add proper header file extern for cmdline_memory_size. [SPARC64]: Kill sparc_ultra_dump_{i,d}tlb() [SPARC64]: Use DECLARE_BITMAP and BITS_TO_LONGS in mm/init.c [SPARC64]: Give move verbose show_mem() output just like i386. [SPARC64]: Mark show_mem() printk's with KERN_INFO. [SPARC64]: Kill kvaddr_to_phys() and friends. [SPARC64]: Privatize sun4u_get_pte() and fix name. ...
| * [TIGON3]: of_get_property() returns const.David S. Miller2007-04-261-1/+1
| | | | | | | | Signed-off-by: David S. Miller <davem@davemloft.net>
| * [TG3]: Use pci_device_to_OF_node() on sparc.David S. Miller2007-04-261-18/+13
| | | | | | | | | | | | | | And use CONFIG_SPARC instead of CONFIG_SPARC64 as the test. Signed-off-by: David S. Miller <davem@davemloft.net>
| * [SPARC/64] constify of_get_property return: driversStephen Rothwell2007-04-261-1/+1
| | | | | | | | | | | | | | | | The only unfortunate bit here is that the name field of struct map_info is not const, so for now we put a cast on the assignment of it. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
* | [SK_BUFF]: Introduce skb_copy_from_linear_data{_offset}Arnaldo Carvalho de Melo2007-04-261-1/+1
| | | | | | | | | | | | | | To clearly state the intent of copying from linear sk_buffs, _offset being a overly long variant but interesting for the sake of saving some bytes. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
* | [SK_BUFF]: Introduce tcp_hdr(), remove skb->h.thArnaldo Carvalho de Melo2007-04-261-8/+7
| | | | | | | | | | Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* | [TCP]: Introduce tcp_hdrlen() and tcp_optlen()Arnaldo Carvalho de Melo2007-04-261-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | The ip_hdrlen() buddy, created to reduce the number of skb->h.th-> uses and to avoid the longer, open coded equivalent. Ditched a no-op in bnx2 in the process. I wonder if we should have a BUG_ON(skb->h.th->doff < 5) in tcp_optlen()... Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* | [SK_BUFF]: Introduce ip_hdr(), remove skb->nh.iphArnaldo Carvalho de Melo2007-04-261-15/+15
| | | | | | | | | | Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* | [IP]: Introduce ip_hdrlen()Arnaldo Carvalho de Melo2007-04-261-3/+3
|/ | | | | | | | | | | | | | | | For the common sequence "skb->nh.iph->ihl * 4", removing a good number of open coded skb->nh.iph uses, now to go after the rest... Just out of curiosity, here are the idioms found to get the same result: skb->nh.iph->ihl << 2 skb->nh.iph->ihl<<2 skb->nh.iph->ihl * 4 skb->nh.iph->ihl*4 (skb->nh.iph)->ihl * sizeof(u32) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Fix crash during tg3_init_one().Michael Chan2007-04-071-2/+4
| | | | | | | | | | | | The driver will crash when the chip has been initialized by EFI before tg3_init_one(). In this case, the driver will call tg3_chip_reset() before allocating consistent memory. The bug is fixed by checking for tp->hw_status before accessing it during tg3_chip_reset(). Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Update version and reldate.Michael Chan2007-03-261-2/+2
| | | | | | | Update version to 3.75. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Exit irq handler during chip reset.Michael Chan2007-03-261-47/+66
| | | | | | | | | | | | | | | | | | | | | On most tg3 chips, the memory enable bit in the PCI command register gets cleared during chip reset and must be restored before accessing PCI registers using memory cycles. The chip does not generate interrupt during chip reset, but the irq handler can still be called because of irq sharing or irqpoll. Reading a register in the irq handler can cause a master abort in this scenario and may result in a crash on some architectures. Use the TG3_FLAG_CHIP_RESETTING flag to tell the irq handler to exit without touching any registers. The checking of the flag is in the "slow" path of the irq handler and will not affect normal performance. The msi handler is not shared and therefore does not require checking the flag. Thanks to Bernhard Walle <bwalle@suse.de> for reporting the problem. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Eliminate the unused TG3_FLAG_SPLIT_MODE flag.Michael Chan2007-03-261-16/+1
| | | | | | | | This flag to support multiple PCIX split completions was never used because of hardware bugs. This will make room for a new flag. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [VLAN]: Avoid a 4-order allocation.Dan Aloni2007-03-031-2/+1
| | | | | | | | | | | | | | This patch splits the vlan_group struct into a multi-allocated struct. On x86_64, the size of the original struct is a little more than 32KB, causing a 4-order allocation, which is prune to problems caused by buddy-system external fragmentation conditions. I couldn't just use vmalloc() because vfree() cannot be called in the softirq context of the RCU callback. Signed-off-by: Dan Aloni <da-x@monatomic.org> Acked-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: TSO workaround fixes.Michael Chan2007-02-261-9/+11
| | | | | | | | | | | | | | | | 1. Add race condition check after netif_stop_queue(). tg3_tx() runs without netif_tx_lock and can race with tg3_start_xmit_dma_bug() -> tg3_tso_bug(). 2. Firmware TSO in 5703/5704/5705 also have the same TSO limitation, i.e. they cannot handle TSO headers bigger than 80 bytes. Rename TG3_FL2_HW_TSO_1_BUG to TG3_FL2_TSO_BUG and set this flag on these chips as well. 3. Update version to 3.74. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Update copyright, version, and reldate.Michael Chan2007-02-131-3/+3
| | | | | | | Update version to 3.73. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Add some tx timeout debug messages.Michael Chan2007-02-131-1/+11
| | | | | | | Print the most useful information during tx timeout to help debug. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Use constant for PHY register 0x1e.Michael Chan2007-02-131-4/+6
| | | | | Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Power down 5704 serdes transceiver when shutting down.Michael Chan2007-02-131-1/+11
| | | | | Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: 5906 doesn't need to switch to slower clock.Michael Chan2007-02-131-1/+2
| | | | | Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: 5722/5756 don't need PHY jitter workaround.Michael Chan2007-02-131-1/+3
| | | | | Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Use lower DMA watermark for 5703.Michael Chan2007-02-131-1/+7
| | | | | | | | Set DMA read watermark to 4 on 5703 in PCIX mode. This is needed to prevent some tx timeouts. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Save MSI state before suspend.Michael Chan2007-02-131-0/+3
| | | | | | | | | | | | | This fixes the following problem: http://bugzilla.kernel.org/show_bug.cgi?id=7969 The MSI state needs to be saved during suspend. PCI state saved during tg3_init_one() does not contain valid MSI state because MSI hasn't been enabled. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Avoid an expensive divide.Eric Dumazet2007-02-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | During an oprofile session of linux-2.6.20 on a dual opteron system, I noticed an expensive divide was done in tg3_poll(). I am using gcc-4.1.1, so the following comment from drivers/net/tg3.c seems over-optimistic : /* Do not place this n-ring entries value into the tp struct itself, * we really want to expose these constants to GCC so that modulo et * al. operations are done with shifts and masks instead of with * hw multiply/modulo instructions. Another solution would be to * replace things like '% foo' with '& (foo - 1)'. */ #define TG3_RX_RCB_RING_SIZE(tp) \ ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ? 512 : 1024) Assembly code before patch : (oprofile results included) 6434 0.0088 :ffffffff803684b9: mov 0x6f0(%r15),%eax 587 8.0e-04 :ffffffff803684c0: and $0x40000,%eax 2170 0.0030 :ffffffff803684c5: cmp $0x1,%eax :ffffffff803684c8: lea 0x1(%r13),%eax :ffffffff803684cc: sbb %ecx,%ecx 2051 0.0028 :ffffffff803684ce: xor %edx,%edx :ffffffff803684d0: and $0x200,%ecx 20 2.7e-05 :ffffffff803684d6: add $0x200,%ecx 1986 0.0027 :ffffffff803684dc: div %ecx 103427 0.1410 :ffffffff803684de: cmp %edx,0xffffffffffffff7c(%rbp) Assembly code after the suggested patch : ffffffff803684b9: mov 0x6f0(%r15),%eax ffffffff803684c0: and $0x40000,%eax ffffffff803684c5: cmp $0x1,%eax ffffffff803684c8: sbb %eax,%eax ffffffff803684ca: inc %r13d ffffffff803684cd: and $0x200,%eax ffffffff803684d2: add $0x1ff,%eax ffffffff803684d7: and %eax,%r13d ffffffff803684da: cmp %r13d,0xffffffffffffff7c(%rbp) Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Acked-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* remove NETIF_F_TSO ifdeferyArjan van de Ven2007-02-051-32/+0
| | | | | | | | | Remove the NETIF_F_TSO #ifdef-ery in drivers/net; this was for old-old-2.4 compat (even current 2.4 has NETIF_F_TSO) but it's time to get rid of it by now. Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
* [TG3]: Add PHY workaround for 5755M.Michael Chan2007-01-091-5/+12
| | | | | | | | | | Some PHY trim values need to be fine-tuned on 5755M to be IEEE-compliant. Update version to 3.72. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Update version and reldate.Michael Chan2006-12-181-2/+2
| | | | | | | Update version to 3.71. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Power down/up 5906 PHY correctly.Michael Chan2006-12-181-1/+16
| | | | | | | | The 5906 PHY requires a special register bit to power down and up the PHY. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Fix race condition when calling register_netdev().Michael Chan2006-12-181-4/+4
| | | | | | | | | | Hot-plug scripts can call tg3_open() as soon as register_netdev() is called in tg3_init_one(). We need to call pci_set_drvdata() before register_netdev(), and netif_carrier_off() needs to be moved to tg3_open() to avoid race conditions. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Assign tp->link_config.orig_* values.Michael Chan2006-12-181-0/+4
| | | | | | | | | | | tp->link_config.orig_* values must be assigned during tg3_set_settings() because these values will be used to setup the link speed during tg3_open(). Without these assignments, the link speed settings will be all messed by if tg3_set_settings() is called when the device is down. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: replace kmalloc+memset with kzallocYan Burman2006-12-181-8/+1
| | | | | | | | Replace kmalloc+memset with kzalloc Signed-off-by: Yan Burman <burman.yan@gmail.com> Acked-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Identify Serdes devices more clearly.Michael Chan2006-12-071-4/+6
| | | | | | | | | Change the message to more clearly identify Serdes devices. Update version to 3.70. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Use msleep.Michael Chan2006-12-071-9/+5
| | | | | | | | Change some udelay() in some eeprom functions to msleep(). Eeprom related functions are always called from sleepable context. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Use netif_msg_*.Michael Chan2006-12-071-5/+10
| | | | | | | | | Use netif_msg_* to turn on or off some messages. Based on Stephen Hemminger's initial patch. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Allow partial speed advertisement.Michael Chan2006-12-071-15/+24
| | | | | | | | Honor the advertisement bitmask from ethtool. We used to always advertise the full capability when autoneg was set to on. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Add TG3_FLG2_IS_NIC flag.Michael Chan2006-12-071-13/+24
| | | | | | | | | | | Add Tg3_FLG2_IS_NIC flag to unambiguously determine whether the device is NIC or onboard. Previously, the EEPROM_WRITE_PROT flag was overloaded to also mean onboard. With the separation, we can support some devices that are onboard but do not use eeprom write protect. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [TG3]: Add 5787F device ID.Michael Chan2006-12-071-1/+3
| | | | | Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>