The following commit has been merged in the master branch: commit 2d3b2ab540312d9c6e302760f7e3e991873e5867 Merge: 2d4632418186613e235fa1fa49972d8a610eba2f 08e34eb14fe4cfd934b5c169a7682a969457c4ea Author: Stephen Rothwell sfr@canb.auug.org.au Date: Tue Dec 13 14:37:26 2011 +1100
Merge remote-tracking branch 'net-next/master'
Conflicts: drivers/net/ethernet/freescale/fsl_pq_mdio.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@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@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@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@google.com diff --combined MAINTAINERS index af23d6d,209ad06..02e270b --- a/MAINTAINERS +++ b/MAINTAINERS @@@ -511,8 -511,8 +511,8 @@@ M: Joerg Roedel <joerg.roedel@amd.com L: iommu@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@amd.com @@@ -749,7 -749,6 +749,7 @@@ M: Barry Song <baohua.song@csr.com L: linux-arm-kernel@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@arm.linux.org.uk @@@ -1055,18 -1054,35 +1055,18 @@@ ARM/SAMSUNG ARM ARCHITECTURE M: Ben Dooks ben-linux@fluff.org M: Kukjin Kim kgene.kim@samsung.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-samsung-soc@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@fluff.org -L: linux-arm-kernel@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@fluff.org -L: linux-arm-kernel@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@fluff.org -L: linux-arm-kernel@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@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@redhat.com +M: Aurelien Jacquiot a-jacquiot@ti.com +L: linux-c6x-dev@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@redhat.com L: linux-cachefs@redhat.com @@@ -2846,14 -2854,6 +2846,14 @@@ L: platform-driver-x86@vger.kernel.or S: Maintained F: drivers/platform/x86/fujitsu-laptop.c
+FUJITSU M-5MO LS CAMERA ISP DRIVER +M: Kyungmin Park kyungmin.park@samsung.com +M: Heungjun Kim riverful.kim@samsung.com +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/video/m5mols/ +F: include/media/m5mols.h + FUSE: FILESYSTEM IN USERSPACE M: Miklos Szeredi miklos@szeredi.hu L: fuse-devel@lists.sourceforge.net @@@ -3796,6 -3796,7 +3796,6 @@@ S: Odd Fixe
KERNEL NFSD, SUNRPC, AND LOCKD SERVERS M: "J. Bruce Fields" bfields@fieldses.org -M: Neil Brown neilb@suse.de L: linux-nfs@vger.kernel.org W: http://nfs.sourceforge.net/ S: Supported @@@ -4027,7 -4028,7 +4027,7 @@@ M: Josh Boyer <jwboyer@gmail.com M: Matt Porter mporter@kernel.crashing.org W: http://www.penguinppc.org/ L: linuxppc-dev@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@logfs.org +M: Prasad Joshi prasadjoshi.linux@gmail.com L: logfs@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@cmpxchg.org +M: Michal Hocko mhocko@suse.cz M: Balbir Singh bsingharora@gmail.com -M: Daisuke Nishimura nishimura@mxp.nes.nec.co.jp M: KAMEZAWA Hiroyuki kamezawa.hiroyu@jp.fujitsu.com L: cgroups@vger.kernel.org L: linux-mm@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@nicira.com + L: dev@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@ladisch.de L: alsa-devel@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@redhat.com + L: netdev@vger.kernel.org + S: Supported + F: drivers/net/team/ + F: include/linux/if_team.h + TEGRA SUPPORT M: Colin Cross ccross@android.com M: Olof Johansson olof@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@mocean-labs.com"); 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,78b9528..1f7834d --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@@ -67,7 -67,7 +67,7 @@@ static struct tt_local_entry *tt_local_ struct hlist_head *head; struct hlist_node *node; struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL; - int index; + uint32_t index;
if (!hash) return NULL; @@@ -99,7 -99,7 +99,7 @@@ static struct tt_global_entry *tt_globa struct hlist_node *node; struct tt_global_entry *tt_global_entry; struct tt_global_entry *tt_global_entry_tmp = NULL; - int index; + uint32_t index;
if (!hash) return NULL; @@@ -245,11 -245,9 +245,11 @@@ void tt_local_add(struct net_device *so 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_PENDING; + tt_global_entry->flags |= TT_CLIENT_ROAM; + tt_global_entry->roam_at = jiffies; + send_roam_adv(bat_priv, tt_global_entry->addr, tt_global_entry->orig_node); } @@@ -316,9 -314,8 +316,8 @@@ int tt_local_seq_print_text(struct seq_ 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,34 -336,13 +338,13 @@@ "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, head, hash_entry) { - pos += snprintf(buff + pos, 30, " * %pM " - "[%c%c%c%c%c]\n", + seq_printf(seq, " * %pM [%c%c%c%c%c]\n", tt_local_entry->addr, (tt_local_entry->flags & TT_CLIENT_ROAM ? 'R' : '.'), @@@ -381,9 -357,6 +359,6 @@@ } rcu_read_unlock(); } - - seq_printf(seq, "%s", buff); - kfree(buff); out: if (primary_if) hardif_free_ref(primary_if); @@@ -429,7 -402,7 +404,7 @@@ static void tt_local_purge(struct bat_p 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]; @@@ -467,7 -440,7 +442,7 @@@ static void tt_local_table_free(struct 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; @@@ -592,9 -565,8 +567,8 @@@ int tt_global_seq_print_text(struct seq 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,35 -589,13 +591,13 @@@ 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, head, hash_entry) { - pos += snprintf(buff + pos, 69, - " * %pM (%3u) via %pM (%3u) " + seq_printf(seq, " * %pM (%3u) via %pM (%3u) " "[%c%c%c]\n", tt_global_entry->addr, tt_global_entry->ttvn, tt_global_entry->orig_node->orig, @@@ -661,9 -611,6 +613,6 @@@ } rcu_read_unlock(); } - - seq_printf(seq, "%s", buff); - kfree(buff); out: if (primary_if) hardif_free_ref(primary_if); @@@ -696,7 -643,6 +645,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 -650,22 +653,36 @@@
if (tt_global_entry->orig_node == orig_node) { if (roaming) { - tt_global_entry->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); + if (!tt_local_entry) { + tt_global_entry->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; + uint32_t i; struct hashtable_t *hash = bat_priv->tt_global_hash; struct hlist_node *node, *safe; struct hlist_head *head; @@@ -752,9 -684,10 +701,10 @@@ 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", + "(via %pM): %s\n", tt_global_entry->addr, - tt_global_entry->orig_node->orig); + tt_global_entry->orig_node->orig, + message); hlist_del_rcu(node); tt_global_entry_free_ref(tt_global_entry); } @@@ -771,7 -704,7 +721,7 @@@ static void tt_global_roam_purge(struc 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]; @@@ -805,7 -738,7 +755,7 @@@ static void tt_global_table_free(struc 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; @@@ -891,7 -824,8 +841,8 @@@ uint16_t tt_global_crc(struct bat_priv 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]; @@@ -928,7 -862,8 +879,8 @@@ uint16_t tt_local_crc(struct bat_priv * struct tt_local_entry *tt_local_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]; @@@ -1065,7 -1000,7 +1017,7 @@@ static struct sk_buff *tt_response_fill 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; @@@ -1204,11 -1139,11 +1156,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 -1269,7 +1286,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;
@@@ -1742,7 -1677,7 +1694,7 @@@ void tt_free(struct bat_priv *bat_priv * entry */ static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags) { - int i; + uint32_t i; struct hashtable_t *hash = bat_priv->tt_local_hash; struct hlist_head *head; struct hlist_node *node; @@@ -1775,7 -1710,7 +1727,7 @@@ static void tt_local_purge_pending_clie 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; 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/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;