[linux-next] LinuxNextTracking branch, master, updated. next-20111214

batman at open-mesh.org batman at open-mesh.org
Thu Dec 15 00:16:50 CET 2011


The following commit has been merged in the master branch:
commit cef8826c48c5f581ed1215da07120b12e20751e3
Merge: 62b804b9a2462bdbe556b0fa8b74e86041cc3706 b43faac69062f0fc75bd3230d67da64e184232d1
Author: Stephen Rothwell <sfr at canb.auug.org.au>
Date:   Wed Dec 14 13:02:10 2011 +1100

    Merge remote-tracking branch 'net-next/master'
    
    Conflicts:
    	drivers/net/ethernet/freescale/fsl_pq_mdio.c
    	net/batman-adv/translation-table.c

diff --combined Documentation/feature-removal-schedule.txt
index dca11ea,33f7327..a57dc2e
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@@ -263,8 -263,7 +263,7 @@@ Who:	Ravikiran Thirumalai <kiran at scalex
  
  What:	Code that is now under CONFIG_WIRELESS_EXT_SYSFS
  	(in net/core/net-sysfs.c)
- When:	After the only user (hal) has seen a release with the patches
- 	for enough time, probably some time in 2010.
+ When:	3.5
  Why:	Over 1K .text/.data size reduction, data is available in other
  	ways (ioctls)
  Who:	Johannes Berg <johannes at sipsolutions.net>
@@@ -551,15 -550,3 +550,15 @@@ When:	3.
  Why:	The iwlagn module has been renamed iwlwifi.  The alias will be around
  	for backward compatibility for several cycles and then dropped.
  Who:	Don Fry <donald.h.fry at intel.com>
 +
 +----------------------------
 +
 +What:	pci_scan_bus_parented()
 +When:	3.5
 +Why:	The pci_scan_bus_parented() interface creates a new root bus.  The
 +	bus is created with default resources (ioport_resource and
 +	iomem_resource) that are always wrong, so we rely on arch code to
 +	correct them later.  Callers of pci_scan_bus_parented() should
 +	convert to using pci_scan_root_bus() so they can supply a list of
 +	bus resources when the bus is created.
 +Who:	Bjorn Helgaas <bhelgaas at google.com>
diff --combined MAINTAINERS
index af23d6d,209ad06..02e270b
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@@ -511,8 -511,8 +511,8 @@@ M:	Joerg Roedel <joerg.roedel at amd.com
  L:	iommu at lists.linux-foundation.org
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git
  S:	Supported
 -F:	arch/x86/kernel/amd_iommu*.c
 -F:	arch/x86/include/asm/amd_iommu*.h
 +F:	drivers/iommu/amd_iommu*.[ch]
 +F:	include/linux/amd-iommu.h
  
  AMD MICROCODE UPDATE SUPPORT
  M:	Andreas Herrmann <andreas.herrmann3 at amd.com>
@@@ -749,7 -749,6 +749,7 @@@ M:	Barry Song <baohua.song at csr.com
  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
  S:	Maintained
  F:	arch/arm/mach-prima2/
 +F:	drivers/dma/sirf-dma*
  
  ARM/EBSA110 MACHINE SUPPORT
  M:	Russell King <linux at arm.linux.org.uk>
@@@ -1055,18 -1054,35 +1055,18 @@@ ARM/SAMSUNG ARM ARCHITECTURE
  M:	Ben Dooks <ben-linux at fluff.org>
  M:	Kukjin Kim <kgene.kim at samsung.com>
  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 +L:	linux-samsung-soc at vger.kernel.org (moderated for non-subscribers)
  W:	http://www.fluff.org/ben/linux/
  S:	Maintained
  F:	arch/arm/plat-samsung/
  F:	arch/arm/plat-s3c24xx/
  F:	arch/arm/plat-s5p/
 +F:	arch/arm/mach-s3c24*/
 +F:	arch/arm/mach-s3c64xx/
  F:	drivers/*/*s3c2410*
  F:	drivers/*/*/*s3c2410*
 -
 -ARM/S3C2410 ARM ARCHITECTURE
 -M:	Ben Dooks <ben-linux at fluff.org>
 -L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 -W:	http://www.fluff.org/ben/linux/
 -S:	Maintained
 -F:	arch/arm/mach-s3c2410/
 -
 -ARM/S3C244x ARM ARCHITECTURE
 -M:	Ben Dooks <ben-linux at fluff.org>
 -L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 -W:	http://www.fluff.org/ben/linux/
 -S:	Maintained
 -F:	arch/arm/mach-s3c2440/
 -F:	arch/arm/mach-s3c2443/
 -
 -ARM/S3C64xx ARM ARCHITECTURE
 -M:	Ben Dooks <ben-linux at fluff.org>
 -L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 -W:	http://www.fluff.org/ben/linux/
 -S:	Maintained
 -F:	arch/arm/mach-s3c64xx/
 +F:	drivers/spi/spi-s3c*
 +F:	sound/soc/samsung/*
  
  ARM/S5P EXYNOS ARM ARCHITECTURES
  M:	Kukjin Kim <kgene.kim at samsung.com>
@@@ -1662,14 -1678,6 +1662,14 @@@ T:	git git://git.alsa-project.org/alsa-
  S:	Maintained
  F:	sound/pci/oxygen/
  
 +C6X ARCHITECTURE
 +M:	Mark Salter <msalter at redhat.com>
 +M:	Aurelien Jacquiot <a-jacquiot at ti.com>
 +L:	linux-c6x-dev at linux-c6x.org
 +W:	http://www.linux-c6x.org/wiki/index.php/Main_Page
 +S:	Maintained
 +F:	arch/c6x/
 +
  CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS
  M:	David Howells <dhowells at redhat.com>
  L:	linux-cachefs at redhat.com
@@@ -2846,14 -2854,6 +2846,14 @@@ L:	platform-driver-x86 at vger.kernel.or
  S:	Maintained
  F:	drivers/platform/x86/fujitsu-laptop.c
  
 +FUJITSU M-5MO LS CAMERA ISP DRIVER
 +M:	Kyungmin Park <kyungmin.park at samsung.com>
 +M:	Heungjun Kim <riverful.kim at samsung.com>
 +L:	linux-media at vger.kernel.org
 +S:	Maintained
 +F:	drivers/media/video/m5mols/
 +F:	include/media/m5mols.h
 +
  FUSE: FILESYSTEM IN USERSPACE
  M:	Miklos Szeredi <miklos at szeredi.hu>
  L:	fuse-devel at lists.sourceforge.net
@@@ -3796,6 -3796,7 +3796,6 @@@ S:	Odd Fixe
  
  KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
  M:	"J. Bruce Fields" <bfields at fieldses.org>
 -M:	Neil Brown <neilb at suse.de>
  L:	linux-nfs at vger.kernel.org
  W:	http://nfs.sourceforge.net/
  S:	Supported
@@@ -4027,7 -4028,7 +4027,7 @@@ M:	Josh Boyer <jwboyer at gmail.com
  M:	Matt Porter <mporter at kernel.crashing.org>
  W:	http://www.penguinppc.org/
  L:	linuxppc-dev at lists.ozlabs.org
 -T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git
 +T:	git git://git.infradead.org/users/jwboyer/powerpc-4xx.git
  S:	Maintained
  F:	arch/powerpc/platforms/40x/
  F:	arch/powerpc/platforms/44x/
@@@ -4131,7 -4132,6 +4131,7 @@@ F:	fs/partitions/ldm.
  
  LogFS
  M:	Joern Engel <joern at logfs.org>
 +M:	Prasad Joshi <prasadjoshi.linux at gmail.com>
  L:	logfs at logfs.org
  W:	logfs.org
  S:	Maintained
@@@ -4297,9 -4297,7 +4297,9 @@@ T:	git git://git.kernel.org/pub/scm/lin
  S:	Maintained
  F:	Documentation/dvb/
  F:	Documentation/video4linux/
 +F:	Documentation/DocBook/media/
  F:	drivers/media/
 +F:	drivers/staging/media/
  F:	include/media/
  F:	include/linux/dvb/
  F:	include/linux/videodev*.h
@@@ -4321,9 -4319,8 +4321,9 @@@ F:	include/linux/mm.
  F:	mm/
  
  MEMORY RESOURCE CONTROLLER
 +M:	Johannes Weiner <hannes at cmpxchg.org>
 +M:	Michal Hocko <mhocko at suse.cz>
  M:	Balbir Singh <bsingharora at gmail.com>
 -M:	Daisuke Nishimura <nishimura at mxp.nes.nec.co.jp>
  M:	KAMEZAWA Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>
  L:	cgroups at vger.kernel.org
  L:	linux-mm at kvack.org
@@@ -4871,6 -4868,14 +4871,14 @@@ S:	Maintaine
  T:	git git://openrisc.net/~jonas/linux
  F:	arch/openrisc
  
+ OPENVSWITCH
+ M:	Jesse Gross <jesse at nicira.com>
+ L:	dev at openvswitch.org
+ W:	http://openvswitch.org
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch.git
+ S:	Maintained
+ F:	net/openvswitch/
+ 
  OPL4 DRIVER
  M:	Clemens Ladisch <clemens at ladisch.de>
  L:	alsa-devel at alsa-project.org (moderated for non-subscribers)
@@@ -6513,6 -6518,13 +6521,13 @@@ W:	http://tcp-lp-mod.sourceforge.net
  S:	Maintained
  F:	net/ipv4/tcp_lp.c
  
+ TEAM DRIVER
+ M:	Jiri Pirko <jpirko at redhat.com>
+ L:	netdev at vger.kernel.org
+ S:	Supported
+ F:	drivers/net/team/
+ F:	include/linux/if_team.h
+ 
  TEGRA SUPPORT
  M:	Colin Cross <ccross at android.com>
  M:	Olof Johansson <olof at lixom.net>
diff --combined drivers/net/ethernet/Makefile
index 94b7f28,cd6d69a..08d5f03
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@@ -10,10 -10,11 +10,11 @@@ obj-$(CONFIG_NET_VENDOR_ALTEON) += alte
  obj-$(CONFIG_NET_VENDOR_AMD) += amd/
  obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
  obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
 -obj-$(CONFIG_NET_ATMEL) += cadence/
 +obj-$(CONFIG_NET_CADENCE) += cadence/
  obj-$(CONFIG_NET_BFIN) += adi/
  obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
  obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/
+ obj-$(CONFIG_NET_CALXEDA_XGMAC) += calxeda/
  obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
  obj-$(CONFIG_NET_VENDOR_CIRRUS) += cirrus/
  obj-$(CONFIG_NET_VENDOR_CISCO) += cisco/
diff --combined drivers/net/ethernet/freescale/fec.c
index c136230,01ee9cc..4ea2bdc
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@@ -99,7 -99,7 +99,7 @@@ static struct platform_device_id fec_de
  MODULE_DEVICE_TABLE(platform, fec_devtype);
  
  enum imx_fec_type {
- 	IMX25_FEC = 1, 	/* runs on i.mx25/50/53 */
+ 	IMX25_FEC = 1,	/* runs on i.mx25/50/53 */
  	IMX27_FEC,	/* runs on i.mx27/35/51 */
  	IMX28_FEC,
  	IMX6Q_FEC,
@@@ -132,7 -132,7 +132,7 @@@ MODULE_PARM_DESC(macaddr, "FEC Etherne
  #elif defined (CONFIG_M5272C3)
  #define	FEC_FLASHMAC	(0xffe04000 + 4)
  #elif defined(CONFIG_MOD5272)
- #define FEC_FLASHMAC 	0xffc0406b
+ #define FEC_FLASHMAC	0xffc0406b
  #else
  #define	FEC_FLASHMAC	0
  #endif
@@@ -232,7 -232,6 +232,7 @@@ struct fec_enet_private 
  	struct	platform_device *pdev;
  
  	int	opened;
 +	int	dev_id;
  
  	/* Phylib and MDIO interface */
  	struct	mii_bus *mii_bus;
@@@ -260,6 -259,8 +260,8 @@@
  /* Transmitter timeout */
  #define TX_TIMEOUT (2 * HZ)
  
+ static int mii_cnt;
+ 
  static void *swap_buffer(void *bufaddr, int len)
  {
  	int i;
@@@ -516,6 -517,7 +518,7 @@@ fec_stop(struct net_device *ndev
  	struct fec_enet_private *fep = netdev_priv(ndev);
  	const struct platform_device_id *id_entry =
  				platform_get_device_id(fep->pdev);
+ 	u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
  
  	/* We cannot expect a graceful transmit stop without link !!! */
  	if (fep->link) {
@@@ -532,8 -534,10 +535,10 @@@
  	writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
  
  	/* We have to keep ENET enabled to have MII interrupt stay working */
- 	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
+ 	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
  		writel(2, fep->hwp + FEC_ECNTRL);
+ 		writel(rmii_mode, fep->hwp + FEC_R_CNTRL);
+ 	}
  }
  
  
@@@ -819,7 -823,7 +824,7 @@@ static void __inline__ fec_get_mac(stru
  			iap = (unsigned char *)FEC_FLASHMAC;
  #else
  		if (pdata)
- 			memcpy(iap, pdata->mac, ETH_ALEN);
+ 			iap = (unsigned char *)&pdata->mac;
  #endif
  	}
  
@@@ -838,7 -842,7 +843,7 @@@
  
  	/* Adjust MAC if using macaddr */
  	if (iap == macaddr)
 -		 ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id;
 +		 ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->dev_id;
  }
  
  /* ------------------------------------------------------------------------- */
@@@ -866,6 -870,8 +871,8 @@@ static void fec_enet_adjust_link(struc
  	if (phy_dev->link) {
  		if (fep->full_duplex != phy_dev->duplex) {
  			fec_restart(ndev, phy_dev->duplex);
+ 			/* prevent unnecessary second fec_restart() below */
+ 			fep->link = phy_dev->link;
  			status_change = 1;
  		}
  	}
@@@ -954,7 -960,7 +961,7 @@@ static int fec_enet_mii_probe(struct ne
  	char mdio_bus_id[MII_BUS_ID_SIZE];
  	char phy_name[MII_BUS_ID_SIZE + 3];
  	int phy_id;
 -	int dev_id = fep->pdev->id;
 +	int dev_id = fep->dev_id;
  
  	fep->phy_dev = NULL;
  
@@@ -973,8 -979,9 +980,9 @@@
  	}
  
  	if (phy_id >= PHY_MAX_ADDR) {
- 		printk(KERN_INFO "%s: no PHY, assuming direct connection "
- 			"to switch\n", ndev->name);
+ 		printk(KERN_INFO
+ 			"%s: no PHY, assuming direct connection to switch\n",
+ 			ndev->name);
  		strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE);
  		phy_id = 0;
  	}
@@@ -999,8 -1006,9 +1007,9 @@@
  	fep->link = 0;
  	fep->full_duplex = 0;
  
- 	printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] "
- 		"(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name,
+ 	printk(KERN_INFO
+ 		"%s: Freescale FEC PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+ 		ndev->name,
  		fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),
  		fep->phy_dev->irq);
  
@@@ -1032,10 -1040,14 +1041,14 @@@ static int fec_enet_mii_init(struct pla
  	 * mdio interface in board design, and need to be configured by
  	 * fec0 mii_bus.
  	 */
 -	if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id > 0) {
 +	if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) {
  		/* fec1 uses fec0 mii_bus */
- 		fep->mii_bus = fec0_mii_bus;
- 		return 0;
+ 		if (mii_cnt && fec0_mii_bus) {
+ 			fep->mii_bus = fec0_mii_bus;
+ 			mii_cnt++;
+ 			return 0;
+ 		}
+ 		return -ENOENT;
  	}
  
  	fep->mii_timeout = 0;
@@@ -1064,7 -1076,7 +1077,7 @@@
  	fep->mii_bus->read = fec_enet_mdio_read;
  	fep->mii_bus->write = fec_enet_mdio_write;
  	fep->mii_bus->reset = fec_enet_mdio_reset;
 -	snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id + 1);
 +	snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", fep->dev_id + 1);
  	fep->mii_bus->priv = fep;
  	fep->mii_bus->parent = &pdev->dev;
  
@@@ -1080,6 -1092,8 +1093,8 @@@
  	if (mdiobus_register(fep->mii_bus))
  		goto err_out_free_mdio_irq;
  
+ 	mii_cnt++;
+ 
  	/* save fec0 mii_bus */
  	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
  		fec0_mii_bus = fep->mii_bus;
@@@ -1096,11 -1110,11 +1111,11 @@@ err_out
  
  static void fec_enet_mii_remove(struct fec_enet_private *fep)
  {
- 	if (fep->phy_dev)
- 		phy_disconnect(fep->phy_dev);
- 	mdiobus_unregister(fep->mii_bus);
- 	kfree(fep->mii_bus->irq);
- 	mdiobus_free(fep->mii_bus);
+ 	if (--mii_cnt == 0) {
+ 		mdiobus_unregister(fep->mii_bus);
+ 		kfree(fep->mii_bus->irq);
+ 		mdiobus_free(fep->mii_bus);
+ 	}
  }
  
  static int fec_enet_get_settings(struct net_device *ndev,
@@@ -1522,7 -1536,6 +1537,7 @@@ fec_probe(struct platform_device *pdev
  	int i, irq, ret = 0;
  	struct resource *r;
  	const struct of_device_id *of_id;
 +	static int dev_id;
  
  	of_id = of_match_device(fec_dt_ids, &pdev->dev);
  	if (of_id)
@@@ -1550,7 -1563,6 +1565,7 @@@
  
  	fep->hwp = ioremap(r->start, resource_size(r));
  	fep->pdev = pdev;
 +	fep->dev_id = dev_id++;
  
  	if (!fep->hwp) {
  		ret = -ENOMEM;
@@@ -1574,8 -1586,12 +1589,12 @@@
  
  	for (i = 0; i < FEC_IRQ_NUM; i++) {
  		irq = platform_get_irq(pdev, i);
- 		if (i && irq < 0)
- 			break;
+ 		if (irq < 0) {
+ 			if (i)
+ 				break;
+ 			ret = irq;
+ 			goto failed_irq;
+ 		}
  		ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
  		if (ret) {
  			while (--i >= 0) {
@@@ -1586,7 -1602,7 +1605,7 @@@
  		}
  	}
  
- 	fep->clk = clk_get(&pdev->dev, "fec_clk");
+ 	fep->clk = clk_get(&pdev->dev, NULL);
  	if (IS_ERR(fep->clk)) {
  		ret = PTR_ERR(fep->clk);
  		goto failed_clk;
@@@ -1638,13 -1654,18 +1657,18 @@@ fec_drv_remove(struct platform_device *
  	struct net_device *ndev = platform_get_drvdata(pdev);
  	struct fec_enet_private *fep = netdev_priv(ndev);
  	struct resource *r;
+ 	int i;
  
- 	fec_stop(ndev);
+ 	unregister_netdev(ndev);
  	fec_enet_mii_remove(fep);
+ 	for (i = 0; i < FEC_IRQ_NUM; i++) {
+ 		int irq = platform_get_irq(pdev, i);
+ 		if (irq > 0)
+ 			free_irq(irq, ndev);
+ 	}
  	clk_disable(fep->clk);
  	clk_put(fep->clk);
  	iounmap(fep->hwp);
- 	unregister_netdev(ndev);
  	free_netdev(ndev);
  
  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --combined drivers/net/ethernet/micrel/ks8842.c
index de9f2e2,75ec87a..0a85690
--- a/drivers/net/ethernet/micrel/ks8842.c
+++ b/drivers/net/ethernet/micrel/ks8842.c
@@@ -459,7 -459,7 +459,7 @@@ static int ks8842_tx_frame_dma(struct s
  		sg_dma_len(&ctl->sg) += 4 - sg_dma_len(&ctl->sg) % 4;
  
  	ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan,
 -		&ctl->sg, 1, DMA_TO_DEVICE,
 +		&ctl->sg, 1, DMA_MEM_TO_DEV,
  		DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
  	if (!ctl->adesc)
  		return NETDEV_TX_BUSY;
@@@ -571,7 -571,7 +571,7 @@@ static int __ks8842_start_new_rx_dma(st
  		sg_dma_len(sg) = DMA_BUFFER_SIZE;
  
  		ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan,
 -			sg, 1, DMA_FROM_DEVICE,
 +			sg, 1, DMA_DEV_TO_MEM,
  			DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
  
  		if (!ctl->adesc)
@@@ -1264,18 -1264,7 +1264,7 @@@ static struct platform_driver ks8842_pl
  	.remove		= ks8842_remove,
  };
  
- static int __init ks8842_init(void)
- {
- 	return platform_driver_register(&ks8842_platform_driver);
- }
- 
- static void __exit ks8842_exit(void)
- {
- 	platform_driver_unregister(&ks8842_platform_driver);
- }
- 
- module_init(ks8842_init);
- module_exit(ks8842_exit);
+ module_platform_driver(ks8842_platform_driver);
  
  MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver");
  MODULE_AUTHOR("Mocean Laboratories <info at mocean-labs.com>");
diff --combined drivers/net/ethernet/natsemi/macsonic.c
index 5987d17,70367d7..f1b8556
--- a/drivers/net/ethernet/natsemi/macsonic.c
+++ b/drivers/net/ethernet/natsemi/macsonic.c
@@@ -142,7 -142,8 +142,7 @@@ static int macsonic_open(struct net_dev
  {
  	int retval;
  
 -	retval = request_irq(dev->irq, sonic_interrupt, IRQ_FLG_FAST,
 -				"sonic", dev);
 +	retval = request_irq(dev->irq, sonic_interrupt, 0, "sonic", dev);
  	if (retval) {
  		printk(KERN_ERR "%s: unable to get IRQ %d.\n",
  				dev->name, dev->irq);
@@@ -153,8 -154,8 +153,8 @@@
  	 * rupt as well, which must prevent re-entrance of the sonic handler.
  	 */
  	if (dev->irq == IRQ_AUTO_3) {
 -		retval = request_irq(IRQ_NUBUS_9, macsonic_interrupt,
 -					IRQ_FLG_FAST, "sonic", dev);
 +		retval = request_irq(IRQ_NUBUS_9, macsonic_interrupt, 0,
 +				     "sonic", dev);
  		if (retval) {
  			printk(KERN_ERR "%s: unable to get IRQ %d.\n",
  					dev->name, IRQ_NUBUS_9);
@@@ -642,15 -643,4 +642,4 @@@ static struct platform_driver mac_sonic
  	},
  };
  
- static int __init mac_sonic_init_module(void)
- {
- 	return platform_driver_register(&mac_sonic_driver);
- }
- 
- static void __exit mac_sonic_cleanup_module(void)
- {
- 	platform_driver_unregister(&mac_sonic_driver);
- }
- 
- module_init(mac_sonic_init_module);
- module_exit(mac_sonic_cleanup_module);
+ module_platform_driver(mac_sonic_driver);
diff --combined drivers/net/ppp/pptp.c
index f8a6853,ede899c..c1c9293
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@@ -162,7 -162,7 +162,7 @@@ static void del_chan(struct pppox_sock 
  {
  	spin_lock(&chan_lock);
  	clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
- 	rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], NULL);
+ 	RCU_INIT_POINTER(callid_sock[sock->proto.pptp.src_addr.call_id], NULL);
  	spin_unlock(&chan_lock);
  	synchronize_rcu();
  }
@@@ -423,8 -423,10 +423,8 @@@ static int pptp_bind(struct socket *soc
  	lock_sock(sk);
  
  	opt->src_addr = sp->sa_addr.pptp;
 -	if (add_chan(po)) {
 -		release_sock(sk);
 +	if (add_chan(po))
  		error = -EBUSY;
 -	}
  
  	release_sock(sk);
  	return error;
diff --combined drivers/net/wireless/ath/ath9k/main.c
index d2348a5,5007297..7d92004
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@@ -118,7 -118,7 +118,7 @@@ void ath9k_ps_restore(struct ath_softc 
  	if (--sc->ps_usecount != 0)
  		goto unlock;
  
- 	if (sc->ps_idle)
+ 	if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
  		mode = ATH9K_PM_FULL_SLEEP;
  	else if (sc->ps_enabled &&
  		 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
@@@ -286,7 -286,7 +286,7 @@@ static bool ath_complete_reset(struct a
  			ath_start_ani(common);
  	}
  
 -	if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) {
 +	if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) {
  		struct ath_hw_antcomb_conf div_ant_conf;
  		u8 lna_conf;
  
@@@ -332,7 -332,8 +332,8 @@@ static int ath_reset_internal(struct at
  		hchan = ah->curchan;
  	}
  
- 	if (fastcc && !ath9k_hw_check_alive(ah))
+ 	if (fastcc && (ah->chip_fullsleep ||
+ 	    !ath9k_hw_check_alive(ah)))
  		fastcc = false;
  
  	if (!ath_prepare_reset(sc, retry_tx, flush))
@@@ -561,7 -562,6 +562,6 @@@ void ath_ani_calibrate(unsigned long da
  	/* Long calibration runs independently of short calibration. */
  	if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
  		longcal = true;
- 		ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
  		common->ani.longcal_timer = timestamp;
  	}
  
@@@ -569,8 -569,6 +569,6 @@@
  	if (!common->ani.caldone) {
  		if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
  			shortcal = true;
- 			ath_dbg(common, ATH_DBG_ANI,
- 				"shortcal @%lu\n", jiffies);
  			common->ani.shortcal_timer = timestamp;
  			common->ani.resetcal_timer = timestamp;
  		}
@@@ -584,8 -582,9 +582,9 @@@
  	}
  
  	/* Verify whether we must check ANI */
- 	if ((timestamp - common->ani.checkani_timer) >=
- 	     ah->config.ani_poll_interval) {
+ 	if (sc->sc_ah->config.enable_ani
+ 	    && (timestamp - common->ani.checkani_timer) >=
+ 	    ah->config.ani_poll_interval) {
  		aniflag = true;
  		common->ani.checkani_timer = timestamp;
  	}
@@@ -605,6 -604,11 +604,11 @@@
  						ah->rxchainmask, longcal);
  	}
  
+ 	ath_dbg(common, ATH_DBG_ANI,
+ 		"Calibration @%lu finished: %s %s %s, caldone: %s\n", jiffies,
+ 		longcal ? "long" : "", shortcal ? "short" : "",
+ 		aniflag ? "ani" : "", common->ani.caldone ? "true" : "false");
+ 
  	ath9k_ps_restore(sc);
  
  set_timer:
@@@ -630,7 -634,8 +634,8 @@@
  	}
  }
  
- static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
+ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
+ 			    struct ieee80211_vif *vif)
  {
  	struct ath_node *an;
  	an = (struct ath_node *)sta->drv_priv;
@@@ -640,6 -645,7 +645,7 @@@
  	list_add(&an->list, &sc->nodes);
  	spin_unlock(&sc->nodes_lock);
  	an->sta = sta;
+ 	an->vif = vif;
  #endif
  	if (sc->sc_flags & SC_OP_TXAGGR) {
  		ath_tx_node_init(sc, an);
@@@ -740,6 -746,9 +746,9 @@@ void ath9k_tasklet(unsigned long data
  		if (status & ATH9K_INT_GENTIMER)
  			ath_gen_timer_isr(sc->sc_ah);
  
+ 	if (status & ATH9K_INT_MCI)
+ 		ath_mci_intr(sc);
+ 
  out:
  	/* re-enable hardware interrupt */
  	ath9k_hw_enable_interrupts(ah);
@@@ -762,7 -771,8 +771,8 @@@ irqreturn_t ath_isr(int irq, void *dev
  		ATH9K_INT_BMISS |		\
  		ATH9K_INT_CST |			\
  		ATH9K_INT_TSFOOR |		\
- 		ATH9K_INT_GENTIMER)
+ 		ATH9K_INT_GENTIMER |		\
+ 		ATH9K_INT_MCI)
  
  	struct ath_softc *sc = dev;
  	struct ath_hw *ah = sc->sc_ah;
@@@ -880,82 -890,6 +890,6 @@@ chip_reset
  #undef SCHED_INTR
  }
  
- static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
- {
- 	struct ath_hw *ah = sc->sc_ah;
- 	struct ath_common *common = ath9k_hw_common(ah);
- 	struct ieee80211_channel *channel = hw->conf.channel;
- 	int r;
- 
- 	ath9k_ps_wakeup(sc);
- 	spin_lock_bh(&sc->sc_pcu_lock);
- 	atomic_set(&ah->intr_ref_cnt, -1);
- 
- 	ath9k_hw_configpcipowersave(ah, false);
- 
- 	if (!ah->curchan)
- 		ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah);
- 
- 	r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- 	if (r) {
- 		ath_err(common,
- 			"Unable to reset channel (%u MHz), reset status %d\n",
- 			channel->center_freq, r);
- 	}
- 
- 	ath_complete_reset(sc, true);
- 
- 	/* Enable LED */
- 	ath9k_hw_cfg_output(ah, ah->led_pin,
- 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- 	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
- 
- 	spin_unlock_bh(&sc->sc_pcu_lock);
- 
- 	ath9k_ps_restore(sc);
- }
- 
- void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
- {
- 	struct ath_hw *ah = sc->sc_ah;
- 	struct ieee80211_channel *channel = hw->conf.channel;
- 	int r;
- 
- 	ath9k_ps_wakeup(sc);
- 
- 	ath_cancel_work(sc);
- 
- 	spin_lock_bh(&sc->sc_pcu_lock);
- 
- 	/*
- 	 * Keep the LED on when the radio is disabled
- 	 * during idle unassociated state.
- 	 */
- 	if (!sc->ps_idle) {
- 		ath9k_hw_set_gpio(ah, ah->led_pin, 1);
- 		ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
- 	}
- 
- 	ath_prepare_reset(sc, false, true);
- 
- 	if (!ah->curchan)
- 		ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
- 
- 	r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- 	if (r) {
- 		ath_err(ath9k_hw_common(sc->sc_ah),
- 			"Unable to reset channel (%u MHz), reset status %d\n",
- 			channel->center_freq, r);
- 	}
- 
- 	ath9k_hw_phy_disable(ah);
- 
- 	ath9k_hw_configpcipowersave(ah, true);
- 
- 	spin_unlock_bh(&sc->sc_pcu_lock);
- 	ath9k_ps_restore(sc);
- }
- 
  static int ath_reset(struct ath_softc *sc, bool retry_tx)
  {
  	int r;
@@@ -1091,6 -1025,9 +1025,9 @@@ static int ath9k_start(struct ieee80211
  	 * and then setup of the interrupt mask.
  	 */
  	spin_lock_bh(&sc->sc_pcu_lock);
+ 
+ 	atomic_set(&ah->intr_ref_cnt, -1);
+ 
  	r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
  	if (r) {
  		ath_err(common,
@@@ -1117,6 -1054,9 +1054,9 @@@
  	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
  		ah->imask |= ATH9K_INT_CST;
  
+ 	if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
+ 		ah->imask |= ATH9K_INT_MCI;
+ 
  	sc->sc_flags &= ~SC_OP_INVALID;
  	sc->sc_ah->is_monitoring = false;
  
@@@ -1129,12 -1069,25 +1069,25 @@@
  		goto mutex_unlock;
  	}
  
+ 	if (ah->led_pin >= 0) {
+ 		ath9k_hw_cfg_output(ah, ah->led_pin,
+ 				    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ 		ath9k_hw_set_gpio(ah, ah->led_pin, 0);
+ 	}
+ 
+ 	/*
+ 	 * Reset key cache to sane defaults (all entries cleared) instead of
+ 	 * semi-random values after suspend/resume.
+ 	 */
+ 	ath9k_cmn_init_crypto(sc->sc_ah);
+ 
  	spin_unlock_bh(&sc->sc_pcu_lock);
  
  	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
  	    !ah->btcoex_hw.enabled) {
- 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- 					   AR_STOMP_LOW_WLAN_WGHT);
+ 		if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
+ 			ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ 						   AR_STOMP_LOW_WLAN_WGHT);
  		ath9k_hw_btcoex_enable(ah);
  
  		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@@ -1173,6 -1126,13 +1126,13 @@@ static void ath9k_tx(struct ieee80211_h
  		}
  	}
  
+ 	/*
+ 	 * Cannot tx while the hardware is in full sleep, it first needs a full
+ 	 * chip reset to recover from that
+ 	 */
+ 	if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP))
+ 		goto exit;
+ 
  	if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
  		/*
  		 * We are using PS-Poll and mac80211 can request TX while in
@@@ -1219,6 -1179,7 +1179,7 @@@ static void ath9k_stop(struct ieee80211
  	struct ath_softc *sc = hw->priv;
  	struct ath_hw *ah = sc->sc_ah;
  	struct ath_common *common = ath9k_hw_common(ah);
+ 	bool prev_idle;
  
  	mutex_lock(&sc->mutex);
  
@@@ -1237,6 -1198,7 +1198,7 @@@
  		ath9k_hw_btcoex_disable(ah);
  		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
  			ath9k_btcoex_timer_pause(sc);
+ 		ath_mci_flush_profile(&sc->btcoex.mci);
  	}
  
  	spin_lock_bh(&sc->sc_pcu_lock);
@@@ -1248,35 -1210,45 +1210,45 @@@
  	 * before setting the invalid flag. */
  	ath9k_hw_disable_interrupts(ah);
  
- 	if (!(sc->sc_flags & SC_OP_INVALID)) {
- 		ath_drain_all_txq(sc, false);
- 		ath_stoprecv(sc);
- 		ath9k_hw_phy_disable(ah);
- 	} else
- 		sc->rx.rxlink = NULL;
+ 	spin_unlock_bh(&sc->sc_pcu_lock);
+ 
+ 	/* we can now sync irq and kill any running tasklets, since we already
+ 	 * disabled interrupts and not holding a spin lock */
+ 	synchronize_irq(sc->irq);
+ 	tasklet_kill(&sc->intr_tq);
+ 	tasklet_kill(&sc->bcon_tasklet);
+ 
+ 	prev_idle = sc->ps_idle;
+ 	sc->ps_idle = true;
+ 
+ 	spin_lock_bh(&sc->sc_pcu_lock);
+ 
+ 	if (ah->led_pin >= 0) {
+ 		ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+ 		ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
+ 	}
+ 
+ 	ath_prepare_reset(sc, false, true);
  
  	if (sc->rx.frag) {
  		dev_kfree_skb_any(sc->rx.frag);
  		sc->rx.frag = NULL;
  	}
  
- 	/* disable HAL and put h/w to sleep */
- 	ath9k_hw_disable(ah);
+ 	if (!ah->curchan)
+ 		ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
  
- 	spin_unlock_bh(&sc->sc_pcu_lock);
+ 	ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
+ 	ath9k_hw_phy_disable(ah);
  
- 	/* we can now sync irq and kill any running tasklets, since we already
- 	 * disabled interrupts and not holding a spin lock */
- 	synchronize_irq(sc->irq);
- 	tasklet_kill(&sc->intr_tq);
- 	tasklet_kill(&sc->bcon_tasklet);
+ 	ath9k_hw_configpcipowersave(ah, true);
  
- 	ath9k_ps_restore(sc);
+ 	spin_unlock_bh(&sc->sc_pcu_lock);
  
- 	sc->ps_idle = true;
- 	ath_radio_disable(sc, hw);
+ 	ath9k_ps_restore(sc);
  
  	sc->sc_flags |= SC_OP_INVALID;
+ 	sc->ps_idle = prev_idle;
  
  	mutex_unlock(&sc->mutex);
  
@@@ -1616,8 -1588,8 +1588,8 @@@ static int ath9k_config(struct ieee8021
  	struct ath_hw *ah = sc->sc_ah;
  	struct ath_common *common = ath9k_hw_common(ah);
  	struct ieee80211_conf *conf = &hw->conf;
- 	bool disable_radio = false;
  
+ 	ath9k_ps_wakeup(sc);
  	mutex_lock(&sc->mutex);
  
  	/*
@@@ -1628,13 -1600,8 +1600,8 @@@
  	 */
  	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
  		sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
- 		if (!sc->ps_idle) {
- 			ath_radio_enable(sc, hw);
- 			ath_dbg(common, ATH_DBG_CONFIG,
- 				"not-idle: enabling radio\n");
- 		} else {
- 			disable_radio = true;
- 		}
+ 		if (sc->ps_idle)
+ 			ath_cancel_work(sc);
  	}
  
  	/*
@@@ -1741,18 -1708,12 +1708,12 @@@
  		ath_dbg(common, ATH_DBG_CONFIG,
  			"Set power: %d\n", conf->power_level);
  		sc->config.txpowlimit = 2 * conf->power_level;
- 		ath9k_ps_wakeup(sc);
  		ath9k_cmn_update_txpow(ah, sc->curtxpow,
  				       sc->config.txpowlimit, &sc->curtxpow);
  	}
  
  	mutex_unlock(&sc->mutex);
+ 	ath9k_ps_restore(sc);
  
  	return 0;
  }
@@@ -1798,7 -1759,7 +1759,7 @@@ static int ath9k_sta_add(struct ieee802
  	struct ath_node *an = (struct ath_node *) sta->drv_priv;
  	struct ieee80211_key_conf ps_key = { };
  
- 	ath_node_attach(sc, sta);
+ 	ath_node_attach(sc, sta, vif);
  
  	if (vif->type != NL80211_IFTYPE_AP &&
  	    vif->type != NL80211_IFTYPE_AP_VLAN)
@@@ -2320,9 -2281,6 +2281,6 @@@ static void ath9k_flush(struct ieee8021
  		return;
  	}
  
- 	if (drop)
- 		timeout = 1;
- 
  	for (j = 0; j < timeout; j++) {
  		bool npend = false;
  
@@@ -2340,21 -2298,22 +2298,22 @@@
  		}
  
  		if (!npend)
- 		    goto out;
+ 		    break;
  	}
  
- 	ath9k_ps_wakeup(sc);
- 	spin_lock_bh(&sc->sc_pcu_lock);
- 	drain_txq = ath_drain_all_txq(sc, false);
- 	spin_unlock_bh(&sc->sc_pcu_lock);
+ 	if (drop) {
+ 		ath9k_ps_wakeup(sc);
+ 		spin_lock_bh(&sc->sc_pcu_lock);
+ 		drain_txq = ath_drain_all_txq(sc, false);
+ 		spin_unlock_bh(&sc->sc_pcu_lock);
  
- 	if (!drain_txq)
- 		ath_reset(sc, false);
+ 		if (!drain_txq)
+ 			ath_reset(sc, false);
  
- 	ath9k_ps_restore(sc);
- 	ieee80211_wake_queues(hw);
+ 		ath9k_ps_restore(sc);
+ 		ieee80211_wake_queues(hw);
+ 	}
  
- out:
  	ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
  	mutex_unlock(&sc->mutex);
  }
diff --combined drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index df1540c,a1a95d5..67c66dc
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@@ -91,10 -91,7 +91,10 @@@ static void iwlagn_tx_cmd_build_basic(s
  		tx_cmd->tid_tspec = qc[0] & 0xf;
  		tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
  	} else {
 -		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
 +		if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
 +			tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
 +		else
 +			tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
  	}
  
  	iwlagn_tx_cmd_protection(priv, info, fc, &tx_flags);
@@@ -286,6 -283,19 +286,19 @@@ int iwlagn_tx_skb(struct iwl_priv *priv
  		IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
  #endif
  
+ 	if (unlikely(ieee80211_is_probe_resp(fc))) {
+ 		struct iwl_wipan_noa_data *noa_data =
+ 			rcu_dereference(priv->noa_data);
+ 
+ 		if (noa_data &&
+ 		    pskb_expand_head(skb, 0, noa_data->length,
+ 				     GFP_ATOMIC) == 0) {
+ 			memcpy(skb_put(skb, noa_data->length),
+ 			       noa_data->data, noa_data->length);
+ 			hdr = (struct ieee80211_hdr *)skb->data;
+ 		}
+ 	}
+ 
  	hdr_len = ieee80211_hdrlen(fc);
  
  	/* For management frames use broadcast id to do not break aggregation */
@@@ -780,6 -790,7 +793,7 @@@ int iwlagn_rx_reply_tx(struct iwl_priv 
  		iwl_rx_reply_tx_agg(priv, tx_resp);
  
  	if (tx_resp->frame_count == 1) {
+ 		IWL_DEBUG_TX_REPLY(priv, "Q %d, ssn %d", txq_id, ssn);
  		__skb_queue_head_init(&skbs);
  		/*we can free until ssn % q.n_bd not inclusive */
  		iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
@@@ -803,7 -814,8 +817,8 @@@
  			    iwl_is_associated_ctx(ctx) && ctx->vif &&
  			    ctx->vif->type == NL80211_IFTYPE_STATION) {
  				ctx->last_tx_rejected = true;
- 				iwl_trans_stop_queue(trans(priv), txq_id);
+ 				iwl_trans_stop_queue(trans(priv), txq_id,
+ 					"Tx on passive channel");
  
  				IWL_DEBUG_TX_REPLY(priv,
  					   "TXQ %d status %s (0x%08x) "
@@@ -909,11 -921,9 +924,9 @@@ int iwlagn_rx_reply_compressed_ba(struc
  			   ba_resp->sta_id);
  	IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, "
  			   "scd_flow = %d, scd_ssn = %d\n",
- 			   ba_resp->tid,
- 			   ba_resp->seq_ctl,
+ 			   ba_resp->tid, ba_resp->seq_ctl,
  			   (unsigned long long)le64_to_cpu(ba_resp->bitmap),
- 			   ba_resp->scd_flow,
- 			   ba_resp->scd_ssn);
+ 			   scd_flow, ba_resp_scd_ssn);
  
  	/* Mark that the expected block-ack response arrived */
  	agg->wait_for_ba = false;
diff --combined net/batman-adv/translation-table.c
index 5f09a57,cc87acf..dc0779b
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@@ -36,18 -36,9 +36,9 @@@ static void _tt_global_del(struct bat_p
  static void tt_purge(struct work_struct *work);
  
  /* returns 1 if they are the same mac addr */
- static int compare_ltt(const struct hlist_node *node, const void *data2)
+ static int compare_tt(const struct hlist_node *node, const void *data2)
  {
- 	const void *data1 = container_of(node, struct tt_local_entry,
- 					 hash_entry);
- 
- 	return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
- }
- 
- /* returns 1 if they are the same mac addr */
- static int compare_gtt(const struct hlist_node *node, const void *data2)
- {
- 	const void *data1 = container_of(node, struct tt_global_entry,
+ 	const void *data1 = container_of(node, struct tt_common_entry,
  					 hash_entry);
  
  	return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
@@@ -60,14 -51,13 +51,13 @@@ static void tt_start_timer(struct bat_p
  			   msecs_to_jiffies(5000));
  }
  
- static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv,
- 						 const void *data)
+ static struct tt_common_entry *tt_hash_find(struct hashtable_t *hash,
+ 					    const void *data)
  {
- 	struct hashtable_t *hash = bat_priv->tt_local_hash;
  	struct hlist_head *head;
  	struct hlist_node *node;
- 	struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL;
- 	int index;
+ 	struct tt_common_entry *tt_common_entry, *tt_common_entry_tmp = NULL;
+ 	uint32_t index;
  
  	if (!hash)
  		return NULL;
@@@ -76,51 -66,46 +66,46 @@@
  	head = &hash->table[index];
  
  	rcu_read_lock();
- 	hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) {
- 		if (!compare_eth(tt_local_entry, data))
+ 	hlist_for_each_entry_rcu(tt_common_entry, node, head, hash_entry) {
+ 		if (!compare_eth(tt_common_entry, data))
  			continue;
  
- 		if (!atomic_inc_not_zero(&tt_local_entry->refcount))
+ 		if (!atomic_inc_not_zero(&tt_common_entry->refcount))
  			continue;
  
- 		tt_local_entry_tmp = tt_local_entry;
+ 		tt_common_entry_tmp = tt_common_entry;
  		break;
  	}
  	rcu_read_unlock();
  
- 	return tt_local_entry_tmp;
+ 	return tt_common_entry_tmp;
  }
  
- static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
- 						   const void *data)
+ static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv,
+ 						 const void *data)
  {
- 	struct hashtable_t *hash = bat_priv->tt_global_hash;
- 	struct hlist_head *head;
- 	struct hlist_node *node;
- 	struct tt_global_entry *tt_global_entry;
- 	struct tt_global_entry *tt_global_entry_tmp = NULL;
- 	int index;
- 
- 	if (!hash)
- 		return NULL;
- 
- 	index = choose_orig(data, hash->size);
- 	head = &hash->table[index];
+ 	struct tt_common_entry *tt_common_entry;
+ 	struct tt_local_entry *tt_local_entry = NULL;
  
- 	rcu_read_lock();
- 	hlist_for_each_entry_rcu(tt_global_entry, node, head, hash_entry) {
- 		if (!compare_eth(tt_global_entry, data))
- 			continue;
+ 	tt_common_entry = tt_hash_find(bat_priv->tt_local_hash, data);
+ 	if (tt_common_entry)
+ 		tt_local_entry = container_of(tt_common_entry,
+ 					      struct tt_local_entry, common);
+ 	return tt_local_entry;
+ }
  
- 		if (!atomic_inc_not_zero(&tt_global_entry->refcount))
- 			continue;
+ static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
+ 						   const void *data)
+ {
+ 	struct tt_common_entry *tt_common_entry;
+ 	struct tt_global_entry *tt_global_entry = NULL;
  
- 		tt_global_entry_tmp = tt_global_entry;
- 		break;
- 	}
- 	rcu_read_unlock();
+ 	tt_common_entry = tt_hash_find(bat_priv->tt_global_hash, data);
+ 	if (tt_common_entry)
+ 		tt_global_entry = container_of(tt_common_entry,
+ 					       struct tt_global_entry, common);
+ 	return tt_global_entry;
  
- 	return tt_global_entry_tmp;
  }
  
  static bool is_out_of_time(unsigned long starting_time, unsigned long timeout)
@@@ -133,15 -118,18 +118,18 @@@
  
  static void tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry)
  {
- 	if (atomic_dec_and_test(&tt_local_entry->refcount))
- 		kfree_rcu(tt_local_entry, rcu);
+ 	if (atomic_dec_and_test(&tt_local_entry->common.refcount))
+ 		kfree_rcu(tt_local_entry, common.rcu);
  }
  
  static void tt_global_entry_free_rcu(struct rcu_head *rcu)
  {
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_global_entry *tt_global_entry;
  
- 	tt_global_entry = container_of(rcu, struct tt_global_entry, rcu);
+ 	tt_common_entry = container_of(rcu, struct tt_common_entry, rcu);
+ 	tt_global_entry = container_of(tt_common_entry, struct tt_global_entry,
+ 				       common);
  
  	if (tt_global_entry->orig_node)
  		orig_node_free_ref(tt_global_entry->orig_node);
@@@ -151,8 -139,9 +139,9 @@@
  
  static void tt_global_entry_free_ref(struct tt_global_entry *tt_global_entry)
  {
- 	if (atomic_dec_and_test(&tt_global_entry->refcount))
- 		call_rcu(&tt_global_entry->rcu, tt_global_entry_free_rcu);
+ 	if (atomic_dec_and_test(&tt_global_entry->common.refcount))
+ 		call_rcu(&tt_global_entry->common.rcu,
+ 			 tt_global_entry_free_rcu);
  }
  
  static void tt_local_event(struct bat_priv *bat_priv, const uint8_t *addr,
@@@ -201,6 -190,7 +190,7 @@@ void tt_local_add(struct net_device *so
  	struct bat_priv *bat_priv = netdev_priv(soft_iface);
  	struct tt_local_entry *tt_local_entry = NULL;
  	struct tt_global_entry *tt_global_entry = NULL;
+ 	int hash_added;
  
  	tt_local_entry = tt_local_hash_find(bat_priv, addr);
  
@@@ -217,26 -207,33 +207,33 @@@
  		"Creating new local tt entry: %pM (ttvn: %d)\n", addr,
  		(uint8_t)atomic_read(&bat_priv->ttvn));
  
- 	memcpy(tt_local_entry->addr, addr, ETH_ALEN);
- 	tt_local_entry->last_seen = jiffies;
- 	tt_local_entry->flags = NO_FLAGS;
+ 	memcpy(tt_local_entry->common.addr, addr, ETH_ALEN);
+ 	tt_local_entry->common.flags = NO_FLAGS;
  	if (is_wifi_iface(ifindex))
- 		tt_local_entry->flags |= TT_CLIENT_WIFI;
- 	atomic_set(&tt_local_entry->refcount, 2);
+ 		tt_local_entry->common.flags |= TT_CLIENT_WIFI;
+ 	atomic_set(&tt_local_entry->common.refcount, 2);
+ 	tt_local_entry->last_seen = jiffies;
  
  	/* the batman interface mac address should never be purged */
  	if (compare_eth(addr, soft_iface->dev_addr))
- 		tt_local_entry->flags |= TT_CLIENT_NOPURGE;
+ 		tt_local_entry->common.flags |= TT_CLIENT_NOPURGE;
+ 
+ 	hash_added = hash_add(bat_priv->tt_local_hash, compare_tt, choose_orig,
+ 			 &tt_local_entry->common,
+ 			 &tt_local_entry->common.hash_entry);
+ 
+ 	if (unlikely(hash_added != 0)) {
+ 		/* remove the reference for the hash */
+ 		tt_local_entry_free_ref(tt_local_entry);
+ 		goto out;
+ 	}
  
- 	tt_local_event(bat_priv, addr, tt_local_entry->flags);
+ 	tt_local_event(bat_priv, addr, tt_local_entry->common.flags);
  
  	/* The local entry has to be marked as NEW to avoid to send it in
  	 * a full table response going out before the next ttvn increment
  	 * (consistency check) */
- 	tt_local_entry->flags |= TT_CLIENT_NEW;
- 
- 	hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
- 		 tt_local_entry, &tt_local_entry->hash_entry);
+ 	tt_local_entry->common.flags |= TT_CLIENT_NEW;
  
  	/* remove address from global hash if present */
  	tt_global_entry = tt_global_hash_find(bat_priv, addr);
@@@ -245,12 -242,10 +242,12 @@@
  	if (tt_global_entry) {
  		/* This node is probably going to update its tt table */
  		tt_global_entry->orig_node->tt_poss_change = true;
 -		/* The global entry has to be marked as PENDING and has to be
 +		/* The global entry has to be marked as ROAMING and has to be
  		 * kept for consistency purpose */
- 		tt_global_entry->flags |= TT_CLIENT_ROAM;
 -		tt_global_entry->common.flags |= TT_CLIENT_PENDING;
++		tt_global_entry->common.flags |= TT_CLIENT_ROAM;
 +		tt_global_entry->roam_at = jiffies;
 +
- 		send_roam_adv(bat_priv, tt_global_entry->addr,
+ 		send_roam_adv(bat_priv, tt_global_entry->common.addr,
  			      tt_global_entry->orig_node);
  	}
  out:
@@@ -312,13 -307,12 +309,12 @@@ int tt_local_seq_print_text(struct seq_
  	struct net_device *net_dev = (struct net_device *)seq->private;
  	struct bat_priv *bat_priv = netdev_priv(net_dev);
  	struct hashtable_t *hash = bat_priv->tt_local_hash;
- 	struct tt_local_entry *tt_local_entry;
+ 	struct tt_common_entry *tt_common_entry;
  	struct hard_iface *primary_if;
  	struct hlist_node *node;
  	struct hlist_head *head;
- 	size_t buf_size, pos;
- 	char *buff;
- 	int i, ret = 0;
+ 	uint32_t i;
+ 	int ret = 0;
  
  	primary_if = primary_if_get_selected(bat_priv);
  	if (!primary_if) {
@@@ -339,51 -333,27 +335,27 @@@
  		   "announced via TT (TTVN: %u):\n",
  		   net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn));
  
- 	buf_size = 1;
- 	/* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
- 	for (i = 0; i < hash->size; i++) {
- 		head = &hash->table[i];
- 
- 		rcu_read_lock();
- 		__hlist_for_each_rcu(node, head)
- 			buf_size += 29;
- 		rcu_read_unlock();
- 	}
- 
- 	buff = kmalloc(buf_size, GFP_ATOMIC);
- 	if (!buff) {
- 		ret = -ENOMEM;
- 		goto out;
- 	}
- 
- 	buff[0] = '\0';
- 	pos = 0;
- 
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
- 		hlist_for_each_entry_rcu(tt_local_entry, node,
+ 		hlist_for_each_entry_rcu(tt_common_entry, node,
  					 head, hash_entry) {
- 			pos += snprintf(buff + pos, 30, " * %pM "
- 					"[%c%c%c%c%c]\n",
- 					tt_local_entry->addr,
- 					(tt_local_entry->flags &
+ 			seq_printf(seq, " * %pM [%c%c%c%c%c]\n",
+ 					tt_common_entry->addr,
+ 					(tt_common_entry->flags &
  					 TT_CLIENT_ROAM ? 'R' : '.'),
- 					(tt_local_entry->flags &
+ 					(tt_common_entry->flags &
  					 TT_CLIENT_NOPURGE ? 'P' : '.'),
- 					(tt_local_entry->flags &
+ 					(tt_common_entry->flags &
  					 TT_CLIENT_NEW ? 'N' : '.'),
- 					(tt_local_entry->flags &
+ 					(tt_common_entry->flags &
  					 TT_CLIENT_PENDING ? 'X' : '.'),
- 					(tt_local_entry->flags &
+ 					(tt_common_entry->flags &
  					 TT_CLIENT_WIFI ? 'W' : '.'));
  		}
  		rcu_read_unlock();
  	}
- 
- 	seq_printf(seq, "%s", buff);
- 	kfree(buff);
  out:
  	if (primary_if)
  		hardif_free_ref(primary_if);
@@@ -394,13 -364,13 +366,13 @@@ static void tt_local_set_pending(struc
  				 struct tt_local_entry *tt_local_entry,
  				 uint16_t flags)
  {
- 	tt_local_event(bat_priv, tt_local_entry->addr,
- 		       tt_local_entry->flags | flags);
+ 	tt_local_event(bat_priv, tt_local_entry->common.addr,
+ 		       tt_local_entry->common.flags | flags);
  
  	/* The local client has to be marked as "pending to be removed" but has
  	 * to be kept in the table in order to send it in a full table
  	 * response issued before the net ttvn increment (consistency check) */
- 	tt_local_entry->flags |= TT_CLIENT_PENDING;
+ 	tt_local_entry->common.flags |= TT_CLIENT_PENDING;
  }
  
  void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
@@@ -416,7 -386,7 +388,7 @@@
  			     (roaming ? TT_CLIENT_ROAM : NO_FLAGS));
  
  	bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) pending to be removed: "
- 		"%s\n", tt_local_entry->addr, message);
+ 		"%s\n", tt_local_entry->common.addr, message);
  out:
  	if (tt_local_entry)
  		tt_local_entry_free_ref(tt_local_entry);
@@@ -426,23 -396,27 +398,27 @@@ static void tt_local_purge(struct bat_p
  {
  	struct hashtable_t *hash = bat_priv->tt_local_hash;
  	struct tt_local_entry *tt_local_entry;
+ 	struct tt_common_entry *tt_common_entry;
  	struct hlist_node *node, *node_tmp;
  	struct hlist_head *head;
  	spinlock_t *list_lock; /* protects write access to the hash lists */
- 	int i;
+ 	uint32_t i;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
- 		hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
+ 		hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
  					  head, hash_entry) {
- 			if (tt_local_entry->flags & TT_CLIENT_NOPURGE)
+ 			tt_local_entry = container_of(tt_common_entry,
+ 						      struct tt_local_entry,
+ 						      common);
+ 			if (tt_local_entry->common.flags & TT_CLIENT_NOPURGE)
  				continue;
  
  			/* entry already marked for deletion */
- 			if (tt_local_entry->flags & TT_CLIENT_PENDING)
+ 			if (tt_local_entry->common.flags & TT_CLIENT_PENDING)
  				continue;
  
  			if (!is_out_of_time(tt_local_entry->last_seen,
@@@ -453,7 -427,7 +429,7 @@@
  					     TT_CLIENT_DEL);
  			bat_dbg(DBG_TT, bat_priv, "Local tt entry (%pM) "
  				"pending to be removed: timed out\n",
- 				tt_local_entry->addr);
+ 				tt_local_entry->common.addr);
  		}
  		spin_unlock_bh(list_lock);
  	}
@@@ -464,10 -438,11 +440,11 @@@ static void tt_local_table_free(struct 
  {
  	struct hashtable_t *hash;
  	spinlock_t *list_lock; /* protects write access to the hash lists */
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_local_entry *tt_local_entry;
  	struct hlist_node *node, *node_tmp;
  	struct hlist_head *head;
- 	int i;
+ 	uint32_t i;
  
  	if (!bat_priv->tt_local_hash)
  		return;
@@@ -479,9 -454,12 +456,12 @@@
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
- 		hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
+ 		hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
  					  head, hash_entry) {
  			hlist_del_rcu(node);
+ 			tt_local_entry = container_of(tt_common_entry,
+ 						      struct tt_local_entry,
+ 						      common);
  			tt_local_entry_free_ref(tt_local_entry);
  		}
  		spin_unlock_bh(list_lock);
@@@ -529,6 -507,7 +509,7 @@@ int tt_global_add(struct bat_priv *bat_
  	struct tt_global_entry *tt_global_entry;
  	struct orig_node *orig_node_tmp;
  	int ret = 0;
+ 	int hash_added;
  
  	tt_global_entry = tt_global_hash_find(bat_priv, tt_addr);
  
@@@ -539,18 -518,24 +520,24 @@@
  		if (!tt_global_entry)
  			goto out;
  
- 		memcpy(tt_global_entry->addr, tt_addr, ETH_ALEN);
+ 		memcpy(tt_global_entry->common.addr, tt_addr, ETH_ALEN);
+ 		tt_global_entry->common.flags = NO_FLAGS;
+ 		atomic_set(&tt_global_entry->common.refcount, 2);
  		/* Assign the new orig_node */
  		atomic_inc(&orig_node->refcount);
  		tt_global_entry->orig_node = orig_node;
  		tt_global_entry->ttvn = ttvn;
- 		tt_global_entry->flags = NO_FLAGS;
  		tt_global_entry->roam_at = 0;
- 		atomic_set(&tt_global_entry->refcount, 2);
  
- 		hash_add(bat_priv->tt_global_hash, compare_gtt,
- 			 choose_orig, tt_global_entry,
- 			 &tt_global_entry->hash_entry);
+ 		hash_added = hash_add(bat_priv->tt_global_hash, compare_tt,
+ 				 choose_orig, &tt_global_entry->common,
+ 				 &tt_global_entry->common.hash_entry);
+ 
+ 		if (unlikely(hash_added != 0)) {
+ 			/* remove the reference for the hash */
+ 			tt_global_entry_free_ref(tt_global_entry);
+ 			goto out_remove;
+ 		}
  		atomic_inc(&orig_node->tt_size);
  	} else {
  		if (tt_global_entry->orig_node != orig_node) {
@@@ -561,20 -546,21 +548,21 @@@
  			orig_node_free_ref(orig_node_tmp);
  			atomic_inc(&orig_node->tt_size);
  		}
+ 		tt_global_entry->common.flags = NO_FLAGS;
  		tt_global_entry->ttvn = ttvn;
- 		tt_global_entry->flags = NO_FLAGS;
  		tt_global_entry->roam_at = 0;
  	}
  
  	if (wifi)
- 		tt_global_entry->flags |= TT_CLIENT_WIFI;
+ 		tt_global_entry->common.flags |= TT_CLIENT_WIFI;
  
  	bat_dbg(DBG_TT, bat_priv,
  		"Creating new global tt entry: %pM (via %pM)\n",
- 		tt_global_entry->addr, orig_node->orig);
+ 		tt_global_entry->common.addr, orig_node->orig);
  
+ out_remove:
  	/* remove address from local hash if present */
- 	tt_local_remove(bat_priv, tt_global_entry->addr,
+ 	tt_local_remove(bat_priv, tt_global_entry->common.addr,
  			"global tt received", roaming);
  	ret = 1;
  out:
@@@ -588,13 -574,13 +576,13 @@@ int tt_global_seq_print_text(struct seq
  	struct net_device *net_dev = (struct net_device *)seq->private;
  	struct bat_priv *bat_priv = netdev_priv(net_dev);
  	struct hashtable_t *hash = bat_priv->tt_global_hash;
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_global_entry *tt_global_entry;
  	struct hard_iface *primary_if;
  	struct hlist_node *node;
  	struct hlist_head *head;
- 	size_t buf_size, pos;
- 	char *buff;
- 	int i, ret = 0;
+ 	uint32_t i;
+ 	int ret = 0;
  
  	primary_if = primary_if_get_selected(bat_priv);
  	if (!primary_if) {
@@@ -617,53 -603,32 +605,32 @@@
  	seq_printf(seq, "       %-13s %s       %-15s %s %s\n",
  		   "Client", "(TTVN)", "Originator", "(Curr TTVN)", "Flags");
  
- 	buf_size = 1;
- 	/* Estimate length for: " * xx:xx:xx:xx:xx:xx (ttvn) via
- 	 * xx:xx:xx:xx:xx:xx (cur_ttvn)\n"*/
- 	for (i = 0; i < hash->size; i++) {
- 		head = &hash->table[i];
- 
- 		rcu_read_lock();
- 		__hlist_for_each_rcu(node, head)
- 			buf_size += 67;
- 		rcu_read_unlock();
- 	}
- 
- 	buff = kmalloc(buf_size, GFP_ATOMIC);
- 	if (!buff) {
- 		ret = -ENOMEM;
- 		goto out;
- 	}
- 
- 	buff[0] = '\0';
- 	pos = 0;
- 
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
- 		hlist_for_each_entry_rcu(tt_global_entry, node,
+ 		hlist_for_each_entry_rcu(tt_common_entry, node,
  					 head, hash_entry) {
- 			pos += snprintf(buff + pos, 69,
- 					" * %pM  (%3u) via %pM     (%3u)   "
- 					"[%c%c%c]\n", tt_global_entry->addr,
+ 			tt_global_entry = container_of(tt_common_entry,
+ 						       struct tt_global_entry,
+ 						       common);
+ 			seq_printf(seq, " * %pM  (%3u) via %pM     (%3u)   "
+ 					"[%c%c%c]\n",
+ 					tt_global_entry->common.addr,
  					tt_global_entry->ttvn,
  					tt_global_entry->orig_node->orig,
  					(uint8_t) atomic_read(
  						&tt_global_entry->orig_node->
  						last_ttvn),
- 					(tt_global_entry->flags &
+ 					(tt_global_entry->common.flags &
  					 TT_CLIENT_ROAM ? 'R' : '.'),
- 					(tt_global_entry->flags &
+ 					(tt_global_entry->common.flags &
  					 TT_CLIENT_PENDING ? 'X' : '.'),
- 					(tt_global_entry->flags &
+ 					(tt_global_entry->common.flags &
  					 TT_CLIENT_WIFI ? 'W' : '.'));
  		}
  		rcu_read_unlock();
  	}
- 
- 	seq_printf(seq, "%s", buff);
- 	kfree(buff);
  out:
  	if (primary_if)
  		hardif_free_ref(primary_if);
@@@ -679,13 -644,13 +646,13 @@@ static void _tt_global_del(struct bat_p
  
  	bat_dbg(DBG_TT, bat_priv,
  		"Deleting global tt entry %pM (via %pM): %s\n",
- 		tt_global_entry->addr, tt_global_entry->orig_node->orig,
+ 		tt_global_entry->common.addr, tt_global_entry->orig_node->orig,
  		message);
  
  	atomic_dec(&tt_global_entry->orig_node->tt_size);
  
- 	hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
- 		    tt_global_entry->addr);
+ 	hash_remove(bat_priv->tt_global_hash, compare_tt, choose_orig,
+ 		    tt_global_entry->common.addr);
  out:
  	if (tt_global_entry)
  		tt_global_entry_free_ref(tt_global_entry);
@@@ -696,7 -661,6 +663,7 @@@ void tt_global_del(struct bat_priv *bat
  		   const char *message, bool roaming)
  {
  	struct tt_global_entry *tt_global_entry = NULL;
 +	struct tt_local_entry *tt_local_entry = NULL;
  
  	tt_global_entry = tt_global_hash_find(bat_priv, addr);
  	if (!tt_global_entry)
@@@ -704,36 -668,23 +671,37 @@@
  
  	if (tt_global_entry->orig_node == orig_node) {
  		if (roaming) {
 -			tt_global_entry->common.flags |= TT_CLIENT_ROAM;
 -			tt_global_entry->roam_at = jiffies;
 -			goto out;
 +			/* if we are deleting a global entry due to a roam
 +			 * event, there are two possibilities:
 +			 * 1) the client roamed from node A to node B => we mark
 +			 *    it with TT_CLIENT_ROAM, we start a timer and we
 +			 *    wait for node B to claim it. In case of timeout
 +			 *    the entry is purged.
 +			 * 2) the client roamed to us => we can directly delete
 +			 *    the global entry, since it is useless now. */
 +			tt_local_entry = tt_local_hash_find(bat_priv,
- 							tt_global_entry->addr);
++							tt_global_entry->common.addr);
 +			if (!tt_local_entry) {
- 				tt_global_entry->flags |= TT_CLIENT_ROAM;
++				tt_global_entry->common.flags |= TT_CLIENT_ROAM;
 +				tt_global_entry->roam_at = jiffies;
 +				goto out;
 +			}
  		}
  		_tt_global_del(bat_priv, tt_global_entry, message);
  	}
  out:
  	if (tt_global_entry)
  		tt_global_entry_free_ref(tt_global_entry);
 +	if (tt_local_entry)
 +		tt_local_entry_free_ref(tt_local_entry);
  }
  
  void tt_global_del_orig(struct bat_priv *bat_priv,
  			struct orig_node *orig_node, const char *message)
  {
  	struct tt_global_entry *tt_global_entry;
- 	int i;
+ 	struct tt_common_entry *tt_common_entry;
+ 	uint32_t i;
  	struct hashtable_t *hash = bat_priv->tt_global_hash;
  	struct hlist_node *node, *safe;
  	struct hlist_head *head;
@@@ -747,14 -698,18 +715,18 @@@
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
- 		hlist_for_each_entry_safe(tt_global_entry, node, safe,
+ 		hlist_for_each_entry_safe(tt_common_entry, node, safe,
  					 head, hash_entry) {
+ 			tt_global_entry = container_of(tt_common_entry,
+ 						       struct tt_global_entry,
+ 						       common);
  			if (tt_global_entry->orig_node == orig_node) {
  				bat_dbg(DBG_TT, bat_priv,
  					"Deleting global tt entry %pM "
- 					"(via %pM): originator time out\n",
- 					tt_global_entry->addr,
- 					tt_global_entry->orig_node->orig);
+ 					"(via %pM): %s\n",
+ 					tt_global_entry->common.addr,
+ 					tt_global_entry->orig_node->orig,
+ 					message);
  				hlist_del_rcu(node);
  				tt_global_entry_free_ref(tt_global_entry);
  			}
@@@ -767,20 -722,24 +739,24 @@@
  static void tt_global_roam_purge(struct bat_priv *bat_priv)
  {
  	struct hashtable_t *hash = bat_priv->tt_global_hash;
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_global_entry *tt_global_entry;
  	struct hlist_node *node, *node_tmp;
  	struct hlist_head *head;
  	spinlock_t *list_lock; /* protects write access to the hash lists */
- 	int i;
+ 	uint32_t i;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
- 		hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
+ 		hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
  					  head, hash_entry) {
- 			if (!(tt_global_entry->flags & TT_CLIENT_ROAM))
+ 			tt_global_entry = container_of(tt_common_entry,
+ 						       struct tt_global_entry,
+ 						       common);
+ 			if (!(tt_global_entry->common.flags & TT_CLIENT_ROAM))
  				continue;
  			if (!is_out_of_time(tt_global_entry->roam_at,
  					    TT_CLIENT_ROAM_TIMEOUT * 1000))
@@@ -788,7 -747,7 +764,7 @@@
  
  			bat_dbg(DBG_TT, bat_priv, "Deleting global "
  				"tt entry (%pM): Roaming timeout\n",
- 				tt_global_entry->addr);
+ 				tt_global_entry->common.addr);
  			atomic_dec(&tt_global_entry->orig_node->tt_size);
  			hlist_del_rcu(node);
  			tt_global_entry_free_ref(tt_global_entry);
@@@ -802,10 -761,11 +778,11 @@@ static void tt_global_table_free(struc
  {
  	struct hashtable_t *hash;
  	spinlock_t *list_lock; /* protects write access to the hash lists */
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_global_entry *tt_global_entry;
  	struct hlist_node *node, *node_tmp;
  	struct hlist_head *head;
- 	int i;
+ 	uint32_t i;
  
  	if (!bat_priv->tt_global_hash)
  		return;
@@@ -817,9 -777,12 +794,12 @@@
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
- 		hlist_for_each_entry_safe(tt_global_entry, node, node_tmp,
+ 		hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
  					  head, hash_entry) {
  			hlist_del_rcu(node);
+ 			tt_global_entry = container_of(tt_common_entry,
+ 						       struct tt_global_entry,
+ 						       common);
  			tt_global_entry_free_ref(tt_global_entry);
  		}
  		spin_unlock_bh(list_lock);
@@@ -835,8 -798,8 +815,8 @@@ static bool _is_ap_isolated(struct tt_l
  {
  	bool ret = false;
  
- 	if (tt_local_entry->flags & TT_CLIENT_WIFI &&
- 	    tt_global_entry->flags & TT_CLIENT_WIFI)
+ 	if (tt_local_entry->common.flags & TT_CLIENT_WIFI &&
+ 	    tt_global_entry->common.flags & TT_CLIENT_WIFI)
  		ret = true;
  
  	return ret;
@@@ -869,7 -832,7 +849,7 @@@ struct orig_node *transtable_search(str
  
  	/* A global client marked as PENDING has already moved from that
  	 * originator */
- 	if (tt_global_entry->flags & TT_CLIENT_PENDING)
+ 	if (tt_global_entry->common.flags & TT_CLIENT_PENDING)
  		goto out;
  
  	orig_node = tt_global_entry->orig_node;
@@@ -888,29 -851,34 +868,34 @@@ uint16_t tt_global_crc(struct bat_priv 
  {
  	uint16_t total = 0, total_one;
  	struct hashtable_t *hash = bat_priv->tt_global_hash;
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_global_entry *tt_global_entry;
  	struct hlist_node *node;
  	struct hlist_head *head;
- 	int i, j;
+ 	uint32_t i;
+ 	int j;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
- 		hlist_for_each_entry_rcu(tt_global_entry, node,
+ 		hlist_for_each_entry_rcu(tt_common_entry, node,
  					 head, hash_entry) {
+ 			tt_global_entry = container_of(tt_common_entry,
+ 						       struct tt_global_entry,
+ 						       common);
  			if (compare_eth(tt_global_entry->orig_node,
  					orig_node)) {
  				/* Roaming clients are in the global table for
  				 * consistency only. They don't have to be
  				 * taken into account while computing the
  				 * global crc */
- 				if (tt_global_entry->flags & TT_CLIENT_ROAM)
+ 				if (tt_common_entry->flags & TT_CLIENT_ROAM)
  					continue;
  				total_one = 0;
  				for (j = 0; j < ETH_ALEN; j++)
  					total_one = crc16_byte(total_one,
- 						tt_global_entry->addr[j]);
+ 						tt_common_entry->addr[j]);
  				total ^= total_one;
  			}
  		}
@@@ -925,25 -893,26 +910,26 @@@ uint16_t tt_local_crc(struct bat_priv *
  {
  	uint16_t total = 0, total_one;
  	struct hashtable_t *hash = bat_priv->tt_local_hash;
- 	struct tt_local_entry *tt_local_entry;
+ 	struct tt_common_entry *tt_common_entry;
  	struct hlist_node *node;
  	struct hlist_head *head;
- 	int i, j;
+ 	uint32_t i;
+ 	int j;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
- 		hlist_for_each_entry_rcu(tt_local_entry, node,
+ 		hlist_for_each_entry_rcu(tt_common_entry, node,
  					 head, hash_entry) {
  			/* not yet committed clients have not to be taken into
  			 * account while computing the CRC */
- 			if (tt_local_entry->flags & TT_CLIENT_NEW)
+ 			if (tt_common_entry->flags & TT_CLIENT_NEW)
  				continue;
  			total_one = 0;
  			for (j = 0; j < ETH_ALEN; j++)
  				total_one = crc16_byte(total_one,
- 						   tt_local_entry->addr[j]);
+ 						   tt_common_entry->addr[j]);
  			total ^= total_one;
  		}
  		rcu_read_unlock();
@@@ -1032,21 -1001,25 +1018,25 @@@ unlock
  /* data_ptr is useless here, but has to be kept to respect the prototype */
  static int tt_local_valid_entry(const void *entry_ptr, const void *data_ptr)
  {
- 	const struct tt_local_entry *tt_local_entry = entry_ptr;
+ 	const struct tt_common_entry *tt_common_entry = entry_ptr;
  
- 	if (tt_local_entry->flags & TT_CLIENT_NEW)
+ 	if (tt_common_entry->flags & TT_CLIENT_NEW)
  		return 0;
  	return 1;
  }
  
  static int tt_global_valid_entry(const void *entry_ptr, const void *data_ptr)
  {
- 	const struct tt_global_entry *tt_global_entry = entry_ptr;
+ 	const struct tt_common_entry *tt_common_entry = entry_ptr;
+ 	const struct tt_global_entry *tt_global_entry;
  	const struct orig_node *orig_node = data_ptr;
  
- 	if (tt_global_entry->flags & TT_CLIENT_ROAM)
+ 	if (tt_common_entry->flags & TT_CLIENT_ROAM)
  		return 0;
  
+ 	tt_global_entry = container_of(tt_common_entry, struct tt_global_entry,
+ 				       common);
+ 
  	return (tt_global_entry->orig_node == orig_node);
  }
  
@@@ -1057,7 -1030,7 +1047,7 @@@ static struct sk_buff *tt_response_fill
  							      const void *),
  					      void *cb_data)
  {
- 	struct tt_local_entry *tt_local_entry;
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_query_packet *tt_response;
  	struct tt_change *tt_change;
  	struct hlist_node *node;
@@@ -1065,7 -1038,7 +1055,7 @@@
  	struct sk_buff *skb = NULL;
  	uint16_t tt_tot, tt_count;
  	ssize_t tt_query_size = sizeof(struct tt_query_packet);
- 	int i;
+ 	uint32_t i;
  
  	if (tt_query_size + tt_len > primary_if->soft_iface->mtu) {
  		tt_len = primary_if->soft_iface->mtu - tt_query_size;
@@@ -1089,15 -1062,16 +1079,16 @@@
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
- 		hlist_for_each_entry_rcu(tt_local_entry, node,
+ 		hlist_for_each_entry_rcu(tt_common_entry, node,
  					 head, hash_entry) {
  			if (tt_count == tt_tot)
  				break;
  
- 			if ((valid_cb) && (!valid_cb(tt_local_entry, cb_data)))
+ 			if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
  				continue;
  
- 			memcpy(tt_change->addr, tt_local_entry->addr, ETH_ALEN);
+ 			memcpy(tt_change->addr, tt_common_entry->addr,
+ 			       ETH_ALEN);
  			tt_change->flags = NO_FLAGS;
  
  			tt_count++;
@@@ -1204,11 -1178,11 +1195,11 @@@ static bool send_other_tt_response(stru
  		(tt_request->flags & TT_FULL_TABLE ? 'F' : '.'));
  
  	/* Let's get the orig node of the REAL destination */
- 	req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst);
+ 	req_dst_orig_node = orig_hash_find(bat_priv, tt_request->dst);
  	if (!req_dst_orig_node)
  		goto out;
  
- 	res_dst_orig_node = get_orig_node(bat_priv, tt_request->src);
+ 	res_dst_orig_node = orig_hash_find(bat_priv, tt_request->src);
  	if (!res_dst_orig_node)
  		goto out;
  
@@@ -1334,7 -1308,7 +1325,7 @@@ static bool send_my_tt_response(struct 
  	my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
  	req_ttvn = tt_request->ttvn;
  
- 	orig_node = get_orig_node(bat_priv, tt_request->src);
+ 	orig_node = orig_hash_find(bat_priv, tt_request->src);
  	if (!orig_node)
  		goto out;
  
@@@ -1514,7 -1488,7 +1505,7 @@@ bool is_my_client(struct bat_priv *bat_
  		goto out;
  	/* Check if the client has been logically deleted (but is kept for
  	 * consistency purpose) */
- 	if (tt_local_entry->flags & TT_CLIENT_PENDING)
+ 	if (tt_local_entry->common.flags & TT_CLIENT_PENDING)
  		goto out;
  	ret = true;
  out:
@@@ -1737,45 -1711,53 +1728,53 @@@ void tt_free(struct bat_priv *bat_priv
  	kfree(bat_priv->tt_buff);
  }
  
- /* This function will reset the specified flags from all the entries in
-  * the given hash table and will increment num_local_tt for each involved
-  * entry */
- static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags)
+ /* This function will enable or disable the specified flags for all the entries
+  * in the given hash table and returns the number of modified entries */
+ static uint16_t tt_set_flags(struct hashtable_t *hash, uint16_t flags,
+ 			     bool enable)
  {
- 	int i;
- 	struct hashtable_t *hash = bat_priv->tt_local_hash;
+ 	uint32_t i;
+ 	uint16_t changed_num = 0;
  	struct hlist_head *head;
  	struct hlist_node *node;
- 	struct tt_local_entry *tt_local_entry;
+ 	struct tt_common_entry *tt_common_entry;
  
  	if (!hash)
- 		return;
+ 		goto out;
  
  	for (i = 0; i < hash->size; i++) {
  		head = &hash->table[i];
  
  		rcu_read_lock();
- 		hlist_for_each_entry_rcu(tt_local_entry, node,
+ 		hlist_for_each_entry_rcu(tt_common_entry, node,
  					 head, hash_entry) {
- 			if (!(tt_local_entry->flags & flags))
- 				continue;
- 			tt_local_entry->flags &= ~flags;
- 			atomic_inc(&bat_priv->num_local_tt);
+ 			if (enable) {
+ 				if ((tt_common_entry->flags & flags) == flags)
+ 					continue;
+ 				tt_common_entry->flags |= flags;
+ 			} else {
+ 				if (!(tt_common_entry->flags & flags))
+ 					continue;
+ 				tt_common_entry->flags &= ~flags;
+ 			}
+ 			changed_num++;
  		}
  		rcu_read_unlock();
  	}
- 
+ out:
+ 	return changed_num;
  }
  
  /* Purge out all the tt local entries marked with TT_CLIENT_PENDING */
  static void tt_local_purge_pending_clients(struct bat_priv *bat_priv)
  {
  	struct hashtable_t *hash = bat_priv->tt_local_hash;
+ 	struct tt_common_entry *tt_common_entry;
  	struct tt_local_entry *tt_local_entry;
  	struct hlist_node *node, *node_tmp;
  	struct hlist_head *head;
  	spinlock_t *list_lock; /* protects write access to the hash lists */
- 	int i;
+ 	uint32_t i;
  
  	if (!hash)
  		return;
@@@ -1785,16 -1767,19 +1784,19 @@@
  		list_lock = &hash->list_locks[i];
  
  		spin_lock_bh(list_lock);
- 		hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
+ 		hlist_for_each_entry_safe(tt_common_entry, node, node_tmp,
  					  head, hash_entry) {
- 			if (!(tt_local_entry->flags & TT_CLIENT_PENDING))
+ 			if (!(tt_common_entry->flags & TT_CLIENT_PENDING))
  				continue;
  
  			bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
- 				"(%pM): pending\n", tt_local_entry->addr);
+ 				"(%pM): pending\n", tt_common_entry->addr);
  
  			atomic_dec(&bat_priv->num_local_tt);
  			hlist_del_rcu(node);
+ 			tt_local_entry = container_of(tt_common_entry,
+ 						      struct tt_local_entry,
+ 						      common);
  			tt_local_entry_free_ref(tt_local_entry);
  		}
  		spin_unlock_bh(list_lock);
@@@ -1804,7 -1789,11 +1806,11 @@@
  
  void tt_commit_changes(struct bat_priv *bat_priv)
  {
- 	tt_local_reset_flags(bat_priv, TT_CLIENT_NEW);
+ 	uint16_t changed_num = tt_set_flags(bat_priv->tt_local_hash,
+ 					    TT_CLIENT_NEW, false);
+ 	/* all the reset entries have now to be effectively counted as local
+ 	 * entries */
+ 	atomic_add(changed_num, &bat_priv->num_local_tt);
  	tt_local_purge_pending_clients(bat_priv);
  
  	/* Increment the TTVN only once per OGM interval */
diff --combined net/ipv4/ipip.c
index 0b2e732,9490690..413ed1b
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@@ -148,7 -148,7 +148,7 @@@ struct pcpu_tstats 
  	unsigned long	rx_bytes;
  	unsigned long	tx_packets;
  	unsigned long	tx_bytes;
- };
+ } __attribute__((aligned(4*sizeof(unsigned long))));
  
  static struct net_device_stats *ipip_get_stats(struct net_device *dev)
  {
@@@ -285,8 -285,6 +285,8 @@@ static struct ip_tunnel * ipip_tunnel_l
  	if (register_netdevice(dev) < 0)
  		goto failed_free;
  
 +	strcpy(nt->parms.name, dev->name);
 +
  	dev_hold(dev);
  	ipip_tunnel_link(ipn, nt);
  	return nt;
@@@ -761,6 -759,7 +761,6 @@@ static int ipip_tunnel_init(struct net_
  	struct ip_tunnel *tunnel = netdev_priv(dev);
  
  	tunnel->dev = dev;
 -	strcpy(tunnel->parms.name, dev->name);
  
  	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
  	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
@@@ -826,7 -825,6 +826,7 @@@ static void ipip_destroy_tunnels(struc
  static int __net_init ipip_init_net(struct net *net)
  {
  	struct ipip_net *ipn = net_generic(net, ipip_net_id);
 +	struct ip_tunnel *t;
  	int err;
  
  	ipn->tunnels[0] = ipn->tunnels_wc;
@@@ -850,9 -848,6 +850,9 @@@
  	if ((err = register_netdev(ipn->fb_tunnel_dev)))
  		goto err_reg_dev;
  
 +	t = netdev_priv(ipn->fb_tunnel_dev);
 +
 +	strcpy(t->parms.name, ipn->fb_tunnel_dev->name);
  	return 0;
  
  err_reg_dev:
diff --combined net/ipv6/addrconf.c
index 36806de,94f3fd9..59a9d0e
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@@ -630,13 -630,13 +630,13 @@@ ipv6_add_addr(struct inet6_dev *idev, c
  		goto out;
  	}
  
- 	rt = addrconf_dst_alloc(idev, addr, 0);
+ 	rt = addrconf_dst_alloc(idev, addr, false);
  	if (IS_ERR(rt)) {
  		err = PTR_ERR(rt);
  		goto out;
  	}
  
- 	ipv6_addr_copy(&ifa->addr, addr);
+ 	ifa->addr = *addr;
  
  	spin_lock_init(&ifa->lock);
  	spin_lock_init(&ifa->state_lock);
@@@ -657,7 -657,7 +657,7 @@@
  	 * layer address of our nexhop router
  	 */
  
- 	if (dst_get_neighbour_raw(&rt->dst) == NULL)
+ 	if (dst_get_neighbour_noref_raw(&rt->dst) == NULL)
  		ifa->flags &= ~IFA_F_OPTIMISTIC;
  
  	ifa->idev = idev;
@@@ -1228,7 -1228,7 +1228,7 @@@ try_nextdev
  	if (!hiscore->ifa)
  		return -EADDRNOTAVAIL;
  
- 	ipv6_addr_copy(saddr, &hiscore->ifa->addr);
+ 	*saddr = hiscore->ifa->addr;
  	in6_ifa_put(hiscore->ifa);
  	return 0;
  }
@@@ -1249,7 -1249,7 +1249,7 @@@ int ipv6_get_lladdr(struct net_device *
  		list_for_each_entry(ifp, &idev->addr_list, if_list) {
  			if (ifp->scope == IFA_LINK &&
  			    !(ifp->flags & banned_flags)) {
- 				ipv6_addr_copy(addr, &ifp->addr);
+ 				*addr = ifp->addr;
  				err = 0;
  				break;
  			}
@@@ -1700,7 -1700,7 +1700,7 @@@ addrconf_prefix_route(struct in6_addr *
  		.fc_protocol = RTPROT_KERNEL,
  	};
  
- 	ipv6_addr_copy(&cfg.fc_dst, pfx);
+ 	cfg.fc_dst = *pfx;
  
  	/* Prevent useless cloning on PtP SIT.
  	   This thing is done here expecting that the whole
@@@ -1805,8 -1805,7 +1805,8 @@@ static struct inet6_dev *addrconf_add_d
  		return ERR_PTR(-EACCES);
  
  	/* Add default multicast route */
 -	addrconf_add_mroute(dev);
 +	if (!(dev->flags & IFF_LOOPBACK))
 +		addrconf_add_mroute(dev);
  
  	/* Add link local route */
  	addrconf_add_lroute(dev);
diff --combined net/ipv6/sit.c
index 96f3623,b7d14cc..3b6dac9
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@@ -91,7 -91,7 +91,7 @@@ struct pcpu_tstats 
  	unsigned long	rx_bytes;
  	unsigned long	tx_packets;
  	unsigned long	tx_bytes;
- };
+ } __attribute__((aligned(4*sizeof(unsigned long))));
  
  static struct net_device_stats *ipip6_get_stats(struct net_device *dev)
  {
@@@ -263,8 -263,6 +263,8 @@@ static struct ip_tunnel *ipip6_tunnel_l
  	if (register_netdevice(dev) < 0)
  		goto failed_free;
  
 +	strcpy(nt->parms.name, dev->name);
 +
  	dev_hold(dev);
  
  	ipip6_tunnel_link(sitn, nt);
@@@ -682,7 -680,7 +682,7 @@@ static netdev_tx_t ipip6_tunnel_xmit(st
  		struct neighbour *neigh = NULL;
  
  		if (skb_dst(skb))
- 			neigh = dst_get_neighbour(skb_dst(skb));
+ 			neigh = dst_get_neighbour_noref(skb_dst(skb));
  
  		if (neigh == NULL) {
  			if (net_ratelimit())
@@@ -707,7 -705,7 +707,7 @@@
  		struct neighbour *neigh = NULL;
  
  		if (skb_dst(skb))
- 			neigh = dst_get_neighbour(skb_dst(skb));
+ 			neigh = dst_get_neighbour_noref(skb_dst(skb));
  
  		if (neigh == NULL) {
  			if (net_ratelimit())
@@@ -916,7 -914,7 +916,7 @@@ ipip6_tunnel_ioctl (struct net_device *
  				goto done;
  #ifdef CONFIG_IPV6_SIT_6RD
  		} else {
- 			ipv6_addr_copy(&ip6rd.prefix, &t->ip6rd.prefix);
+ 			ip6rd.prefix = t->ip6rd.prefix;
  			ip6rd.relay_prefix = t->ip6rd.relay_prefix;
  			ip6rd.prefixlen = t->ip6rd.prefixlen;
  			ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen;
@@@ -1084,7 -1082,7 +1084,7 @@@
  			if (relay_prefix != ip6rd.relay_prefix)
  				goto done;
  
- 			ipv6_addr_copy(&t->ip6rd.prefix, &prefix);
+ 			t->ip6rd.prefix = prefix;
  			t->ip6rd.relay_prefix = relay_prefix;
  			t->ip6rd.prefixlen = ip6rd.prefixlen;
  			t->ip6rd.relay_prefixlen = ip6rd.relay_prefixlen;
@@@ -1146,6 -1144,7 +1146,6 @@@ static int ipip6_tunnel_init(struct net
  	struct ip_tunnel *tunnel = netdev_priv(dev);
  
  	tunnel->dev = dev;
 -	strcpy(tunnel->parms.name, dev->name);
  
  	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
  	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
@@@ -1208,7 -1207,6 +1208,7 @@@ static void __net_exit sit_destroy_tunn
  static int __net_init sit_init_net(struct net *net)
  {
  	struct sit_net *sitn = net_generic(net, sit_net_id);
 +	struct ip_tunnel *t;
  	int err;
  
  	sitn->tunnels[0] = sitn->tunnels_wc;
@@@ -1233,9 -1231,6 +1233,9 @@@
  	if ((err = register_netdev(sitn->fb_tunnel_dev)))
  		goto err_reg_dev;
  
 +	t = netdev_priv(sitn->fb_tunnel_dev);
 +
 +	strcpy(t->parms.name, sitn->fb_tunnel_dev->name);
  	return 0;
  
  err_reg_dev:
diff --combined net/mac80211/agg-tx.c
index 2e4b961,c45fa5d..7380287
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@@ -78,10 -78,13 +78,13 @@@ static void ieee80211_send_addba_reques
  	memcpy(mgmt->da, da, ETH_ALEN);
  	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
  	if (sdata->vif.type == NL80211_IFTYPE_AP ||
- 	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ 	    sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+ 	    sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
  		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
  	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
  		memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+ 	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ 		memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
  
  	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
  					  IEEE80211_STYPE_ACTION);
@@@ -185,6 -188,7 +188,7 @@@ int ___ieee80211_stop_tx_ba_session(str
  #endif /* CONFIG_MAC80211_HT_DEBUG */
  
  	del_timer_sync(&tid_tx->addba_resp_timer);
+ 	del_timer_sync(&tid_tx->session_timer);
  
  	/*
  	 * After this packets are no longer handed right through
@@@ -303,38 -307,6 +307,38 @@@ ieee80211_wake_queue_agg(struct ieee802
  	__release(agg_queue);
  }
  
 +/*
 + * splice packets from the STA's pending to the local pending,
 + * requires a call to ieee80211_agg_splice_finish later
 + */
 +static void __acquires(agg_queue)
 +ieee80211_agg_splice_packets(struct ieee80211_local *local,
 +			     struct tid_ampdu_tx *tid_tx, u16 tid)
 +{
 +	int queue = ieee80211_ac_from_tid(tid);
 +	unsigned long flags;
 +
 +	ieee80211_stop_queue_agg(local, tid);
 +
 +	if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
 +			  " from the pending queue\n", tid))
 +		return;
 +
 +	if (!skb_queue_empty(&tid_tx->pending)) {
 +		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 +		/* copy over remaining packets */
 +		skb_queue_splice_tail_init(&tid_tx->pending,
 +					   &local->pending[queue]);
 +		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 +	}
 +}
 +
 +static void __releases(agg_queue)
 +ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
 +{
 +	ieee80211_wake_queue_agg(local, tid);
 +}
 +
  void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
  {
  	struct tid_ampdu_tx *tid_tx;
@@@ -346,17 -318,19 +350,17 @@@
  	tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
  
  	/*
 -	 * While we're asking the driver about the aggregation,
 -	 * stop the AC queue so that we don't have to worry
 -	 * about frames that came in while we were doing that,
 -	 * which would require us to put them to the AC pending
 -	 * afterwards which just makes the code more complex.
 +	 * Start queuing up packets for this aggregation session.
 +	 * We're going to release them once the driver is OK with
 +	 * that.
  	 */
  	clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
  
  	/*
 -	 * make sure no packets are being processed to get
 -	 * valid starting sequence number
 +	 * Make sure no packets are being processed. This ensures that
 +	 * we have a valid starting sequence number and that in-flight
 +	 * packets have been flushed out and no packets for this TID
 +	 * will go into the driver during the ampdu_action call.
  	 */
  	synchronize_net();
  
@@@ -370,15 -344,17 +374,15 @@@
  					" tid %d\n", tid);
  #endif
  		spin_lock_bh(&sta->lock);
 +		ieee80211_agg_splice_packets(local, tid_tx, tid);
  		ieee80211_assign_tid_tx(sta, tid, NULL);
 +		ieee80211_agg_splice_finish(local, tid);
  		spin_unlock_bh(&sta->lock);
  
 -		ieee80211_wake_queue_agg(local, tid);
  		kfree_rcu(tid_tx, rcu_head);
  		return;
  	}
  
 -	/* we can take packets again now */
 -	ieee80211_wake_queue_agg(local, tid);
 -
  	/* activate the timer for the recipient's addBA response */
  	mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
  #ifdef CONFIG_MAC80211_HT_DEBUG
@@@ -396,6 -372,28 +400,28 @@@
  				     tid_tx->timeout);
  }
  
+ /*
+  * After accepting the AddBA Response we activated a timer,
+  * resetting it after each frame that we send.
+  */
+ static void sta_tx_agg_session_timer_expired(unsigned long data)
+ {
+ 	/* not an elegant detour, but there is no choice as the timer passes
+ 	 * only one argument, and various sta_info are needed here, so init
+ 	 * flow in sta_info_create gives the TID as data, while the timer_to_id
+ 	 * array gives the sta through container_of */
+ 	u8 *ptid = (u8 *)data;
+ 	u8 *timer_to_id = ptid - *ptid;
+ 	struct sta_info *sta = container_of(timer_to_id, struct sta_info,
+ 					 timer_to_tid[0]);
+ 
+ #ifdef CONFIG_MAC80211_HT_DEBUG
+ 	printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid);
+ #endif
+ 
+ 	ieee80211_stop_tx_ba_session(&sta->sta, *ptid);
+ }
+ 
  int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
  				  u16 timeout)
  {
@@@ -420,15 -418,11 +446,11 @@@
  	       pubsta->addr, tid);
  #endif /* CONFIG_MAC80211_HT_DEBUG */
  
- 	/*
- 	 * The aggregation code is not prepared to handle
- 	 * anything but STA/AP due to the BSSID handling.
- 	 * IBSS could work in the code but isn't supported
- 	 * by drivers or the standard.
- 	 */
  	if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ 	    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
  	    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- 	    sdata->vif.type != NL80211_IFTYPE_AP)
+ 	    sdata->vif.type != NL80211_IFTYPE_AP &&
+ 	    sdata->vif.type != NL80211_IFTYPE_ADHOC)
  		return -EINVAL;
  
  	if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
@@@ -439,6 -433,27 +461,27 @@@
  		return -EINVAL;
  	}
  
+ 	/*
+ 	 * 802.11n-2009 11.5.1.1: If the initiating STA is an HT STA, is a
+ 	 * member of an IBSS, and has no other existing Block Ack agreement
+ 	 * with the recipient STA, then the initiating STA shall transmit a
+ 	 * Probe Request frame to the recipient STA and shall not transmit an
+ 	 * ADDBA Request frame unless it receives a Probe Response frame
+ 	 * from the recipient within dot11ADDBAFailureTimeout.
+ 	 *
+ 	 * The probe request mechanism for ADDBA is currently not implemented,
+ 	 * but we only build up Block Ack session with HT STAs. This information
+ 	 * is set when we receive a bss info from a probe response or a beacon.
+ 	 */
+ 	if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC &&
+ 	    !sta->sta.ht_cap.ht_supported) {
+ #ifdef CONFIG_MAC80211_HT_DEBUG
+ 		printk(KERN_DEBUG "BA request denied - IBSS STA %pM"
+ 		       "does not advertise HT support\n", pubsta->addr);
+ #endif /* CONFIG_MAC80211_HT_DEBUG */
+ 		return -EINVAL;
+ 	}
+ 
  	spin_lock_bh(&sta->lock);
  
  	/* we have tried too many times, receiver does not want A-MPDU */
@@@ -470,11 -485,16 +513,16 @@@
  
  	tid_tx->timeout = timeout;
  
- 	/* Tx timer */
+ 	/* response timer */
  	tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
  	tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
  	init_timer(&tid_tx->addba_resp_timer);
  
+ 	/* tx timer */
+ 	tid_tx->session_timer.function = sta_tx_agg_session_timer_expired;
+ 	tid_tx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
+ 	init_timer(&tid_tx->session_timer);
+ 
  	/* assign a dialog token */
  	sta->ampdu_mlme.dialog_token_allocator++;
  	tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator;
@@@ -494,6 -514,38 +542,6 @@@
  }
  EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
  
 -/*
 - * splice packets from the STA's pending to the local pending,
 - * requires a call to ieee80211_agg_splice_finish later
 - */
 -static void __acquires(agg_queue)
 -ieee80211_agg_splice_packets(struct ieee80211_local *local,
 -			     struct tid_ampdu_tx *tid_tx, u16 tid)
 -{
 -	int queue = ieee80211_ac_from_tid(tid);
 -	unsigned long flags;
 -
 -	ieee80211_stop_queue_agg(local, tid);
 -
 -	if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
 -			  " from the pending queue\n", tid))
 -		return;
 -
 -	if (!skb_queue_empty(&tid_tx->pending)) {
 -		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 -		/* copy over remaining packets */
 -		skb_queue_splice_tail_init(&tid_tx->pending,
 -					   &local->pending[queue]);
 -		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 -	}
 -}
 -
 -static void __releases(agg_queue)
 -ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
 -{
 -	ieee80211_wake_queue_agg(local, tid);
 -}
 -
  static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
  					 struct sta_info *sta, u16 tid)
  {
@@@ -547,7 -599,7 +595,7 @@@ void ieee80211_start_tx_ba_cb(struct ie
  	}
  
  	mutex_lock(&local->sta_mtx);
- 	sta = sta_info_get(sdata, ra);
+ 	sta = sta_info_get_bss(sdata, ra);
  	if (!sta) {
  		mutex_unlock(&local->sta_mtx);
  #ifdef CONFIG_MAC80211_HT_DEBUG
@@@ -676,7 -728,7 +724,7 @@@ void ieee80211_stop_tx_ba_cb(struct iee
  
  	mutex_lock(&local->sta_mtx);
  
- 	sta = sta_info_get(sdata, ra);
+ 	sta = sta_info_get_bss(sdata, ra);
  	if (!sta) {
  #ifdef CONFIG_MAC80211_HT_DEBUG
  		printk(KERN_DEBUG "Could not find station: %pM\n", ra);
@@@ -814,6 -866,11 +862,11 @@@ void ieee80211_process_addba_resp(struc
  			ieee80211_agg_tx_operational(local, sta, tid);
  
  		sta->ampdu_mlme.addba_req_num[tid] = 0;
+ 
+ 		if (tid_tx->timeout)
+ 			mod_timer(&tid_tx->session_timer,
+ 				  TU_TO_EXP_TIME(tid_tx->timeout));
+ 
  	} else {
  		___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR,
  						true);
diff --combined net/nfc/nci/core.c
index ea660344,37de28e..c55f233
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@@ -25,6 -25,8 +25,8 @@@
   *
   */
  
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+ 
  #include <linux/types.h>
  #include <linux/workqueue.h>
  #include <linux/completion.h>
@@@ -69,7 -71,7 +71,7 @@@ static int __nci_request(struct nci_de
  	__u32 timeout)
  {
  	int rc = 0;
 -	unsigned long completion_rc;
 +	long completion_rc;
  
  	ndev->req_status = NCI_REQ_PEND;
  
@@@ -79,7 -81,7 +81,7 @@@
  							&ndev->req_completion,
  							timeout);
  
- 	nfc_dbg("wait_for_completion return %ld", completion_rc);
+ 	pr_debug("wait_for_completion return %ld\n", completion_rc);
  
  	if (completion_rc > 0) {
  		switch (ndev->req_status) {
@@@ -96,8 -98,8 +98,8 @@@
  			break;
  		}
  	} else {
- 		nfc_err("wait_for_completion_interruptible_timeout failed %ld",
- 			completion_rc);
+ 		pr_err("wait_for_completion_interruptible_timeout failed %ld\n",
+ 		       completion_rc);
  
  		rc = ((completion_rc == 0) ? (-ETIMEDOUT) : (completion_rc));
  	}
@@@ -126,7 -128,10 +128,10 @@@ static inline int nci_request(struct nc
  
  static void nci_reset_req(struct nci_dev *ndev, unsigned long opt)
  {
- 	nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 0, NULL);
+ 	struct nci_core_reset_cmd cmd;
+ 
+ 	cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG;
+ 	nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd);
  }
  
  static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
@@@ -136,17 -141,11 +141,11 @@@
  
  static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
  {
- 	struct nci_core_conn_create_cmd conn_cmd;
  	struct nci_rf_disc_map_cmd cmd;
  	struct disc_map_config *cfg = cmd.mapping_configs;
  	__u8 *num = &cmd.num_mapping_configs;
  	int i;
  
- 	/* create static rf connection */
- 	conn_cmd.target_handle = 0;
- 	conn_cmd.num_target_specific_params = 0;
- 	nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd);
- 
  	/* set rf mapping configurations */
  	*num = 0;
  
@@@ -326,8 -325,6 +325,6 @@@ static void nci_cmd_timer(unsigned lon
  {
  	struct nci_dev *ndev = (void *) arg;
  
- 	nfc_dbg("entry");
- 
  	atomic_set(&ndev->cmd_cnt, 1);
  	queue_work(ndev->cmd_wq, &ndev->cmd_work);
  }
@@@ -336,8 -333,6 +333,6 @@@ static int nci_dev_up(struct nfc_dev *n
  {
  	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
  
- 	nfc_dbg("entry");
- 
  	return nci_open_device(ndev);
  }
  
@@@ -345,8 -340,6 +340,6 @@@ static int nci_dev_down(struct nfc_dev 
  {
  	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
  
- 	nfc_dbg("entry");
- 
  	return nci_close_device(ndev);
  }
  
@@@ -355,20 -348,18 +348,18 @@@ static int nci_start_poll(struct nfc_de
  	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
  	int rc;
  
- 	nfc_dbg("entry");
- 
  	if (test_bit(NCI_DISCOVERY, &ndev->flags)) {
- 		nfc_err("unable to start poll, since poll is already active");
+ 		pr_err("unable to start poll, since poll is already active\n");
  		return -EBUSY;
  	}
  
  	if (ndev->target_active_prot) {
- 		nfc_err("there is an active target");
+ 		pr_err("there is an active target\n");
  		return -EBUSY;
  	}
  
  	if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
- 		nfc_dbg("target is active, implicitly deactivate...");
+ 		pr_debug("target is active, implicitly deactivate...\n");
  
  		rc = nci_request(ndev, nci_rf_deactivate_req, 0,
  			msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
@@@ -389,10 -380,8 +380,8 @@@ static void nci_stop_poll(struct nfc_de
  {
  	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
  
- 	nfc_dbg("entry");
- 
  	if (!test_bit(NCI_DISCOVERY, &ndev->flags)) {
- 		nfc_err("unable to stop poll, since poll is not active");
+ 		pr_err("unable to stop poll, since poll is not active\n");
  		return;
  	}
  
@@@ -405,21 -394,21 +394,21 @@@ static int nci_activate_target(struct n
  {
  	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
  
- 	nfc_dbg("entry, target_idx %d, protocol 0x%x", target_idx, protocol);
+ 	pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol);
  
  	if (!test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
- 		nfc_err("there is no available target to activate");
+ 		pr_err("there is no available target to activate\n");
  		return -EINVAL;
  	}
  
  	if (ndev->target_active_prot) {
- 		nfc_err("there is already an active target");
+ 		pr_err("there is already an active target\n");
  		return -EBUSY;
  	}
  
  	if (!(ndev->target_available_prots & (1 << protocol))) {
- 		nfc_err("target does not support the requested protocol 0x%x",
- 			protocol);
+ 		pr_err("target does not support the requested protocol 0x%x\n",
+ 		       protocol);
  		return -EINVAL;
  	}
  
@@@ -433,10 -422,10 +422,10 @@@ static void nci_deactivate_target(struc
  {
  	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
  
- 	nfc_dbg("entry, target_idx %d", target_idx);
+ 	pr_debug("target_idx %d\n", target_idx);
  
  	if (!ndev->target_active_prot) {
- 		nfc_err("unable to deactivate target, no active target");
+ 		pr_err("unable to deactivate target, no active target\n");
  		return;
  	}
  
@@@ -456,10 -445,10 +445,10 @@@ static int nci_data_exchange(struct nfc
  	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
  	int rc;
  
- 	nfc_dbg("entry, target_idx %d, len %d", target_idx, skb->len);
+ 	pr_debug("target_idx %d, len %d\n", target_idx, skb->len);
  
  	if (!ndev->target_active_prot) {
- 		nfc_err("unable to exchange data, no active target");
+ 		pr_err("unable to exchange data, no active target\n");
  		return -EINVAL;
  	}
  
@@@ -470,7 -459,7 +459,7 @@@
  	ndev->data_exchange_cb = cb;
  	ndev->data_exchange_cb_context = cb_context;
  
- 	rc = nci_send_data(ndev, ndev->conn_id, skb);
+ 	rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);
  	if (rc)
  		clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
  
@@@ -502,7 -491,7 +491,7 @@@ struct nci_dev *nci_allocate_device(str
  {
  	struct nci_dev *ndev;
  
- 	nfc_dbg("entry, supported_protocols 0x%x", supported_protocols);
+ 	pr_debug("supported_protocols 0x%x\n", supported_protocols);
  
  	if (!ops->open || !ops->close || !ops->send)
  		return NULL;
@@@ -542,8 -531,6 +531,6 @@@ EXPORT_SYMBOL(nci_allocate_device)
   */
  void nci_free_device(struct nci_dev *ndev)
  {
- 	nfc_dbg("entry");
- 
  	nfc_free_device(ndev->nfc_dev);
  	kfree(ndev);
  }
@@@ -560,8 -547,6 +547,6 @@@ int nci_register_device(struct nci_dev 
  	struct device *dev = &ndev->nfc_dev->dev;
  	char name[32];
  
- 	nfc_dbg("entry");
- 
  	rc = nfc_register_device(ndev->nfc_dev);
  	if (rc)
  		goto exit;
@@@ -624,8 -609,6 +609,6 @@@ EXPORT_SYMBOL(nci_register_device)
   */
  void nci_unregister_device(struct nci_dev *ndev)
  {
- 	nfc_dbg("entry");
- 
  	nci_close_device(ndev);
  
  	destroy_workqueue(ndev->cmd_wq);
@@@ -645,7 -628,7 +628,7 @@@ int nci_recv_frame(struct sk_buff *skb
  {
  	struct nci_dev *ndev = (struct nci_dev *) skb->dev;
  
- 	nfc_dbg("entry, len %d", skb->len);
+ 	pr_debug("len %d\n", skb->len);
  
  	if (!ndev || (!test_bit(NCI_UP, &ndev->flags)
  		&& !test_bit(NCI_INIT, &ndev->flags))) {
@@@ -665,7 -648,7 +648,7 @@@ static int nci_send_frame(struct sk_buf
  {
  	struct nci_dev *ndev = (struct nci_dev *) skb->dev;
  
- 	nfc_dbg("entry, len %d", skb->len);
+ 	pr_debug("len %d\n", skb->len);
  
  	if (!ndev) {
  		kfree_skb(skb);
@@@ -684,11 -667,11 +667,11 @@@ int nci_send_cmd(struct nci_dev *ndev, 
  	struct nci_ctrl_hdr *hdr;
  	struct sk_buff *skb;
  
- 	nfc_dbg("entry, opcode 0x%x, plen %d", opcode, plen);
+ 	pr_debug("opcode 0x%x, plen %d\n", opcode, plen);
  
  	skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL);
  	if (!skb) {
- 		nfc_err("no memory for command");
+ 		pr_err("no memory for command\n");
  		return -ENOMEM;
  	}
  
@@@ -718,7 -701,7 +701,7 @@@ static void nci_tx_work(struct work_str
  	struct nci_dev *ndev = container_of(work, struct nci_dev, tx_work);
  	struct sk_buff *skb;
  
- 	nfc_dbg("entry, credits_cnt %d", atomic_read(&ndev->credits_cnt));
+ 	pr_debug("credits_cnt %d\n", atomic_read(&ndev->credits_cnt));
  
  	/* Send queued tx data */
  	while (atomic_read(&ndev->credits_cnt)) {
@@@ -726,12 -709,15 +709,15 @@@
  		if (!skb)
  			return;
  
- 		atomic_dec(&ndev->credits_cnt);
+ 		/* Check if data flow control is used */
+ 		if (atomic_read(&ndev->credits_cnt) !=
+ 				NCI_DATA_FLOW_CONTROL_NOT_USED)
+ 			atomic_dec(&ndev->credits_cnt);
  
- 		nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d",
- 				nci_pbf(skb->data),
- 				nci_conn_id(skb->data),
- 				nci_plen(skb->data));
+ 		pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n",
+ 			 nci_pbf(skb->data),
+ 			 nci_conn_id(skb->data),
+ 			 nci_plen(skb->data));
  
  		nci_send_frame(skb);
  	}
@@@ -760,7 -746,7 +746,7 @@@ static void nci_rx_work(struct work_str
  			break;
  
  		default:
- 			nfc_err("unknown MT 0x%x", nci_mt(skb->data));
+ 			pr_err("unknown MT 0x%x\n", nci_mt(skb->data));
  			kfree_skb(skb);
  			break;
  		}
@@@ -774,7 -760,7 +760,7 @@@ static void nci_cmd_work(struct work_st
  	struct nci_dev *ndev = container_of(work, struct nci_dev, cmd_work);
  	struct sk_buff *skb;
  
- 	nfc_dbg("entry, cmd_cnt %d", atomic_read(&ndev->cmd_cnt));
+ 	pr_debug("cmd_cnt %d\n", atomic_read(&ndev->cmd_cnt));
  
  	/* Send queued command */
  	if (atomic_read(&ndev->cmd_cnt)) {
@@@ -784,11 -770,11 +770,11 @@@
  
  		atomic_dec(&ndev->cmd_cnt);
  
- 		nfc_dbg("NCI TX: MT=cmd, PBF=%d, GID=0x%x, OID=0x%x, plen=%d",
- 				nci_pbf(skb->data),
- 				nci_opcode_gid(nci_opcode(skb->data)),
- 				nci_opcode_oid(nci_opcode(skb->data)),
- 				nci_plen(skb->data));
+ 		pr_debug("NCI TX: MT=cmd, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",
+ 			 nci_pbf(skb->data),
+ 			 nci_opcode_gid(nci_opcode(skb->data)),
+ 			 nci_opcode_oid(nci_opcode(skb->data)),
+ 			 nci_plen(skb->data));
  
  		nci_send_frame(skb);
  
diff --combined net/sched/sch_gred.c
index 6cd8ddf,a1b7407..1b5e631
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@@ -34,7 -34,7 +34,7 @@@ struct gred_sched
  
  struct gred_sched_data {
  	u32		limit;		/* HARD maximal queue length	*/
- 	u32      	DP;		/* the drop pramaters */
+ 	u32		DP;		/* the drop parameters */
  	u32		bytesin;	/* bytes seen on virtualQ so far*/
  	u32		packetsin;	/* packets seen on virtualQ so far*/
  	u32		backlog;	/* bytes on the virtualQ */
@@@ -379,13 -379,14 +379,14 @@@ static inline int gred_change_table_def
  }
  
  static inline int gred_change_vq(struct Qdisc *sch, int dp,
- 				 struct tc_gred_qopt *ctl, int prio, u8 *stab)
+ 				 struct tc_gred_qopt *ctl, int prio,
+ 				 u8 *stab, u32 max_P)
  {
  	struct gred_sched *table = qdisc_priv(sch);
  	struct gred_sched_data *q;
  
  	if (table->tab[dp] == NULL) {
 -		table->tab[dp] = kzalloc(sizeof(*q), GFP_KERNEL);
 +		table->tab[dp] = kzalloc(sizeof(*q), GFP_ATOMIC);
  		if (table->tab[dp] == NULL)
  			return -ENOMEM;
  	}
@@@ -400,7 -401,7 +401,7 @@@
  
  	red_set_parms(&q->parms,
  		      ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog,
- 		      ctl->Scell_log, stab);
+ 		      ctl->Scell_log, stab, max_P);
  
  	return 0;
  }
@@@ -409,6 -410,7 +410,7 @@@ static const struct nla_policy gred_pol
  	[TCA_GRED_PARMS]	= { .len = sizeof(struct tc_gred_qopt) },
  	[TCA_GRED_STAB]		= { .len = 256 },
  	[TCA_GRED_DPS]		= { .len = sizeof(struct tc_gred_sopt) },
+ 	[TCA_GRED_MAX_P]	= { .type = NLA_U32 },
  };
  
  static int gred_change(struct Qdisc *sch, struct nlattr *opt)
@@@ -418,6 -420,7 +420,7 @@@
  	struct nlattr *tb[TCA_GRED_MAX + 1];
  	int err, prio = GRED_DEF_PRIO;
  	u8 *stab;
+ 	u32 max_P;
  
  	if (opt == NULL)
  		return -EINVAL;
@@@ -433,6 -436,8 +436,8 @@@
  	    tb[TCA_GRED_STAB] == NULL)
  		return -EINVAL;
  
+ 	max_P = tb[TCA_GRED_MAX_P] ? nla_get_u32(tb[TCA_GRED_MAX_P]) : 0;
+ 
  	err = -EINVAL;
  	ctl = nla_data(tb[TCA_GRED_PARMS]);
  	stab = nla_data(tb[TCA_GRED_STAB]);
@@@ -457,7 -462,7 +462,7 @@@
  
  	sch_tree_lock(sch);
  
- 	err = gred_change_vq(sch, ctl->DP, ctl, prio, stab);
+ 	err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P);
  	if (err < 0)
  		goto errout_locked;
  
@@@ -498,6 -503,7 +503,7 @@@ static int gred_dump(struct Qdisc *sch
  	struct gred_sched *table = qdisc_priv(sch);
  	struct nlattr *parms, *opts = NULL;
  	int i;
+ 	u32 max_p[MAX_DPs];
  	struct tc_gred_sopt sopt = {
  		.DPs	= table->DPs,
  		.def_DP	= table->def,
@@@ -509,6 -515,14 +515,14 @@@
  	if (opts == NULL)
  		goto nla_put_failure;
  	NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt);
+ 
+ 	for (i = 0; i < MAX_DPs; i++) {
+ 		struct gred_sched_data *q = table->tab[i];
+ 
+ 		max_p[i] = q ? q->parms.max_P : 0;
+ 	}
+ 	NLA_PUT(skb, TCA_GRED_MAX_P, sizeof(max_p), max_p);
+ 
  	parms = nla_nest_start(skb, TCA_GRED_PARMS);
  	if (parms == NULL)
  		goto nla_put_failure;
diff --combined net/sunrpc/svc.c
index e9632bb,9d01d46..a3797c0
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@@ -527,20 -527,17 +527,20 @@@ svc_destroy(struct svc_serv *serv
  		printk("svc_destroy: no threads for serv=%p!\n", serv);
  
  	del_timer_sync(&serv->sv_temptimer);
 -
 -	svc_close_all(&serv->sv_tempsocks);
 +	/*
 +	 * The set of xprts (contained in the sv_tempsocks and
 +	 * sv_permsocks lists) is now constant, since it is modified
 +	 * only by accepting new sockets (done by service threads in
 +	 * svc_recv) or aging old ones (done by sv_temptimer), or
 +	 * configuration changes (excluded by whatever locking the
 +	 * caller is using--nfsd_mutex in the case of nfsd).  So it's
 +	 * safe to traverse those lists and shut everything down:
 +	 */
 +	svc_close_all(serv);
  
  	if (serv->sv_shutdown)
  		serv->sv_shutdown(serv);
  
 -	svc_close_all(&serv->sv_permsocks);
 -
 -	BUG_ON(!list_empty(&serv->sv_permsocks));
 -	BUG_ON(!list_empty(&serv->sv_tempsocks));
 -
  	cache_clean_deferred(serv);
  
  	if (svc_serv_is_pooled(serv))
@@@ -686,8 -683,8 +686,8 @@@ found_pool
   * Create or destroy enough new threads to make the number
   * of threads the given number.  If `pool' is non-NULL, applies
   * only to threads in that pool, otherwise round-robins between
 - * all pools.  Must be called with a svc_get() reference and
 - * the BKL or another lock to protect access to svc_serv fields.
 + * all pools.  Caller must ensure that mutual exclusion between this and
 + * server startup or shutdown.
   *
   * Destroying threads relies on the service threads filling in
   * rqstp->rq_task, which only the nfs ones do.  Assumes the serv
@@@ -829,7 -826,7 +829,7 @@@ static int __svc_rpcb_register4(const u
  	return error;
  }
  
- #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ #if IS_ENABLED(CONFIG_IPV6)
  /*
   * Register an "inet6" protocol family netid with the local
   * rpcbind daemon via an rpcbind v4 SET request.
@@@ -875,7 -872,7 +875,7 @@@ static int __svc_rpcb_register6(const u
  
  	return error;
  }
- #endif	/* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+ #endif	/* IS_ENABLED(CONFIG_IPV6) */
  
  /*
   * Register a kernel RPC service via rpcbind version 4.
@@@ -896,11 -893,11 +896,11 @@@ static int __svc_register(const char *p
  		error = __svc_rpcb_register4(program, version,
  						protocol, port);
  		break;
- #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ #if IS_ENABLED(CONFIG_IPV6)
  	case PF_INET6:
  		error = __svc_rpcb_register6(program, version,
  						protocol, port);
- #endif	/* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+ #endif
  	}
  
  	if (error < 0)
diff --combined net/sunrpc/svc_xprt.c
index 0633c7e,38649cf..74cb0d8
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@@ -22,7 -22,6 +22,7 @@@ static struct svc_deferred_req *svc_def
  static int svc_deferred_recv(struct svc_rqst *rqstp);
  static struct cache_deferred_req *svc_defer(struct cache_req *req);
  static void svc_age_temp_xprts(unsigned long closure);
 +static void svc_delete_xprt(struct svc_xprt *xprt);
  
  /* apparently the "standard" is that clients close
   * idle connections after 5 minutes, servers after
@@@ -148,8 -147,8 +148,8 @@@ EXPORT_SYMBOL_GPL(svc_xprt_put)
   * Called by transport drivers to initialize the transport independent
   * portion of the transport instance.
   */
 -void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
 -		   struct svc_serv *serv)
 +void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
 +		   struct svc_xprt *xprt, struct svc_serv *serv)
  {
  	memset(xprt, 0, sizeof(*xprt));
  	xprt->xpt_class = xcl;
@@@ -164,7 -163,7 +164,7 @@@
  	spin_lock_init(&xprt->xpt_lock);
  	set_bit(XPT_BUSY, &xprt->xpt_flags);
  	rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
 -	xprt->xpt_net = get_net(&init_net);
 +	xprt->xpt_net = get_net(net);
  }
  EXPORT_SYMBOL_GPL(svc_xprt_init);
  
@@@ -180,13 -179,13 +180,13 @@@ static struct svc_xprt *__svc_xpo_creat
  		.sin_addr.s_addr	= htonl(INADDR_ANY),
  		.sin_port		= htons(port),
  	};
- #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ #if IS_ENABLED(CONFIG_IPV6)
  	struct sockaddr_in6 sin6 = {
  		.sin6_family		= AF_INET6,
  		.sin6_addr		= IN6ADDR_ANY_INIT,
  		.sin6_port		= htons(port),
  	};
- #endif	/* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+ #endif
  	struct sockaddr *sap;
  	size_t len;
  
@@@ -195,12 -194,12 +195,12 @@@
  		sap = (struct sockaddr *)&sin;
  		len = sizeof(sin);
  		break;
- #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ #if IS_ENABLED(CONFIG_IPV6)
  	case PF_INET6:
  		sap = (struct sockaddr *)&sin6;
  		len = sizeof(sin6);
  		break;
- #endif	/* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+ #endif
  	default:
  		return ERR_PTR(-EAFNOSUPPORT);
  	}
@@@ -879,7 -878,7 +879,7 @@@ static void call_xpt_users(struct svc_x
  /*
   * Remove a dead transport
   */
 -void svc_delete_xprt(struct svc_xprt *xprt)
 +static void svc_delete_xprt(struct svc_xprt *xprt)
  {
  	struct svc_serv	*serv = xprt->xpt_server;
  	struct svc_deferred_req *dr;
@@@ -894,7 -893,14 +894,7 @@@
  	spin_lock_bh(&serv->sv_lock);
  	if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
  		list_del_init(&xprt->xpt_list);
 -	/*
 -	 * The only time we're called while xpt_ready is still on a list
 -	 * is while the list itself is about to be destroyed (in
 -	 * svc_destroy).  BUT svc_xprt_enqueue could still be attempting
 -	 * to add new entries to the sp_sockets list, so we can't leave
 -	 * a freed xprt on it.
 -	 */
 -	list_del_init(&xprt->xpt_ready);
 +	BUG_ON(!list_empty(&xprt->xpt_ready));
  	if (test_bit(XPT_TEMP, &xprt->xpt_flags))
  		serv->sv_tmpcnt--;
  	spin_unlock_bh(&serv->sv_lock);
@@@ -922,48 -928,22 +922,48 @@@ void svc_close_xprt(struct svc_xprt *xp
  }
  EXPORT_SYMBOL_GPL(svc_close_xprt);
  
 -void svc_close_all(struct list_head *xprt_list)
 +static void svc_close_list(struct list_head *xprt_list)
 +{
 +	struct svc_xprt *xprt;
 +
 +	list_for_each_entry(xprt, xprt_list, xpt_list) {
 +		set_bit(XPT_CLOSE, &xprt->xpt_flags);
 +		set_bit(XPT_BUSY, &xprt->xpt_flags);
 +	}
 +}
 +
 +void svc_close_all(struct svc_serv *serv)
  {
 +	struct svc_pool *pool;
  	struct svc_xprt *xprt;
  	struct svc_xprt *tmp;
 +	int i;
 +
 +	svc_close_list(&serv->sv_tempsocks);
 +	svc_close_list(&serv->sv_permsocks);
  
 +	for (i = 0; i < serv->sv_nrpools; i++) {
 +		pool = &serv->sv_pools[i];
 +
 +		spin_lock_bh(&pool->sp_lock);
 +		while (!list_empty(&pool->sp_sockets)) {
 +			xprt = list_first_entry(&pool->sp_sockets, struct svc_xprt, xpt_ready);
 +			list_del_init(&xprt->xpt_ready);
 +		}
 +		spin_unlock_bh(&pool->sp_lock);
 +	}
  	/*
 -	 * The server is shutting down, and no more threads are running.
 -	 * svc_xprt_enqueue() might still be running, but at worst it
 -	 * will re-add the xprt to sp_sockets, which will soon get
 -	 * freed.  So we don't bother with any more locking, and don't
 -	 * leave the close to the (nonexistent) server threads:
 +	 * At this point the sp_sockets lists will stay empty, since
 +	 * svc_enqueue will not add new entries without taking the
 +	 * sp_lock and checking XPT_BUSY.
  	 */
 -	list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
 -		set_bit(XPT_CLOSE, &xprt->xpt_flags);
 +	list_for_each_entry_safe(xprt, tmp, &serv->sv_tempsocks, xpt_list)
  		svc_delete_xprt(xprt);
 -	}
 +	list_for_each_entry_safe(xprt, tmp, &serv->sv_permsocks, xpt_list)
 +		svc_delete_xprt(xprt);
 +
 +	BUG_ON(!list_empty(&serv->sv_permsocks));
 +	BUG_ON(!list_empty(&serv->sv_tempsocks));
  }
  
  /*
diff --combined net/sunrpc/svcsock.c
index 277909e,4653286..4645709
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@@ -157,7 -157,7 +157,7 @@@ static void svc_set_cmsg_data(struct sv
  			cmh->cmsg_level = SOL_IPV6;
  			cmh->cmsg_type = IPV6_PKTINFO;
  			pki->ipi6_ifindex = daddr->sin6_scope_id;
- 			ipv6_addr_copy(&pki->ipi6_addr,	&daddr->sin6_addr);
+ 			pki->ipi6_addr = daddr->sin6_addr;
  			cmh->cmsg_len = CMSG_LEN(sizeof(*pki));
  		}
  		break;
@@@ -523,7 -523,7 +523,7 @@@ static int svc_udp_get_dest_address6(st
  		return 0;
  
  	daddr->sin6_family = AF_INET6;
- 	ipv6_addr_copy(&daddr->sin6_addr, &pki->ipi6_addr);
+ 	daddr->sin6_addr = pki->ipi6_addr;
  	daddr->sin6_scope_id = pki->ipi6_ifindex;
  	return 1;
  }
@@@ -739,8 -739,7 +739,8 @@@ static void svc_udp_init(struct svc_soc
  {
  	int err, level, optname, one = 1;
  
 -	svc_xprt_init(&svc_udp_class, &svsk->sk_xprt, serv);
 +	svc_xprt_init(sock_net(svsk->sk_sock->sk), &svc_udp_class,
 +		      &svsk->sk_xprt, serv);
  	clear_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
  	svsk->sk_sk->sk_data_ready = svc_udp_data_ready;
  	svsk->sk_sk->sk_write_space = svc_write_space;
@@@ -1344,8 -1343,7 +1344,8 @@@ static void svc_tcp_init(struct svc_soc
  {
  	struct sock	*sk = svsk->sk_sk;
  
 -	svc_xprt_init(&svc_tcp_class, &svsk->sk_xprt, serv);
 +	svc_xprt_init(sock_net(svsk->sk_sock->sk), &svc_tcp_class,
 +		      &svsk->sk_xprt, serv);
  	set_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
  	if (sk->sk_state == TCP_LISTEN) {
  		dprintk("setting up TCP socket for listening\n");
@@@ -1661,7 -1659,7 +1661,7 @@@ static struct svc_xprt *svc_bc_create_s
  		return ERR_PTR(-ENOMEM);
  
  	xprt = &svsk->sk_xprt;
 -	svc_xprt_init(&svc_tcp_bc_class, xprt, serv);
 +	svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv);
  
  	serv->sv_bc_xprt = xprt;
  

-- 
LinuxNextTracking


More information about the linux-merge mailing list