OSDN Git Service

Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Apr 2013 18:21:13 +0000 (11:21 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Apr 2013 18:21:13 +0000 (11:21 -0700)
Pull ext4 fixes from Ted Ts'o:
 "Unfortunately, we introduced some big-endian bugs during the last
  merge window.  Fortunately, Cai and Christian noticed before 3.9
  shipped."

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: fix big-endian bugs which could cause fs corruptions

143 files changed:
MAINTAINERS
arch/arm/boot/dts/armada-370-mirabox.dts
arch/arm/boot/dts/armada-370.dtsi
arch/arm/boot/dts/dbx5x0.dtsi
arch/arm/boot/dts/kirkwood-goflexnet.dts
arch/arm/boot/dts/orion5x.dtsi
arch/arm/mach-cns3xxx/core.c
arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
arch/arm/mach-ep93xx/include/mach/uncompress.h
arch/arm/mach-imx/common.h
arch/arm/mach-imx/hotplug.c
arch/arm/mach-imx/src.c
arch/arm/mach-kirkwood/guruplug-setup.c
arch/arm/mach-kirkwood/openrd-setup.c
arch/arm/mach-kirkwood/rd88f6281-setup.c
arch/arm/mach-msm/timer.c
arch/arm/mach-mvebu/irq-armada-370-xp.c
arch/arm/mach-omap1/clock_data.c
arch/arm/mach-omap2/cclock44xx_data.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-ux500/board-mop500-sdi.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-mop500.h
arch/arm/mach-ux500/cpu-db8500.c
arch/mips/Kconfig
arch/mips/bcm63xx/boards/board_bcm963xx.c
arch/mips/bcm63xx/nvram.c
arch/mips/bcm63xx/setup.c
arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/signal.h
arch/mips/kernel/Makefile
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/linux32.c
arch/mips/kernel/proc.c
arch/mips/lib/bitops.c
arch/mips/lib/csum_partial.S
arch/s390/include/asm/pgtable.h
arch/s390/lib/uaccess_pt.c
arch/tile/kernel/setup.c
drivers/base/regmap/regcache-rbtree.c
drivers/base/regmap/regmap.c
drivers/block/aoe/aoecmd.c
drivers/block/loop.c
drivers/char/hw_random/core.c
drivers/char/virtio_console.c
drivers/clk/tegra/clk-tegra20.c
drivers/dma/Kconfig
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nouveau_drm.h
drivers/media/platform/Kconfig
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/can/sja1000/Kconfig
drivers/net/can/sja1000/plx_pci.c
drivers/net/can/sja1000/sja1000.c
drivers/net/can/sja1000/sja1000.h
drivers/net/ethernet/atheros/atl1e/atl1e.h
drivers/net/ethernet/atheros/atl1e/atl1e_main.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/calxeda/xgmac.c
drivers/net/ethernet/davicom/dm9000.c
drivers/net/ethernet/davicom/dm9000.h
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/intel/e1000/e1000_ethtool.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/ixgb/ixgb_main.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/marvell/sky2.h
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/micrel/ks8851.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/usb/smsc75xx.c
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
drivers/net/wireless/iwlegacy/4965-rs.c
drivers/net/wireless/iwlwifi/dvm/lib.c
drivers/net/wireless/iwlwifi/dvm/ucode.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/mwifiex/pcie.c
drivers/s390/block/scm_blk.c
drivers/s390/block/scm_drv.c
drivers/s390/char/tty3270.c
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/fcoe_ctlr.c
drivers/scsi/libfc/fc_disc.c
drivers/spi/Kconfig
drivers/video/sh_mobile_lcdcfb.c
fs/block_dev.c
fs/nfsd/nfs4xdr.c
fs/reiserfs/xattr.c
include/linux/compat.h
include/linux/netdevice.h
include/linux/signal.h
include/scsi/libfc.h
ipc/msg.c
net/core/dev.c
net/core/flow.c
net/core/rtnetlink.c
net/ipv6/addrconf.c
net/ipv6/ip6_input.c
net/key/af_key.c
net/mac80211/iface.c
net/mac80211/mesh.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/sched/sch_cbq.c
net/sched/sch_fq_codel.c
net/sched/sch_generic.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/vmci_transport.c
net/vmw_vsock/vsock_addr.c
net/vmw_vsock/vsock_addr.h
net/wireless/core.c
net/wireless/core.h
net/wireless/nl80211.c
net/wireless/scan.c
net/wireless/sme.c
net/wireless/trace.h
net/wireless/wext-sme.c
net/xfrm/xfrm_replay.c

index 74e58a4..836a618 100644 (file)
@@ -5065,9 +5065,8 @@ S:        Maintained
 F:     drivers/net/ethernet/marvell/sk*
 
 MARVELL LIBERTAS WIRELESS DRIVER
-M:     Dan Williams <dcbw@redhat.com>
 L:     libertas-dev@lists.infradead.org
-S:     Maintained
+S:     Orphan
 F:     drivers/net/wireless/libertas/
 
 MARVELL MV643XX ETHERNET DRIVER
@@ -5569,6 +5568,7 @@ F:        include/uapi/linux/if_*
 F:     include/uapi/linux/netdevice.h
 
 NETXEN (1/10) GbE SUPPORT
+M:     Manish Chopra <manish.chopra@qlogic.com>
 M:     Sony Chacko <sony.chacko@qlogic.com>
 M:     Rajesh Borundia <rajesh.borundia@qlogic.com>
 L:     netdev@vger.kernel.org
index dd0c57d..3234875 100644 (file)
@@ -54,7 +54,7 @@
                };
 
                mvsdio@d00d4000 {
-                       pinctrl-0 = <&sdio_pins2>;
+                       pinctrl-0 = <&sdio_pins3>;
                        pinctrl-names = "default";
                        status = "okay";
                        /*
index 8188d13..a195deb 100644 (file)
                                             "mpp50", "mpp51", "mpp52";
                              marvell,function = "sd0";
                        };
+
+                       sdio_pins3: sdio-pins3 {
+                             marvell,pins = "mpp48", "mpp49", "mpp50",
+                                            "mpp51", "mpp52", "mpp53";
+                             marvell,function = "sd0";
+                       };
                };
 
                gpio0: gpio@d0018100 {
index 9de9309..aaa63d0 100644 (file)
 
                prcmu: prcmu@80157000 {
                        compatible = "stericsson,db8500-prcmu";
-                       reg = <0x80157000 0x1000>;
-                       reg-names = "prcmu";
+                       reg = <0x80157000 0x1000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>;
+                       reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm";
                        interrupts = <0 47 0x4>;
                        #address-cells = <1>;
                        #size-cells = <1>;
index bd83b8f..c3573be 100644 (file)
@@ -77,6 +77,7 @@
                };
 
                nand@3000000 {
+                       chip-delay = <40>;
                        status = "okay";
 
                        partition@0 {
index 8aad00f..f7bec3b 100644 (file)
@@ -13,6 +13,9 @@
        compatible = "marvell,orion5x";
        interrupt-parent = <&intc>;
 
+       aliases {
+               gpio0 = &gpio0;
+       };
        intc: interrupt-controller {
                compatible = "marvell,orion-intc", "marvell,intc";
                interrupt-controller;
@@ -32,7 +35,9 @@
                        #gpio-cells = <2>;
                        gpio-controller;
                        reg = <0x10100 0x40>;
-                       ngpio = <32>;
+                       ngpios = <32>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
                        interrupts = <6>, <7>, <8>, <9>;
                };
 
@@ -91,7 +96,7 @@
                        reg = <0x90000 0x10000>,
                              <0xf2200000 0x800>;
                        reg-names = "regs", "sram";
-                       interrupts = <22>;
+                       interrupts = <28>;
                        status = "okay";
                };
        };
index e698f26..52e4bb5 100644 (file)
 
 static struct map_desc cns3xxx_io_desc[] __initdata = {
        {
-               .virtual        = CNS3XXX_TC11MP_TWD_BASE_VIRT,
-               .pfn            = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT,
-               .pfn            = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
-               .pfn            = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE),
-               .length         = SZ_4K,
+               .virtual        = CNS3XXX_TC11MP_SCU_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE),
+               .length         = SZ_8K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = CNS3XXX_TIMER1_2_3_BASE_VIRT,
index 191c8e5..b1021aa 100644 (file)
 #define RTC_INTR_STS_OFFSET                    0x34
 
 #define CNS3XXX_MISC_BASE                      0x76000000      /* Misc Control */
-#define CNS3XXX_MISC_BASE_VIRT                 0xFFF07000      /* Misc Control */
+#define CNS3XXX_MISC_BASE_VIRT                 0xFB000000      /* Misc Control */
 
 #define CNS3XXX_PM_BASE                                0x77000000      /* Power Management Control */
-#define CNS3XXX_PM_BASE_VIRT                   0xFFF08000
+#define CNS3XXX_PM_BASE_VIRT                   0xFB001000
 
 #define PM_CLK_GATE_OFFSET                     0x00
 #define PM_SOFT_RST_OFFSET                     0x04
 #define PM_PLL_HM_PD_OFFSET                    0x1C
 
 #define CNS3XXX_UART0_BASE                     0x78000000      /* UART 0 */
-#define CNS3XXX_UART0_BASE_VIRT                        0xFFF09000
+#define CNS3XXX_UART0_BASE_VIRT                        0xFB002000
 
 #define CNS3XXX_UART1_BASE                     0x78400000      /* UART 1 */
 #define CNS3XXX_UART1_BASE_VIRT                        0xFFF0A000
 #define CNS3XXX_I2S_BASE_VIRT                  0xFFF10000
 
 #define CNS3XXX_TIMER1_2_3_BASE                        0x7C800000      /* Timer */
-#define CNS3XXX_TIMER1_2_3_BASE_VIRT           0xFFF10800
+#define CNS3XXX_TIMER1_2_3_BASE_VIRT           0xFB003000
 
 #define TIMER1_COUNTER_OFFSET                  0x00
 #define TIMER1_AUTO_RELOAD_OFFSET              0x04
  * Testchip peripheral and fpga gic regions
  */
 #define CNS3XXX_TC11MP_SCU_BASE                        0x90000000      /* IRQ, Test chip */
-#define CNS3XXX_TC11MP_SCU_BASE_VIRT           0xFF000000
+#define CNS3XXX_TC11MP_SCU_BASE_VIRT           0xFB004000
 
 #define CNS3XXX_TC11MP_GIC_CPU_BASE            0x90000100      /* Test chip interrupt controller CPU interface */
-#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT       0xFF000100
+#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT       (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100)
 
 #define CNS3XXX_TC11MP_TWD_BASE                        0x90000600
-#define CNS3XXX_TC11MP_TWD_BASE_VIRT           0xFF000600
+#define CNS3XXX_TC11MP_TWD_BASE_VIRT           (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600)
 
 #define CNS3XXX_TC11MP_GIC_DIST_BASE           0x90001000      /* Test chip interrupt controller distributor */
-#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT      0xFF001000
+#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT      (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000)
 
 #define CNS3XXX_TC11MP_L220_BASE               0x92002000      /* L220 registers */
 #define CNS3XXX_TC11MP_L220_BASE_VIRT          0xFF002000
index d2afb4d..b5cc77d 100644 (file)
@@ -47,9 +47,13 @@ static void __raw_writel(unsigned int value, unsigned int ptr)
 
 static inline void putc(int c)
 {
-       /* Transmit fifo not full?  */
-       while (__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF)
-               ;
+       int i;
+
+       for (i = 0; i < 10000; i++) {
+               /* Transmit fifo not full? */
+               if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF))
+                       break;
+       }
 
        __raw_writeb(c, PHYS_UART_DATA);
 }
index 5a800bf..5bf4a97 100644 (file)
@@ -110,6 +110,8 @@ void tzic_handle_irq(struct pt_regs *);
 
 extern void imx_enable_cpu(int cpu, bool enable);
 extern void imx_set_cpu_jump(int cpu, void *jump_addr);
+extern u32 imx_get_cpu_arg(int cpu);
+extern void imx_set_cpu_arg(int cpu, u32 arg);
 extern void v7_cpu_resume(void);
 extern u32 *pl310_get_save_ptr(void);
 #ifdef CONFIG_SMP
index 7bc5fe1..361a253 100644 (file)
@@ -46,11 +46,23 @@ static inline void cpu_enter_lowpower(void)
 void imx_cpu_die(unsigned int cpu)
 {
        cpu_enter_lowpower();
+       /*
+        * We use the cpu jumping argument register to sync with
+        * imx_cpu_kill() which is running on cpu0 and waiting for
+        * the register being cleared to kill the cpu.
+        */
+       imx_set_cpu_arg(cpu, ~0);
        cpu_do_idle();
 }
 
 int imx_cpu_kill(unsigned int cpu)
 {
+       unsigned long timeout = jiffies + msecs_to_jiffies(50);
+
+       while (imx_get_cpu_arg(cpu) == 0)
+               if (time_after(jiffies, timeout))
+                       return 0;
        imx_enable_cpu(cpu, false);
+       imx_set_cpu_arg(cpu, 0);
        return 1;
 }
index e15f155..09a742f 100644 (file)
@@ -43,6 +43,18 @@ void imx_set_cpu_jump(int cpu, void *jump_addr)
                       src_base + SRC_GPR1 + cpu * 8);
 }
 
+u32 imx_get_cpu_arg(int cpu)
+{
+       cpu = cpu_logical_map(cpu);
+       return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4);
+}
+
+void imx_set_cpu_arg(int cpu, u32 arg)
+{
+       cpu = cpu_logical_map(cpu);
+       writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4);
+}
+
 void imx_src_prepare_restart(void)
 {
        u32 val;
index 1c6e736..08dd739 100644 (file)
@@ -53,6 +53,8 @@ static struct mv_sata_platform_data guruplug_sata_data = {
 
 static struct mvsdio_platform_data guruplug_mvsdio_data = {
        /* unfortunately the CD signal has not been connected */
+       .gpio_card_detect = -1,
+       .gpio_write_protect = -1,
 };
 
 static struct gpio_led guruplug_led_pins[] = {
index 8ddd69f..6a6eb54 100644 (file)
@@ -55,6 +55,7 @@ static struct mv_sata_platform_data openrd_sata_data = {
 
 static struct mvsdio_platform_data openrd_mvsdio_data = {
        .gpio_card_detect = 29, /* MPP29 used as SD card detect */
+       .gpio_write_protect = -1,
 };
 
 static unsigned int openrd_mpp_config[] __initdata = {
index c7d93b4..d242231 100644 (file)
@@ -69,6 +69,7 @@ static struct mv_sata_platform_data rd88f6281_sata_data = {
 
 static struct mvsdio_platform_data rd88f6281_mvsdio_data = {
        .gpio_card_detect = 28,
+       .gpio_write_protect = -1,
 };
 
 static unsigned int rd88f6281_mpp_config[] __initdata = {
index 2969027..f9fd77e 100644 (file)
@@ -62,7 +62,10 @@ static int msm_timer_set_next_event(unsigned long cycles,
 {
        u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
 
-       writel_relaxed(0, event_base + TIMER_CLEAR);
+       ctrl &= ~TIMER_ENABLE_EN;
+       writel_relaxed(ctrl, event_base + TIMER_ENABLE);
+
+       writel_relaxed(ctrl, event_base + TIMER_CLEAR);
        writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
        writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
        return 0;
index 274ff58..6a9195e 100644 (file)
@@ -44,6 +44,8 @@
 
 #define ARMADA_370_XP_MAX_PER_CPU_IRQS         (28)
 
+#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ       (5)
+
 #define ACTIVE_DOORBELLS                       (8)
 
 static DEFINE_RAW_SPINLOCK(irq_controller_lock);
@@ -62,7 +64,7 @@ static void armada_370_xp_irq_mask(struct irq_data *d)
 #ifdef CONFIG_SMP
        irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
-       if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS)
+       if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
                writel(hwirq, main_int_base +
                                ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS);
        else
@@ -79,7 +81,7 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
 #ifdef CONFIG_SMP
        irq_hw_number_t hwirq = irqd_to_hwirq(d);
 
-       if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS)
+       if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
                writel(hwirq, main_int_base +
                                ARMADA_370_XP_INT_SET_ENABLE_OFFS);
        else
@@ -147,7 +149,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
        writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS);
        irq_set_status_flags(virq, IRQ_LEVEL);
 
-       if (hw < ARMADA_370_XP_MAX_PER_CPU_IRQS) {
+       if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) {
                irq_set_percpu_devid(virq);
                irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
                                        handle_percpu_devid_irq);
index cb7c6ae..6c4f766 100644 (file)
@@ -543,15 +543,6 @@ static struct clk usb_dc_ck = {
        /* Direct from ULPD, no parent */
        .rate           = 48000000,
        .enable_reg     = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
-       .enable_bit     = USB_REQ_EN_SHIFT,
-};
-
-static struct clk usb_dc_ck7xx = {
-       .name           = "usb_dc_ck",
-       .ops            = &clkops_generic,
-       /* Direct from ULPD, no parent */
-       .rate           = 48000000,
-       .enable_reg     = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
        .enable_bit     = SOFT_USB_OTG_DPLL_REQ_SHIFT,
 };
 
@@ -727,8 +718,7 @@ static struct omap_clk omap_clks[] = {
        CLK(NULL,       "usb_clko",     &usb_clko,      CK_16XX | CK_1510 | CK_310),
        CLK(NULL,       "usb_hhc_ck",   &usb_hhc_ck1510, CK_1510 | CK_310),
        CLK(NULL,       "usb_hhc_ck",   &usb_hhc_ck16xx, CK_16XX),
-       CLK(NULL,       "usb_dc_ck",    &usb_dc_ck,     CK_16XX),
-       CLK(NULL,       "usb_dc_ck",    &usb_dc_ck7xx,  CK_7XX),
+       CLK(NULL,       "usb_dc_ck",    &usb_dc_ck,     CK_16XX | CK_7XX),
        CLK(NULL,       "mclk",         &mclk_1510,     CK_1510 | CK_310),
        CLK(NULL,       "mclk",         &mclk_16xx,     CK_16XX),
        CLK(NULL,       "bclk",         &bclk_1510,     CK_1510 | CK_310),
index 3d58f33..0c6834a 100644 (file)
  */
 #define OMAP4_DPLL_ABE_DEFFREQ                         98304000
 
+/*
+ * OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section
+ * "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred
+ * locked frequency for the USB DPLL is 960MHz.
+ */
+#define OMAP4_DPLL_USB_DEFFREQ                         960000000
+
 /* Root clocks */
 
 DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0);
@@ -1011,6 +1018,10 @@ DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel,
                    OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK,
                    hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops);
 
+DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0,
+               OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+               OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL);
+
 DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0,
                OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
                OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
@@ -1538,6 +1549,7 @@ static struct omap_clk omap44xx_clks[] = {
        CLK(NULL,       "per_mcbsp4_gfclk",                     &per_mcbsp4_gfclk,      CK_443X),
        CLK(NULL,       "hsmmc1_fclk",                  &hsmmc1_fclk,   CK_443X),
        CLK(NULL,       "hsmmc2_fclk",                  &hsmmc2_fclk,   CK_443X),
+       CLK(NULL,       "ocp2scp_usb_phy_phy_48m",      &ocp2scp_usb_phy_phy_48m,       CK_443X),
        CLK(NULL,       "sha2md5_fck",                  &sha2md5_fck,   CK_443X),
        CLK(NULL,       "slimbus1_fclk_1",              &slimbus1_fclk_1,       CK_443X),
        CLK(NULL,       "slimbus1_fclk_0",              &slimbus1_fclk_0,       CK_443X),
@@ -1705,5 +1717,13 @@ int __init omap4xxx_clk_init(void)
        if (rc)
                pr_err("%s: failed to configure ABE DPLL!\n", __func__);
 
+       /*
+        * Lock USB DPLL on OMAP4 devices so that the L3INIT power
+        * domain can transition to retention state when not in use.
+        */
+       rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ);
+       if (rc)
+               pr_err("%s: failed to configure USB DPLL!\n", __func__);
+
        return 0;
 }
index 40f4a03..d6ba13e 100644 (file)
@@ -293,5 +293,8 @@ extern void omap_reserve(void);
 struct omap_hwmod;
 extern int omap_dss_reset(struct omap_hwmod *);
 
+/* SoC specific clock initializer */
+extern int (*omap_clk_init)(void);
+
 #endif /* __ASSEMBLER__ */
 #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
index 2c3fdd6..5c445ca 100644 (file)
 #include "prm44xx.h"
 
 /*
+ * omap_clk_init: points to a function that does the SoC-specific
+ * clock initializations
+ */
+int (*omap_clk_init)(void);
+
+/*
  * The machine specific code may provide the extra mapping besides the
  * default mapping provided here.
  */
@@ -397,7 +403,7 @@ void __init omap2420_init_early(void)
        omap242x_clockdomains_init();
        omap2420_hwmod_init();
        omap_hwmod_init_postsetup();
-       omap2420_clk_init();
+       omap_clk_init = omap2420_clk_init;
 }
 
 void __init omap2420_init_late(void)
@@ -427,7 +433,7 @@ void __init omap2430_init_early(void)
        omap243x_clockdomains_init();
        omap2430_hwmod_init();
        omap_hwmod_init_postsetup();
-       omap2430_clk_init();
+       omap_clk_init = omap2430_clk_init;
 }
 
 void __init omap2430_init_late(void)
@@ -462,7 +468,7 @@ void __init omap3_init_early(void)
        omap3xxx_clockdomains_init();
        omap3xxx_hwmod_init();
        omap_hwmod_init_postsetup();
-       omap3xxx_clk_init();
+       omap_clk_init = omap3xxx_clk_init;
 }
 
 void __init omap3430_init_early(void)
@@ -500,7 +506,7 @@ void __init ti81xx_init_early(void)
        omap3xxx_clockdomains_init();
        omap3xxx_hwmod_init();
        omap_hwmod_init_postsetup();
-       omap3xxx_clk_init();
+       omap_clk_init = omap3xxx_clk_init;
 }
 
 void __init omap3_init_late(void)
@@ -568,7 +574,7 @@ void __init am33xx_init_early(void)
        am33xx_clockdomains_init();
        am33xx_hwmod_init();
        omap_hwmod_init_postsetup();
-       am33xx_clk_init();
+       omap_clk_init = am33xx_clk_init;
 }
 #endif
 
@@ -593,7 +599,7 @@ void __init omap4430_init_early(void)
        omap44xx_clockdomains_init();
        omap44xx_hwmod_init();
        omap_hwmod_init_postsetup();
-       omap4xxx_clk_init();
+       omap_clk_init = omap4xxx_clk_init;
 }
 
 void __init omap4430_init_late(void)
index c2c798c..a202a47 100644 (file)
@@ -1368,7 +1368,9 @@ static void _enable_sysc(struct omap_hwmod *oh)
        }
 
        if (sf & SYSC_HAS_MIDLEMODE) {
-               if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
+               if (oh->flags & HWMOD_FORCE_MSTANDBY) {
+                       idlemode = HWMOD_IDLEMODE_FORCE;
+               } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
                        idlemode = HWMOD_IDLEMODE_NO;
                } else {
                        if (sf & SYSC_HAS_ENAWAKEUP)
@@ -1440,7 +1442,8 @@ static void _idle_sysc(struct omap_hwmod *oh)
        }
 
        if (sf & SYSC_HAS_MIDLEMODE) {
-               if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
+               if ((oh->flags & HWMOD_SWSUP_MSTANDBY) ||
+                   (oh->flags & HWMOD_FORCE_MSTANDBY)) {
                        idlemode = HWMOD_IDLEMODE_FORCE;
                } else {
                        if (sf & SYSC_HAS_ENAWAKEUP)
index d43d9b6..d5dc935 100644 (file)
@@ -427,8 +427,8 @@ struct omap_hwmod_omap4_prcm {
  *
  * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
  *     of idle, rather than relying on module smart-idle
- * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
- *     of standby, rather than relying on module smart-standby
+ * HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and
+ *     out of standby, rather than relying on module smart-standby
  * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
  *     SDRAM controller, etc. XXX probably belongs outside the main hwmod file
  *     XXX Should be HWMOD_SETUP_NO_RESET
@@ -459,6 +459,10 @@ struct omap_hwmod_omap4_prcm {
  *     correctly, or this is being abused to deal with some PM latency
  *     issues -- but we're currently suffering from a shortage of
  *     folks who are able to track these issues down properly.
+ * HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device
+ *     is kept in force-standby mode. Failing to do so causes PM problems
+ *     with musb on OMAP3630 at least. Note that musb has a dedicated register
+ *     to control MSTANDBY signal when MIDLEMODE is set to force-standby.
  */
 #define HWMOD_SWSUP_SIDLE                      (1 << 0)
 #define HWMOD_SWSUP_MSTANDBY                   (1 << 1)
@@ -471,6 +475,7 @@ struct omap_hwmod_omap4_prcm {
 #define HWMOD_16BIT_REG                                (1 << 8)
 #define HWMOD_EXT_OPT_MAIN_CLK                 (1 << 9)
 #define HWMOD_BLOCK_WFI                                (1 << 10)
+#define HWMOD_FORCE_MSTANDBY                   (1 << 11)
 
 /*
  * omap_hwmod._int_flags definitions
index ac7e03e..5112d04 100644 (file)
@@ -1707,9 +1707,14 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
         * Erratum ID: i479  idle_req / idle_ack mechanism potentially
         * broken when autoidle is enabled
         * workaround is to disable the autoidle bit at module level.
+        *
+        * Enabling the device in any other MIDLEMODE setting but force-idle
+        * causes core_pwrdm not enter idle states at least on OMAP3630.
+        * Note that musb has OTG_FORCESTDBY register that controls MSTANDBY
+        * signal when MIDLEMODE is set to force-idle.
         */
        .flags          = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
-                               | HWMOD_SWSUP_MSTANDBY,
+                               | HWMOD_FORCE_MSTANDBY,
 };
 
 /* usb_otg_hs */
index 0e47d2e..9e05765 100644 (file)
@@ -2714,6 +2714,10 @@ static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
        { }
 };
 
+static struct omap_hwmod_opt_clk ocp2scp_usb_phy_opt_clks[] = {
+       { .role = "48mhz", .clk = "ocp2scp_usb_phy_phy_48m" },
+};
+
 /* ocp2scp_usb_phy */
 static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
        .name           = "ocp2scp_usb_phy",
@@ -2728,6 +2732,8 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
                },
        },
        .dev_attr       = ocp2scp_dev_attr,
+       .opt_clks       = ocp2scp_usb_phy_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(ocp2scp_usb_phy_opt_clks),
 };
 
 /*
index 2bdd4cf..f62b509 100644 (file)
@@ -547,6 +547,8 @@ static inline void __init realtime_counter_init(void)
                               clksrc_nr, clksrc_src)                   \
 void __init omap##name##_gptimer_timer_init(void)                      \
 {                                                                      \
+       if (omap_clk_init)                                              \
+               omap_clk_init();                                        \
        omap_dmtimer_init();                                            \
        omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop);    \
        omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);        \
@@ -556,6 +558,8 @@ void __init omap##name##_gptimer_timer_init(void)                   \
                                clksrc_nr, clksrc_src)                  \
 void __init omap##name##_sync32k_timer_init(void)              \
 {                                                                      \
+       if (omap_clk_init)                                              \
+               omap_clk_init();                                        \
        omap_dmtimer_init();                                            \
        omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop);    \
        /* Enable the use of clocksource="gp_timer" kernel parameter */ \
index 051b62c..7f2cb6c 100644 (file)
@@ -81,7 +81,6 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
 #endif
 
 struct mmci_platform_data mop500_sdi0_data = {
-       .ios_handler    = mop500_sdi0_ios_handler,
        .ocr_mask       = MMC_VDD_29_30,
        .f_max          = 50000000,
        .capabilities   = MMC_CAP_4_BIT_DATA |
index b034578..87d2d7b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/platform_data/i2c-nomadik.h>
@@ -439,6 +440,15 @@ static void mop500_prox_deactivate(struct device *dev)
        regulator_put(prox_regulator);
 }
 
+void mop500_snowball_ethernet_clock_enable(void)
+{
+       struct clk *clk;
+
+       clk = clk_get_sys("fsmc", NULL);
+       if (!IS_ERR(clk))
+               clk_prepare_enable(clk);
+}
+
 static struct cryp_platform_data u8500_cryp1_platform_data = {
                .mem_to_engine = {
                                .dir = STEDMA40_MEM_TO_PERIPH,
@@ -683,6 +693,8 @@ static void __init snowball_init_machine(void)
        mop500_audio_init(parent);
        mop500_uart_init(parent);
 
+       mop500_snowball_ethernet_clock_enable();
+
        /* This board has full regulator constraints */
        regulator_has_full_constraints();
 }
index eaa605f..d38951b 100644 (file)
@@ -104,6 +104,7 @@ void __init mop500_pinmaps_init(void);
 void __init snowball_pinmaps_init(void);
 void __init hrefv60_pinmaps_init(void);
 void mop500_audio_init(struct device *parent);
+void mop500_snowball_ethernet_clock_enable(void);
 
 int __init mop500_uib_init(void);
 void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
index 19235cf..f1a5818 100644 (file)
@@ -312,9 +312,10 @@ static void __init u8500_init_machine(void)
        /* Pinmaps must be in place before devices register */
        if (of_machine_is_compatible("st-ericsson,mop500"))
                mop500_pinmaps_init();
-       else if (of_machine_is_compatible("calaosystems,snowball-a9500"))
+       else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
                snowball_pinmaps_init();
-       else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
+               mop500_snowball_ethernet_clock_enable();
+       } else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
                hrefv60_pinmaps_init();
        else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
                /* TODO: Add pinmaps for ccu9540 board. */
index cd2e21f..a6fdd16 100644 (file)
@@ -18,7 +18,7 @@ config MIPS
        select HAVE_KRETPROBES
        select HAVE_DEBUG_KMEMLEAK
        select ARCH_BINFMT_ELF_RANDOMIZE_PIE
-       select HAVE_ARCH_TRANSPARENT_HUGEPAGE
+       select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
        select RTC_LIB if !MACH_LOONGSON
        select GENERIC_ATOMIC64 if !64BIT
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
@@ -1493,7 +1493,6 @@ config CPU_XLP
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
        select CPU_SUPPORTS_HIGHMEM
-       select CPU_HAS_LLSC
        select WEAK_ORDERING
        select WEAK_REORDERING_BEYOND_LLSC
        select CPU_HAS_PREFETCH
index ed1949c..9aa7d44 100644 (file)
@@ -745,10 +745,7 @@ void __init board_prom_init(void)
                strcpy(cfe_version, "unknown");
        printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
 
-       if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) {
-               printk(KERN_ERR PFX "invalid nvram checksum\n");
-               return;
-       }
+       bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
 
        board_name = bcm63xx_nvram_get_name();
        /* find board by name */
index 6206116..a4b8864 100644 (file)
@@ -38,7 +38,7 @@ struct bcm963xx_nvram {
 static struct bcm963xx_nvram nvram;
 static int mac_addr_used;
 
-int __init bcm63xx_nvram_init(void *addr)
+void __init bcm63xx_nvram_init(void *addr)
 {
        unsigned int check_len;
        u32 crc, expected_crc;
@@ -60,9 +60,8 @@ int __init bcm63xx_nvram_init(void *addr)
        crc = crc32_le(~0, (u8 *)&nvram, check_len);
 
        if (crc != expected_crc)
-               return -EINVAL;
-
-       return 0;
+               pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
+                       expected_crc, crc);
 }
 
 u8 *bcm63xx_nvram_get_name(void)
index 314231b..35e18e9 100644 (file)
@@ -157,4 +157,4 @@ int __init bcm63xx_register_devices(void)
        return board_register_devices();
 }
 
-device_initcall(bcm63xx_register_devices);
+arch_initcall(bcm63xx_register_devices);
index 62d6a3b..4e0b6bc 100644 (file)
@@ -9,10 +9,8 @@
  *
  * Initialized the local nvram copy from the target address and checks
  * its checksum.
- *
- * Returns 0 on success.
  */
-int __init bcm63xx_nvram_init(void *nvram);
+void bcm63xx_nvram_init(void *nvram);
 
 /**
  * bcm63xx_nvram_get_name() - returns the board name according to nvram
index d9c8284..193c091 100644 (file)
 /* #define cpu_has_prefetch    ? */
 #define cpu_has_mcheck         1
 /* #define cpu_has_ejtag       ? */
-#ifdef CONFIG_CPU_HAS_LLSC
 #define cpu_has_llsc           1
-#else
-#define cpu_has_llsc           0
-#endif
 /* #define cpu_has_vtag_icache ? */
 /* #define cpu_has_dc_aliases  ? */
 /* #define cpu_has_ic_fills_f_dc ? */
index 12b70c2..0da44d4 100644 (file)
@@ -1166,7 +1166,10 @@ do {                                                                     \
        unsigned int __dspctl;                                          \
                                                                        \
        __asm__ __volatile__(                                           \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
        "       rddsp   %0, %x1                                 \n"     \
+       "       .set pop                                        \n"     \
        : "=r" (__dspctl)                                               \
        : "i" (mask));                                                  \
        __dspctl;                                                       \
@@ -1175,30 +1178,198 @@ do {                                                                   \
 #define wrdsp(val, mask)                                               \
 do {                                                                   \
        __asm__ __volatile__(                                           \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
        "       wrdsp   %0, %x1                                 \n"     \
+       "       .set pop                                        \n"     \
        :                                                               \
        : "r" (val), "i" (mask));                                       \
 } while (0)
 
-#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
-#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
-#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
-#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
-
-#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
-#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
-#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
-#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
-
-#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
-#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
-#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
-#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
-
-#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
-#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
-#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
-#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
+#define mflo0()                                                                \
+({                                                                     \
+       long mflo0;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mflo %0, $ac0                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mflo0));                                                \
+       mflo0;                                                          \
+})
+
+#define mflo1()                                                                \
+({                                                                     \
+       long mflo1;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mflo %0, $ac1                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mflo1));                                                \
+       mflo1;                                                          \
+})
+
+#define mflo2()                                                                \
+({                                                                     \
+       long mflo2;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mflo %0, $ac2                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mflo2));                                                \
+       mflo2;                                                          \
+})
+
+#define mflo3()                                                                \
+({                                                                     \
+       long mflo3;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mflo %0, $ac3                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mflo3));                                                \
+       mflo3;                                                          \
+})
+
+#define mfhi0()                                                                \
+({                                                                     \
+       long mfhi0;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mfhi %0, $ac0                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mfhi0));                                                \
+       mfhi0;                                                          \
+})
+
+#define mfhi1()                                                                \
+({                                                                     \
+       long mfhi1;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mfhi %0, $ac1                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mfhi1));                                                \
+       mfhi1;                                                          \
+})
+
+#define mfhi2()                                                                \
+({                                                                     \
+       long mfhi2;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mfhi %0, $ac2                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mfhi2));                                                \
+       mfhi2;                                                          \
+})
+
+#define mfhi3()                                                                \
+({                                                                     \
+       long mfhi3;                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mfhi %0, $ac3                                   \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (mfhi3));                                                \
+       mfhi3;                                                          \
+})
+
+
+#define mtlo0(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mtlo %0, $ac0                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
+
+#define mtlo1(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mtlo %0, $ac1                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
+
+#define mtlo2(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mtlo %0, $ac2                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
+
+#define mtlo3(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mtlo %0, $ac3                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
+
+#define mthi0(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mthi %0, $ac0                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
+
+#define mthi1(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mthi %0, $ac1                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
+
+#define mthi2(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mthi %0, $ac2                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
+
+#define mthi3(x)                                                       \
+({                                                                     \
+       __asm__(                                                        \
+       "       .set push                                       \n"     \
+       "       .set dsp                                        \n"     \
+       "       mthi %0, $ac3                                   \n"     \
+       "       .set pop                                        \n"     \
+       :                                                               \
+       : "r" (x));                                                     \
+})
 
 #else
 
index 197f636..8efe5a9 100644 (file)
@@ -21,6 +21,6 @@
 #include <asm/sigcontext.h>
 #include <asm/siginfo.h>
 
-#define __ARCH_HAS_ODD_SIGACTION
+#define __ARCH_HAS_IRIX_SIGACTION
 
 #endif /* _ASM_SIGNAL_H */
index f81d98f..de75fb5 100644 (file)
@@ -100,29 +100,16 @@ obj-$(CONFIG_HW_PERF_EVENTS)      += perf_event_mipsxx.o
 obj-$(CONFIG_JUMP_LABEL)       += jump_label.o
 
 #
-# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is safe
-# to enable DSP assembler support here even if the MIPS Release 2 CPU we
-# are targetting does not support DSP because all code-paths making use of
-# it properly check that the running CPU *actually does* support these
-# instructions.
+# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is not
+# safe to unconditionnaly use the assembler -mdsp / -mdspr2 switches
+# here because the compiler may use DSP ASE instructions (such as lwx) in
+# code paths where we cannot check that the CPU we are running on supports it.
+# Proper abstraction using HAVE_AS_DSP and macros is done in
+# arch/mips/include/asm/mipsregs.h.
 #
 ifeq ($(CONFIG_CPU_MIPSR2), y)
 CFLAGS_DSP                     = -DHAVE_AS_DSP
 
-#
-# Check if assembler supports DSP ASE
-#
-ifeq ($(call cc-option-yn,-mdsp), y)
-CFLAGS_DSP                     += -mdsp
-endif
-
-#
-# Check if assembler supports DSP ASE Rev2
-#
-ifeq ($(call cc-option-yn,-mdspr2), y)
-CFLAGS_DSP                     += -mdspr2
-endif
-
 CFLAGS_signal.o                        = $(CFLAGS_DSP)
 CFLAGS_signal32.o              = $(CFLAGS_DSP)
 CFLAGS_process.o               = $(CFLAGS_DSP)
index 6bfccc2..d069a19 100644 (file)
@@ -580,6 +580,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->tlbsize = 48;
                break;
        case PRID_IMP_VR41XX:
+               set_isa(c, MIPS_CPU_ISA_III);
+               c->options = R4K_OPTS;
+               c->tlbsize = 32;
                switch (c->processor_id & 0xf0) {
                case PRID_REV_VR4111:
                        c->cputype = CPU_VR4111;
@@ -604,6 +607,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                                __cpu_name[cpu] = "NEC VR4131";
                        } else {
                                c->cputype = CPU_VR4133;
+                               c->options |= MIPS_CPU_LLSC;
                                __cpu_name[cpu] = "NEC VR4133";
                        }
                        break;
@@ -613,9 +617,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                        __cpu_name[cpu] = "NEC Vr41xx";
                        break;
                }
-               set_isa(c, MIPS_CPU_ISA_III);
-               c->options = R4K_OPTS;
-               c->tlbsize = 32;
                break;
        case PRID_IMP_R4300:
                c->cputype = CPU_R4300;
index 8eeee1c..db9655f 100644 (file)
@@ -171,7 +171,7 @@ SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third,
                err = compat_sys_shmctl(first, second, compat_ptr(ptr));
                break;
        default:
-               err = -EINVAL;
+               err = -ENOSYS;
                break;
        }
 
index 135c4aa..7a54f74 100644 (file)
@@ -67,7 +67,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        if (cpu_has_mips_r) {
                seq_printf(m, "isa\t\t\t:");
                if (cpu_has_mips_1)
-                       seq_printf(m, "%s", "mips1");
+                       seq_printf(m, "%s", " mips1");
                if (cpu_has_mips_2)
                        seq_printf(m, "%s", " mips2");
                if (cpu_has_mips_3)
index 81f1dcf..a64daee 100644 (file)
@@ -90,12 +90,12 @@ int __mips_test_and_set_bit(unsigned long nr,
        unsigned bit = nr & SZLONG_MASK;
        unsigned long mask;
        unsigned long flags;
-       unsigned long res;
+       int res;
 
        a += nr >> SZLONG_LOG;
        mask = 1UL << bit;
        raw_local_irq_save(flags);
-       res = (mask & *a);
+       res = (mask & *a) != 0;
        *a |= mask;
        raw_local_irq_restore(flags);
        return res;
@@ -116,12 +116,12 @@ int __mips_test_and_set_bit_lock(unsigned long nr,
        unsigned bit = nr & SZLONG_MASK;
        unsigned long mask;
        unsigned long flags;
-       unsigned long res;
+       int res;
 
        a += nr >> SZLONG_LOG;
        mask = 1UL << bit;
        raw_local_irq_save(flags);
-       res = (mask & *a);
+       res = (mask & *a) != 0;
        *a |= mask;
        raw_local_irq_restore(flags);
        return res;
@@ -141,12 +141,12 @@ int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
        unsigned bit = nr & SZLONG_MASK;
        unsigned long mask;
        unsigned long flags;
-       unsigned long res;
+       int res;
 
        a += nr >> SZLONG_LOG;
        mask = 1UL << bit;
        raw_local_irq_save(flags);
-       res = (mask & *a);
+       res = (mask & *a) != 0;
        *a &= ~mask;
        raw_local_irq_restore(flags);
        return res;
@@ -166,12 +166,12 @@ int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
        unsigned bit = nr & SZLONG_MASK;
        unsigned long mask;
        unsigned long flags;
-       unsigned long res;
+       int res;
 
        a += nr >> SZLONG_LOG;
        mask = 1UL << bit;
        raw_local_irq_save(flags);
-       res = (mask & *a);
+       res = (mask & *a) != 0;
        *a ^= mask;
        raw_local_irq_restore(flags);
        return res;
index 507147a..a6adffb 100644 (file)
@@ -270,7 +270,7 @@ LEAF(csum_partial)
 #endif
 
        /* odd buffer alignment? */
-#ifdef CPU_MIPSR2
+#ifdef CONFIG_CPU_MIPSR2
        wsbh    v1, sum
        movn    sum, v1, t7
 #else
@@ -670,7 +670,7 @@ EXC(        sb      t0, NBYTES-2(dst), .Ls_exc)
        addu    sum, v1
 #endif
 
-#ifdef CPU_MIPSR2
+#ifdef CONFIG_CPU_MIPSR2
        wsbh    v1, sum
        movn    sum, v1, odd
 #else
index 4a29308..4a54431 100644 (file)
@@ -344,6 +344,7 @@ extern unsigned long MODULES_END;
 #define _REGION3_ENTRY_CO      0x100   /* change-recording override        */
 
 /* Bits in the segment table entry */
+#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address       */
 #define _SEGMENT_ENTRY_ORIGIN  ~0x7ffUL/* segment table origin             */
 #define _SEGMENT_ENTRY_RO      0x200   /* page protection bit              */
 #define _SEGMENT_ENTRY_INV     0x20    /* invalid segment table entry      */
@@ -1531,7 +1532,8 @@ extern int s390_enable_sie(void);
 /*
  * No page table caches to initialise
  */
-#define pgtable_cache_init()   do { } while (0)
+static inline void pgtable_cache_init(void) { }
+static inline void check_pgt_cache(void) { }
 
 #include <asm-generic/pgtable.h>
 
index dff631d..466fb33 100644 (file)
@@ -77,42 +77,69 @@ static size_t copy_in_kernel(size_t count, void __user *to,
  * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
  * contains the (negative) exception code.
  */
-static __always_inline unsigned long follow_table(struct mm_struct *mm,
-                                                 unsigned long addr, int write)
+#ifdef CONFIG_64BIT
+static unsigned long follow_table(struct mm_struct *mm,
+                                 unsigned long address, int write)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *ptep;
+       unsigned long *table = (unsigned long *)__pa(mm->pgd);
+
+       switch (mm->context.asce_bits & _ASCE_TYPE_MASK) {
+       case _ASCE_TYPE_REGION1:
+               table = table + ((address >> 53) & 0x7ff);
+               if (unlikely(*table & _REGION_ENTRY_INV))
+                       return -0x39UL;
+               table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+       case _ASCE_TYPE_REGION2:
+               table = table + ((address >> 42) & 0x7ff);
+               if (unlikely(*table & _REGION_ENTRY_INV))
+                       return -0x3aUL;
+               table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+       case _ASCE_TYPE_REGION3:
+               table = table + ((address >> 31) & 0x7ff);
+               if (unlikely(*table & _REGION_ENTRY_INV))
+                       return -0x3bUL;
+               table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+       case _ASCE_TYPE_SEGMENT:
+               table = table + ((address >> 20) & 0x7ff);
+               if (unlikely(*table & _SEGMENT_ENTRY_INV))
+                       return -0x10UL;
+               if (unlikely(*table & _SEGMENT_ENTRY_LARGE)) {
+                       if (write && (*table & _SEGMENT_ENTRY_RO))
+                               return -0x04UL;
+                       return (*table & _SEGMENT_ENTRY_ORIGIN_LARGE) +
+                               (address & ~_SEGMENT_ENTRY_ORIGIN_LARGE);
+               }
+               table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+       }
+       table = table + ((address >> 12) & 0xff);
+       if (unlikely(*table & _PAGE_INVALID))
+               return -0x11UL;
+       if (write && (*table & _PAGE_RO))
+               return -0x04UL;
+       return (*table & PAGE_MASK) + (address & ~PAGE_MASK);
+}
 
-       pgd = pgd_offset(mm, addr);
-       if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-               return -0x3aUL;
+#else /* CONFIG_64BIT */
 
-       pud = pud_offset(pgd, addr);
-       if (pud_none(*pud) || unlikely(pud_bad(*pud)))
-               return -0x3bUL;
+static unsigned long follow_table(struct mm_struct *mm,
+                                 unsigned long address, int write)
+{
+       unsigned long *table = (unsigned long *)__pa(mm->pgd);
 
-       pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd))
+       table = table + ((address >> 20) & 0x7ff);
+       if (unlikely(*table & _SEGMENT_ENTRY_INV))
                return -0x10UL;
-       if (pmd_large(*pmd)) {
-               if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
-                       return -0x04UL;
-               return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
-       }
-       if (unlikely(pmd_bad(*pmd)))
-               return -0x10UL;
-
-       ptep = pte_offset_map(pmd, addr);
-       if (!pte_present(*ptep))
+       table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+       table = table + ((address >> 12) & 0xff);
+       if (unlikely(*table & _PAGE_INVALID))
                return -0x11UL;
-       if (write && (!pte_write(*ptep) || !pte_dirty(*ptep)))
+       if (write && (*table & _PAGE_RO))
                return -0x04UL;
-
-       return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK);
+       return (*table & PAGE_MASK) + (address & ~PAGE_MASK);
 }
 
+#endif /* CONFIG_64BIT */
+
 static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
                                             size_t n, int write_user)
 {
@@ -197,7 +224,7 @@ size_t copy_to_user_pt(size_t n, void __user *to, const void *from)
 
 static size_t clear_user_pt(size_t n, void __user *to)
 {
-       void *zpage = &empty_zero_page;
+       void *zpage = (void *) empty_zero_page;
        long done, size, ret;
 
        done = 0;
index d1e15f7..7a5aa1a 100644 (file)
@@ -1004,15 +1004,8 @@ void __cpuinit setup_cpu(int boot)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
-/*
- * Note that the kernel can potentially support other compression
- * techniques than gz, though we don't do so by default.  If we ever
- * decide to do so we can either look for other filename extensions,
- * or just allow a file with this name to be compressed with an
- * arbitrary compressor (somewhat counterintuitively).
- */
 static int __initdata set_initramfs_file;
-static char __initdata initramfs_file[128] = "initramfs.cpio.gz";
+static char __initdata initramfs_file[128] = "initramfs";
 
 static int __init setup_initramfs_file(char *str)
 {
@@ -1026,9 +1019,9 @@ static int __init setup_initramfs_file(char *str)
 early_param("initramfs_file", setup_initramfs_file);
 
 /*
- * We look for an "initramfs.cpio.gz" file in the hvfs.
- * If there is one, we allocate some memory for it and it will be
- * unpacked to the initramfs.
+ * We look for a file called "initramfs" in the hvfs.  If there is one, we
+ * allocate some memory for it and it will be unpacked to the initramfs.
+ * If it's compressed, the initd code will uncompress it first.
  */
 static void __init load_hv_initrd(void)
 {
@@ -1038,10 +1031,16 @@ static void __init load_hv_initrd(void)
 
        fd = hv_fs_findfile((HV_VirtAddr) initramfs_file);
        if (fd == HV_ENOENT) {
-               if (set_initramfs_file)
+               if (set_initramfs_file) {
                        pr_warning("No such hvfs initramfs file '%s'\n",
                                   initramfs_file);
-               return;
+                       return;
+               } else {
+                       /* Try old backwards-compatible name. */
+                       fd = hv_fs_findfile((HV_VirtAddr)"initramfs.cpio.gz");
+                       if (fd == HV_ENOENT)
+                               return;
+               }
        }
        BUG_ON(fd < 0);
        stat = hv_fs_fstat(fd);
index e6732cf..79f4fca 100644 (file)
@@ -398,7 +398,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
                        base = 0;
 
                if (max < rbnode->base_reg + rbnode->blklen)
-                       end = rbnode->base_reg + rbnode->blklen - max;
+                       end = max - rbnode->base_reg + 1;
                else
                        end = rbnode->blklen;
 
index 3d23675..d34adef 100644 (file)
@@ -710,12 +710,12 @@ skip_format_initialization:
                }
        }
 
+       regmap_debugfs_init(map, config->name);
+
        ret = regcache_init(map, config);
        if (ret != 0)
                goto err_range;
 
-       regmap_debugfs_init(map, config->name);
-
        /* Add a devres resource for dev_get_regmap() */
        m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL);
        if (!m) {
@@ -943,8 +943,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
                unsigned int ival;
                int val_bytes = map->format.val_bytes;
                for (i = 0; i < val_len / val_bytes; i++) {
-                       memcpy(map->work_buf, val + (i * val_bytes), val_bytes);
-                       ival = map->format.parse_val(map->work_buf);
+                       ival = map->format.parse_val(val + (i * val_bytes));
                        ret = regcache_write(map, reg + (i * map->reg_stride),
                                             ival);
                        if (ret) {
@@ -1036,6 +1035,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
                        kfree(async->work_buf);
                        kfree(async);
                }
+
+               return ret;
        }
 
        trace_regmap_hw_write_start(map->dev, reg,
index 25ef5c0..92b6d7c 100644 (file)
@@ -51,8 +51,9 @@ new_skb(ulong len)
 {
        struct sk_buff *skb;
 
-       skb = alloc_skb(len, GFP_ATOMIC);
+       skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC);
        if (skb) {
+               skb_reserve(skb, MAX_HEADER);
                skb_reset_mac_header(skb);
                skb_reset_network_header(skb);
                skb->protocol = __constant_htons(ETH_P_AOE);
index fe5f640..2c127f9 100644 (file)
@@ -922,6 +922,11 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
                lo->lo_flags |= LO_FLAGS_PARTSCAN;
        if (lo->lo_flags & LO_FLAGS_PARTSCAN)
                ioctl_by_bdev(bdev, BLKRRPART, 0);
+
+       /* Grab the block_device to prevent its destruction after we
+        * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev).
+        */
+       bdgrab(bdev);
        return 0;
 
 out_clr:
@@ -1031,8 +1036,10 @@ static int loop_clr_fd(struct loop_device *lo)
        memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
        memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
        memset(lo->lo_file_name, 0, LO_NAME_SIZE);
-       if (bdev)
+       if (bdev) {
+               bdput(bdev);
                invalidate_bdev(bdev);
+       }
        set_capacity(lo->lo_disk, 0);
        loop_sysfs_exit(lo);
        if (bdev) {
index 69ae597..a0f7724 100644 (file)
@@ -380,6 +380,15 @@ void hwrng_unregister(struct hwrng *rng)
 }
 EXPORT_SYMBOL_GPL(hwrng_unregister);
 
+static void __exit hwrng_exit(void)
+{
+       mutex_lock(&rng_mutex);
+       BUG_ON(current_rng);
+       kfree(rng_buffer);
+       mutex_unlock(&rng_mutex);
+}
+
+module_exit(hwrng_exit);
 
 MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
 MODULE_LICENSE("GPL");
index e905d5f..ce5f3fc 100644 (file)
@@ -149,7 +149,8 @@ struct ports_device {
        spinlock_t ports_lock;
 
        /* To protect the vq operations for the control channel */
-       spinlock_t cvq_lock;
+       spinlock_t c_ivq_lock;
+       spinlock_t c_ovq_lock;
 
        /* The current config space is stored here */
        struct virtio_console_config config;
@@ -569,11 +570,14 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id,
        vq = portdev->c_ovq;
 
        sg_init_one(sg, &cpkt, sizeof(cpkt));
+
+       spin_lock(&portdev->c_ovq_lock);
        if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) {
                virtqueue_kick(vq);
                while (!virtqueue_get_buf(vq, &len))
                        cpu_relax();
        }
+       spin_unlock(&portdev->c_ovq_lock);
        return 0;
 }
 
@@ -1436,7 +1440,7 @@ static int add_port(struct ports_device *portdev, u32 id)
                 * rproc_serial does not want the console port, only
                 * the generic port implementation.
                 */
-               port->host_connected = port->guest_connected = true;
+               port->host_connected = true;
        else if (!use_multiport(port->portdev)) {
                /*
                 * If we're not using multiport support,
@@ -1709,23 +1713,23 @@ static void control_work_handler(struct work_struct *work)
        portdev = container_of(work, struct ports_device, control_work);
        vq = portdev->c_ivq;
 
-       spin_lock(&portdev->cvq_lock);
+       spin_lock(&portdev->c_ivq_lock);
        while ((buf = virtqueue_get_buf(vq, &len))) {
-               spin_unlock(&portdev->cvq_lock);
+               spin_unlock(&portdev->c_ivq_lock);
 
                buf->len = len;
                buf->offset = 0;
 
                handle_control_message(portdev, buf);
 
-               spin_lock(&portdev->cvq_lock);
+               spin_lock(&portdev->c_ivq_lock);
                if (add_inbuf(portdev->c_ivq, buf) < 0) {
                        dev_warn(&portdev->vdev->dev,
                                 "Error adding buffer to queue\n");
                        free_buf(buf, false);
                }
        }
-       spin_unlock(&portdev->cvq_lock);
+       spin_unlock(&portdev->c_ivq_lock);
 }
 
 static void out_intr(struct virtqueue *vq)
@@ -1752,13 +1756,23 @@ static void in_intr(struct virtqueue *vq)
        port->inbuf = get_inbuf(port);
 
        /*
-        * Don't queue up data when port is closed.  This condition
+        * Normally the port should not accept data when the port is
+        * closed. For generic serial ports, the host won't (shouldn't)
+        * send data till the guest is connected. But this condition
         * can be reached when a console port is not yet connected (no
-        * tty is spawned) and the host sends out data to console
-        * ports.  For generic serial ports, the host won't
-        * (shouldn't) send data till the guest is connected.
+        * tty is spawned) and the other side sends out data over the
+        * vring, or when a remote devices start sending data before
+        * the ports are opened.
+        *
+        * A generic serial port will discard data if not connected,
+        * while console ports and rproc-serial ports accepts data at
+        * any time. rproc-serial is initiated with guest_connected to
+        * false because port_fops_open expects this. Console ports are
+        * hooked up with an HVC console and is initialized with
+        * guest_connected to true.
         */
-       if (!port->guest_connected)
+
+       if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev))
                discard_port_data(port);
 
        spin_unlock_irqrestore(&port->inbuf_lock, flags);
@@ -1986,10 +2000,12 @@ static int virtcons_probe(struct virtio_device *vdev)
        if (multiport) {
                unsigned int nr_added_bufs;
 
-               spin_lock_init(&portdev->cvq_lock);
+               spin_lock_init(&portdev->c_ivq_lock);
+               spin_lock_init(&portdev->c_ovq_lock);
                INIT_WORK(&portdev->control_work, &control_work_handler);
 
-               nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
+               nr_added_bufs = fill_queue(portdev->c_ivq,
+                                          &portdev->c_ivq_lock);
                if (!nr_added_bufs) {
                        dev_err(&vdev->dev,
                                "Error allocating buffers for control queue\n");
@@ -2140,7 +2156,7 @@ static int virtcons_restore(struct virtio_device *vdev)
                return ret;
 
        if (use_multiport(portdev))
-               fill_queue(portdev->c_ivq, &portdev->cvq_lock);
+               fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
 
        list_for_each_entry(port, &portdev->ports, list) {
                port->in_vq = portdev->in_vqs[port->id];
index 1e2de73..f873dce 100644 (file)
@@ -703,7 +703,7 @@ static void tegra20_pll_init(void)
        clks[pll_a_out0] = clk;
 
        /* PLLE */
-       clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, NULL,
+       clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base,
                             0, 100000000, &pll_e_params,
                             0, pll_e_freq_table, NULL);
        clk_register_clkdev(clk, "pll_e", NULL);
index 80b6997..aeaea32 100644 (file)
@@ -83,6 +83,7 @@ config INTEL_IOP_ADMA
 
 config DW_DMAC
        tristate "Synopsys DesignWare AHB DMA support"
+       depends on GENERIC_HARDIRQS
        select DMA_ENGINE
        default y if CPU_AT32AP7000
        help
index 792c3e3..dd64a06 100644 (file)
@@ -2326,7 +2326,6 @@ int drm_mode_addfb(struct drm_device *dev,
        fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
        if (IS_ERR(fb)) {
                DRM_DEBUG_KMS("could not create framebuffer\n");
-               drm_modeset_unlock_all(dev);
                return PTR_ERR(fb);
        }
 
@@ -2506,7 +2505,6 @@ int drm_mode_addfb2(struct drm_device *dev,
        fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
        if (IS_ERR(fb)) {
                DRM_DEBUG_KMS("could not create framebuffer\n");
-               drm_modeset_unlock_all(dev);
                return PTR_ERR(fb);
        }
 
index 13fdcd1..429e07d 100644 (file)
@@ -123,6 +123,7 @@ int drm_open(struct inode *inode, struct file *filp)
        int retcode = 0;
        int need_setup = 0;
        struct address_space *old_mapping;
+       struct address_space *old_imapping;
 
        minor = idr_find(&drm_minors_idr, minor_id);
        if (!minor)
@@ -137,6 +138,7 @@ int drm_open(struct inode *inode, struct file *filp)
        if (!dev->open_count++)
                need_setup = 1;
        mutex_lock(&dev->struct_mutex);
+       old_imapping = inode->i_mapping;
        old_mapping = dev->dev_mapping;
        if (old_mapping == NULL)
                dev->dev_mapping = &inode->i_data;
@@ -159,8 +161,8 @@ int drm_open(struct inode *inode, struct file *filp)
 
 err_undo:
        mutex_lock(&dev->struct_mutex);
-       filp->f_mapping = old_mapping;
-       inode->i_mapping = old_mapping;
+       filp->f_mapping = old_imapping;
+       inode->i_mapping = old_imapping;
        iput(container_of(dev->dev_mapping, struct inode, i_data));
        dev->dev_mapping = old_mapping;
        mutex_unlock(&dev->struct_mutex);
index 3b11ab0..9a48e1a 100644 (file)
@@ -57,7 +57,7 @@ eb_create(struct drm_i915_gem_execbuffer2 *args)
        if (eb == NULL) {
                int size = args->buffer_count;
                int count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
-               BUILD_BUG_ON(!is_power_of_2(PAGE_SIZE / sizeof(struct hlist_head)));
+               BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head));
                while (count > 2*size)
                        count >>= 1;
                eb = kzalloc(count*sizeof(struct hlist_head) +
index 32a3693..1ce45a0 100644 (file)
@@ -45,6 +45,9 @@
 
 struct intel_crt {
        struct intel_encoder base;
+       /* DPMS state is stored in the connector, which we need in the
+        * encoder's enable/disable callbacks */
+       struct intel_connector *connector;
        bool force_hotplug_required;
        u32 adpa_reg;
 };
@@ -81,29 +84,6 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
        return true;
 }
 
-static void intel_disable_crt(struct intel_encoder *encoder)
-{
-       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-       struct intel_crt *crt = intel_encoder_to_crt(encoder);
-       u32 temp;
-
-       temp = I915_READ(crt->adpa_reg);
-       temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
-       temp &= ~ADPA_DAC_ENABLE;
-       I915_WRITE(crt->adpa_reg, temp);
-}
-
-static void intel_enable_crt(struct intel_encoder *encoder)
-{
-       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-       struct intel_crt *crt = intel_encoder_to_crt(encoder);
-       u32 temp;
-
-       temp = I915_READ(crt->adpa_reg);
-       temp |= ADPA_DAC_ENABLE;
-       I915_WRITE(crt->adpa_reg, temp);
-}
-
 /* Note: The caller is required to filter out dpms modes not supported by the
  * platform. */
 static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
@@ -135,6 +115,19 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
        I915_WRITE(crt->adpa_reg, temp);
 }
 
+static void intel_disable_crt(struct intel_encoder *encoder)
+{
+       intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
+static void intel_enable_crt(struct intel_encoder *encoder)
+{
+       struct intel_crt *crt = intel_encoder_to_crt(encoder);
+
+       intel_crt_set_dpms(encoder, crt->connector->base.dpms);
+}
+
+
 static void intel_crt_dpms(struct drm_connector *connector, int mode)
 {
        struct drm_device *dev = connector->dev;
@@ -746,6 +739,7 @@ void intel_crt_init(struct drm_device *dev)
        }
 
        connector = &intel_connector->base;
+       crt->connector = intel_connector;
        drm_connector_init(dev, &intel_connector->base,
                           &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
index d7d4afe..8fc93f9 100644 (file)
@@ -2559,12 +2559,15 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 {
        struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
        struct intel_dp *intel_dp = &intel_dig_port->dp;
+       struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
        i2c_del_adapter(&intel_dp->adapter);
        drm_encoder_cleanup(encoder);
        if (is_edp(intel_dp)) {
                cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
+               mutex_lock(&dev->mode_config.mutex);
                ironlake_panel_vdd_off_sync(intel_dp);
+               mutex_unlock(&dev->mode_config.mutex);
        }
        kfree(intel_dig_port);
 }
index 3b6dc88..5eb3e0d 100644 (file)
@@ -391,7 +391,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nouveau_device *device = nv_device(drm->device);
        struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
-       struct nouveau_abi16_chan *chan, *temp;
+       struct nouveau_abi16_chan *chan = NULL, *temp;
        struct nouveau_abi16_ntfy *ntfy;
        struct nouveau_object *object;
        struct nv_dma_class args = {};
@@ -404,10 +404,11 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
        if (unlikely(nv_device(abi16->device)->card_type >= NV_C0))
                return nouveau_abi16_put(abi16, -EINVAL);
 
-       list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
-               if (chan->chan->handle == (NVDRM_CHAN | info->channel))
+       list_for_each_entry(temp, &abi16->channels, head) {
+               if (temp->chan->handle == (NVDRM_CHAN | info->channel)) {
+                       chan = temp;
                        break;
-               chan = NULL;
+               }
        }
 
        if (!chan)
@@ -459,17 +460,18 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
 {
        struct drm_nouveau_gpuobj_free *fini = data;
        struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
-       struct nouveau_abi16_chan *chan, *temp;
+       struct nouveau_abi16_chan *chan = NULL, *temp;
        struct nouveau_abi16_ntfy *ntfy;
        int ret;
 
        if (unlikely(!abi16))
                return -ENOMEM;
 
-       list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
-               if (chan->chan->handle == (NVDRM_CHAN | fini->channel))
+       list_for_each_entry(temp, &abi16->channels, head) {
+               if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) {
+                       chan = temp;
                        break;
-               chan = NULL;
+               }
        }
 
        if (!chan)
index d109936..c95decf 100644 (file)
@@ -72,11 +72,25 @@ module_param_named(modeset, nouveau_modeset, int, 0400);
 static struct drm_driver driver;
 
 static int
+nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
+{
+       struct nouveau_drm *drm =
+               container_of(event, struct nouveau_drm, vblank[head]);
+       drm_handle_vblank(drm->dev, head);
+       return NVKM_EVENT_KEEP;
+}
+
+static int
 nouveau_drm_vblank_enable(struct drm_device *dev, int head)
 {
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nouveau_disp *pdisp = nouveau_disp(drm->device);
-       nouveau_event_get(pdisp->vblank, head, &drm->vblank);
+
+       if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank)))
+               return -EIO;
+       WARN_ON_ONCE(drm->vblank[head].func);
+       drm->vblank[head].func = nouveau_drm_vblank_handler;
+       nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]);
        return 0;
 }
 
@@ -85,16 +99,11 @@ nouveau_drm_vblank_disable(struct drm_device *dev, int head)
 {
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nouveau_disp *pdisp = nouveau_disp(drm->device);
-       nouveau_event_put(pdisp->vblank, head, &drm->vblank);
-}
-
-static int
-nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
-{
-       struct nouveau_drm *drm =
-               container_of(event, struct nouveau_drm, vblank);
-       drm_handle_vblank(drm->dev, head);
-       return NVKM_EVENT_KEEP;
+       if (drm->vblank[head].func)
+               nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]);
+       else
+               WARN_ON_ONCE(1);
+       drm->vblank[head].func = NULL;
 }
 
 static u64
@@ -292,7 +301,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
 
        dev->dev_private = drm;
        drm->dev = dev;
-       drm->vblank.func = nouveau_drm_vblank_handler;
 
        INIT_LIST_HEAD(&drm->clients);
        spin_lock_init(&drm->tile.lock);
index b25df37..9c39baf 100644 (file)
@@ -113,7 +113,7 @@ struct nouveau_drm {
        struct nvbios vbios;
        struct nouveau_display *display;
        struct backlight_device *backlight;
-       struct nouveau_eventh vblank;
+       struct nouveau_eventh vblank[4];
 
        /* power management */
        struct nouveau_pm *pm;
index 05d7b63..a0639e7 100644 (file)
@@ -204,7 +204,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC
 
 config VIDEO_SH_VEU
        tristate "SuperH VEU mem2mem video processing driver"
-       depends on VIDEO_DEV && VIDEO_V4L2
+       depends on VIDEO_DEV && VIDEO_V4L2 && GENERIC_HARDIRQS
        select VIDEOBUF2_DMA_CONTIG
        select V4L2_MEM2MEM_DEV
        help
index 6bbd90e..a51241b 100644 (file)
@@ -1976,12 +1976,11 @@ static int __bond_release_one(struct net_device *bond_dev,
                return -EINVAL;
        }
 
+       write_unlock_bh(&bond->lock);
        /* unregister rx_handler early so bond_handle_frame wouldn't be called
         * for this slave anymore.
         */
        netdev_rx_handler_unregister(slave_dev);
-       write_unlock_bh(&bond->lock);
-       synchronize_net();
        write_lock_bh(&bond->lock);
 
        if (!all && !bond->params.fail_over_mac) {
index db103e0..ea7a388 100644 (file)
@@ -527,7 +527,7 @@ static ssize_t bonding_store_arp_interval(struct device *d,
                goto out;
        }
        if (new_value < 0) {
-               pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
+               pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n",
                       bond->dev->name, new_value, INT_MAX);
                ret = -EINVAL;
                goto out;
@@ -542,14 +542,15 @@ static ssize_t bonding_store_arp_interval(struct device *d,
        pr_info("%s: Setting ARP monitoring interval to %d.\n",
                bond->dev->name, new_value);
        bond->params.arp_interval = new_value;
-       if (bond->params.miimon) {
-               pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
-                       bond->dev->name, bond->dev->name);
-               bond->params.miimon = 0;
-       }
-       if (!bond->params.arp_targets[0]) {
-               pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
-                       bond->dev->name);
+       if (new_value) {
+               if (bond->params.miimon) {
+                       pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
+                               bond->dev->name, bond->dev->name);
+                       bond->params.miimon = 0;
+               }
+               if (!bond->params.arp_targets[0])
+                       pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
+                               bond->dev->name);
        }
        if (bond->dev->flags & IFF_UP) {
                /* If the interface is up, we may need to fire off
@@ -557,10 +558,13 @@ static ssize_t bonding_store_arp_interval(struct device *d,
                 * timer will get fired off when the open function
                 * is called.
                 */
-               cancel_delayed_work_sync(&bond->mii_work);
-               queue_delayed_work(bond->wq, &bond->arp_work, 0);
+               if (!new_value) {
+                       cancel_delayed_work_sync(&bond->arp_work);
+               } else {
+                       cancel_delayed_work_sync(&bond->mii_work);
+                       queue_delayed_work(bond->wq, &bond->arp_work, 0);
+               }
        }
-
 out:
        rtnl_unlock();
        return ret;
@@ -702,7 +706,7 @@ static ssize_t bonding_store_downdelay(struct device *d,
        }
        if (new_value < 0) {
                pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
-                      bond->dev->name, new_value, 1, INT_MAX);
+                      bond->dev->name, new_value, 0, INT_MAX);
                ret = -EINVAL;
                goto out;
        } else {
@@ -757,8 +761,8 @@ static ssize_t bonding_store_updelay(struct device *d,
                goto out;
        }
        if (new_value < 0) {
-               pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
-                      bond->dev->name, new_value, 1, INT_MAX);
+               pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n",
+                      bond->dev->name, new_value, 0, INT_MAX);
                ret = -EINVAL;
                goto out;
        } else {
@@ -968,37 +972,37 @@ static ssize_t bonding_store_miimon(struct device *d,
        }
        if (new_value < 0) {
                pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
-                      bond->dev->name, new_value, 1, INT_MAX);
+                      bond->dev->name, new_value, 0, INT_MAX);
                ret = -EINVAL;
                goto out;
-       } else {
-               pr_info("%s: Setting MII monitoring interval to %d.\n",
-                       bond->dev->name, new_value);
-               bond->params.miimon = new_value;
-               if (bond->params.updelay)
-                       pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
-                               bond->dev->name,
-                               bond->params.updelay * bond->params.miimon);
-               if (bond->params.downdelay)
-                       pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
-                               bond->dev->name,
-                               bond->params.downdelay * bond->params.miimon);
-               if (bond->params.arp_interval) {
-                       pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
-                               bond->dev->name);
-                       bond->params.arp_interval = 0;
-                       if (bond->params.arp_validate) {
-                               bond->params.arp_validate =
-                                       BOND_ARP_VALIDATE_NONE;
-                       }
-               }
-
-               if (bond->dev->flags & IFF_UP) {
-                       /* If the interface is up, we may need to fire off
-                        * the MII timer. If the interface is down, the
-                        * timer will get fired off when the open function
-                        * is called.
-                        */
+       }
+       pr_info("%s: Setting MII monitoring interval to %d.\n",
+               bond->dev->name, new_value);
+       bond->params.miimon = new_value;
+       if (bond->params.updelay)
+               pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
+                       bond->dev->name,
+                       bond->params.updelay * bond->params.miimon);
+       if (bond->params.downdelay)
+               pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
+                       bond->dev->name,
+                       bond->params.downdelay * bond->params.miimon);
+       if (new_value && bond->params.arp_interval) {
+               pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
+                       bond->dev->name);
+               bond->params.arp_interval = 0;
+               if (bond->params.arp_validate)
+                       bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
+       }
+       if (bond->dev->flags & IFF_UP) {
+               /* If the interface is up, we may need to fire off
+                * the MII timer. If the interface is down, the
+                * timer will get fired off when the open function
+                * is called.
+                */
+               if (!new_value) {
+                       cancel_delayed_work_sync(&bond->mii_work);
+               } else {
                        cancel_delayed_work_sync(&bond->arp_work);
                        queue_delayed_work(bond->wq, &bond->mii_work, 0);
                }
index b39ca5b..ff2ba86 100644 (file)
@@ -46,6 +46,7 @@ config CAN_EMS_PCI
 config CAN_PEAK_PCMCIA
        tristate "PEAK PCAN-PC Card"
        depends on PCMCIA
+       depends on HAS_IOPORT
        ---help---
          This driver is for the PCAN-PC Card PCMCIA adapter (1 or 2 channels)
          from PEAK-System (http://www.peak-system.com). To compile this
index a042cdc..3c18d7d 100644 (file)
@@ -348,7 +348,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv)
         */
        if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) ==
            REG_CR_BASICCAN_INITIAL &&
-           (priv->read_reg(priv, REG_SR) == REG_SR_BASICCAN_INITIAL) &&
+           (priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_BASICCAN_INITIAL) &&
            (priv->read_reg(priv, REG_IR) == REG_IR_BASICCAN_INITIAL))
                flag = 1;
 
@@ -360,7 +360,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv)
         * See states on p. 23 of the Datasheet.
         */
        if (priv->read_reg(priv, REG_MOD) == REG_MOD_PELICAN_INITIAL &&
-           priv->read_reg(priv, REG_SR) == REG_SR_PELICAN_INITIAL &&
+           priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_PELICAN_INITIAL &&
            priv->read_reg(priv, REG_IR) == REG_IR_PELICAN_INITIAL)
                return flag;
 
index daf4013..e4df307 100644 (file)
@@ -92,7 +92,7 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
         */
        spin_lock_irqsave(&priv->cmdreg_lock, flags);
        priv->write_reg(priv, REG_CMR, val);
-       priv->read_reg(priv, REG_SR);
+       priv->read_reg(priv, SJA1000_REG_SR);
        spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
 }
 
@@ -502,7 +502,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 
        while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
                n++;
-               status = priv->read_reg(priv, REG_SR);
+               status = priv->read_reg(priv, SJA1000_REG_SR);
                /* check for absent controller due to hw unplug */
                if (status == 0xFF && sja1000_is_absent(priv))
                        return IRQ_NONE;
@@ -530,7 +530,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
                        /* receive interrupt */
                        while (status & SR_RBS) {
                                sja1000_rx(dev);
-                               status = priv->read_reg(priv, REG_SR);
+                               status = priv->read_reg(priv, SJA1000_REG_SR);
                                /* check for absent controller */
                                if (status == 0xFF && sja1000_is_absent(priv))
                                        return IRQ_NONE;
index afa9984..aa48e05 100644 (file)
@@ -56,7 +56,7 @@
 /* SJA1000 registers - manual section 6.4 (Pelican Mode) */
 #define REG_MOD                0x00
 #define REG_CMR                0x01
-#define REG_SR         0x02
+#define SJA1000_REG_SR         0x02
 #define REG_IR         0x03
 #define REG_IER                0x04
 #define REG_ALC                0x0B
index 829b5ad..edfdf6b 100644 (file)
@@ -438,7 +438,6 @@ struct atl1e_adapter {
        struct atl1e_hw        hw;
        struct atl1e_hw_stats  hw_stats;
 
-       bool have_msi;
        u32 wol;
        u16 link_speed;
        u16 link_duplex;
index 92f4734..f73d560 100644 (file)
@@ -1849,34 +1849,19 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
 
        free_irq(adapter->pdev->irq, netdev);
-
-       if (adapter->have_msi)
-               pci_disable_msi(adapter->pdev);
 }
 
 static int atl1e_request_irq(struct atl1e_adapter *adapter)
 {
        struct pci_dev    *pdev   = adapter->pdev;
        struct net_device *netdev = adapter->netdev;
-       int flags = 0;
        int err = 0;
 
-       adapter->have_msi = true;
-       err = pci_enable_msi(pdev);
-       if (err) {
-               netdev_dbg(netdev,
-                          "Unable to allocate MSI interrupt Error: %d\n", err);
-               adapter->have_msi = false;
-       }
-
-       if (!adapter->have_msi)
-               flags |= IRQF_SHARED;
-       err = request_irq(pdev->irq, atl1e_intr, flags, netdev->name, netdev);
+       err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name,
+                         netdev);
        if (err) {
                netdev_dbg(adapter->netdev,
                           "Unable to allocate interrupt Error: %d\n", err);
-               if (adapter->have_msi)
-                       pci_disable_msi(pdev);
                return err;
        }
        netdev_dbg(netdev, "atl1e_request_irq OK\n");
index 67d2663..17a9727 100644 (file)
@@ -14604,8 +14604,11 @@ static void tg3_read_vpd(struct tg3 *tp)
                if (j + len > block_end)
                        goto partno;
 
-               memcpy(tp->fw_ver, &vpd_data[j], len);
-               strncat(tp->fw_ver, " bc ", vpdlen - len - 1);
+               if (len >= sizeof(tp->fw_ver))
+                       len = sizeof(tp->fw_ver) - 1;
+               memset(tp->fw_ver, 0, sizeof(tp->fw_ver));
+               snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len,
+                        &vpd_data[j]);
        }
 
 partno:
index a170065..b0ebc9f 100644 (file)
 #define XGMAC_FLOW_CTRL_FCB_BPA        0x00000001      /* Flow Control Busy ... */
 
 /* XGMAC_INT_STAT reg */
+#define XGMAC_INT_STAT_PMTIM   0x00800000      /* PMT Interrupt Mask */
 #define XGMAC_INT_STAT_PMT     0x0080          /* PMT Interrupt Status */
 #define XGMAC_INT_STAT_LPI     0x0040          /* LPI Interrupt Status */
 
@@ -960,6 +961,9 @@ static int xgmac_hw_init(struct net_device *dev)
        writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS);
        writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA);
 
+       /* Mask power mgt interrupt */
+       writel(XGMAC_INT_STAT_PMTIM, ioaddr + XGMAC_INT_STAT);
+
        /* XGMAC requires AXI bus init. This is a 'magic number' for now */
        writel(0x0077000E, ioaddr + XGMAC_DMA_AXI_BUS);
 
@@ -1141,6 +1145,9 @@ static int xgmac_rx(struct xgmac_priv *priv, int limit)
                struct sk_buff *skb;
                int frame_len;
 
+               if (!dma_ring_cnt(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ))
+                       break;
+
                entry = priv->rx_tail;
                p = priv->dma_rx + entry;
                if (desc_get_owner(p))
@@ -1825,7 +1832,7 @@ static void xgmac_pmt(void __iomem *ioaddr, unsigned long mode)
        unsigned int pmt = 0;
 
        if (mode & WAKE_MAGIC)
-               pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT;
+               pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT_EN;
        if (mode & WAKE_UCAST)
                pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_GLBL_UNICAST;
 
index 8cdf025..9eada8e 100644 (file)
@@ -257,6 +257,107 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count)
                tmp = readl(reg);
 }
 
+/*
+ * Sleep, either by using msleep() or if we are suspending, then
+ * use mdelay() to sleep.
+ */
+static void dm9000_msleep(board_info_t *db, unsigned int ms)
+{
+       if (db->in_suspend)
+               mdelay(ms);
+       else
+               msleep(ms);
+}
+
+/* Read a word from phyxcer */
+static int
+dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
+{
+       board_info_t *db = netdev_priv(dev);
+       unsigned long flags;
+       unsigned int reg_save;
+       int ret;
+
+       mutex_lock(&db->addr_lock);
+
+       spin_lock_irqsave(&db->lock, flags);
+
+       /* Save previous register address */
+       reg_save = readb(db->io_addr);
+
+       /* Fill the phyxcer register into REG_0C */
+       iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+       /* Issue phyxcer read command */
+       iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);
+
+       writeb(reg_save, db->io_addr);
+       spin_unlock_irqrestore(&db->lock, flags);
+
+       dm9000_msleep(db, 1);           /* Wait read complete */
+
+       spin_lock_irqsave(&db->lock, flags);
+       reg_save = readb(db->io_addr);
+
+       iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer read command */
+
+       /* The read data keeps on REG_0D & REG_0E */
+       ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
+
+       /* restore the previous address */
+       writeb(reg_save, db->io_addr);
+       spin_unlock_irqrestore(&db->lock, flags);
+
+       mutex_unlock(&db->addr_lock);
+
+       dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
+       return ret;
+}
+
+/* Write a word to phyxcer */
+static void
+dm9000_phy_write(struct net_device *dev,
+                int phyaddr_unused, int reg, int value)
+{
+       board_info_t *db = netdev_priv(dev);
+       unsigned long flags;
+       unsigned long reg_save;
+
+       dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
+       mutex_lock(&db->addr_lock);
+
+       spin_lock_irqsave(&db->lock, flags);
+
+       /* Save previous register address */
+       reg_save = readb(db->io_addr);
+
+       /* Fill the phyxcer register into REG_0C */
+       iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+       /* Fill the written data into REG_0D & REG_0E */
+       iow(db, DM9000_EPDRL, value);
+       iow(db, DM9000_EPDRH, value >> 8);
+
+       /* Issue phyxcer write command */
+       iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);
+
+       writeb(reg_save, db->io_addr);
+       spin_unlock_irqrestore(&db->lock, flags);
+
+       dm9000_msleep(db, 1);           /* Wait write complete */
+
+       spin_lock_irqsave(&db->lock, flags);
+       reg_save = readb(db->io_addr);
+
+       iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer write command */
+
+       /* restore the previous address */
+       writeb(reg_save, db->io_addr);
+
+       spin_unlock_irqrestore(&db->lock, flags);
+       mutex_unlock(&db->addr_lock);
+}
+
 /* dm9000_set_io
  *
  * select the specified set of io routines to use with the
@@ -795,6 +896,9 @@ dm9000_init_dm9000(struct net_device *dev)
 
        iow(db, DM9000_GPCR, GPCR_GEP_CNTL);    /* Let GPIO0 output */
 
+       dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
+       dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */
+
        ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
 
        /* if wol is needed, then always set NCR_WAKEEN otherwise we end
@@ -1201,109 +1305,6 @@ dm9000_open(struct net_device *dev)
        return 0;
 }
 
-/*
- * Sleep, either by using msleep() or if we are suspending, then
- * use mdelay() to sleep.
- */
-static void dm9000_msleep(board_info_t *db, unsigned int ms)
-{
-       if (db->in_suspend)
-               mdelay(ms);
-       else
-               msleep(ms);
-}
-
-/*
- *   Read a word from phyxcer
- */
-static int
-dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
-{
-       board_info_t *db = netdev_priv(dev);
-       unsigned long flags;
-       unsigned int reg_save;
-       int ret;
-
-       mutex_lock(&db->addr_lock);
-
-       spin_lock_irqsave(&db->lock,flags);
-
-       /* Save previous register address */
-       reg_save = readb(db->io_addr);
-
-       /* Fill the phyxcer register into REG_0C */
-       iow(db, DM9000_EPAR, DM9000_PHY | reg);
-
-       iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);   /* Issue phyxcer read command */
-
-       writeb(reg_save, db->io_addr);
-       spin_unlock_irqrestore(&db->lock,flags);
-
-       dm9000_msleep(db, 1);           /* Wait read complete */
-
-       spin_lock_irqsave(&db->lock,flags);
-       reg_save = readb(db->io_addr);
-
-       iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer read command */
-
-       /* The read data keeps on REG_0D & REG_0E */
-       ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
-
-       /* restore the previous address */
-       writeb(reg_save, db->io_addr);
-       spin_unlock_irqrestore(&db->lock,flags);
-
-       mutex_unlock(&db->addr_lock);
-
-       dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
-       return ret;
-}
-
-/*
- *   Write a word to phyxcer
- */
-static void
-dm9000_phy_write(struct net_device *dev,
-                int phyaddr_unused, int reg, int value)
-{
-       board_info_t *db = netdev_priv(dev);
-       unsigned long flags;
-       unsigned long reg_save;
-
-       dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
-       mutex_lock(&db->addr_lock);
-
-       spin_lock_irqsave(&db->lock,flags);
-
-       /* Save previous register address */
-       reg_save = readb(db->io_addr);
-
-       /* Fill the phyxcer register into REG_0C */
-       iow(db, DM9000_EPAR, DM9000_PHY | reg);
-
-       /* Fill the written data into REG_0D & REG_0E */
-       iow(db, DM9000_EPDRL, value);
-       iow(db, DM9000_EPDRH, value >> 8);
-
-       iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);   /* Issue phyxcer write command */
-
-       writeb(reg_save, db->io_addr);
-       spin_unlock_irqrestore(&db->lock, flags);
-
-       dm9000_msleep(db, 1);           /* Wait write complete */
-
-       spin_lock_irqsave(&db->lock,flags);
-       reg_save = readb(db->io_addr);
-
-       iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer write command */
-
-       /* restore the previous address */
-       writeb(reg_save, db->io_addr);
-
-       spin_unlock_irqrestore(&db->lock, flags);
-       mutex_unlock(&db->addr_lock);
-}
-
 static void
 dm9000_shutdown(struct net_device *dev)
 {
@@ -1502,7 +1503,12 @@ dm9000_probe(struct platform_device *pdev)
        db->flags |= DM9000_PLATF_SIMPLE_PHY;
 #endif
 
-       dm9000_reset(db);
+       /* Fixing bug on dm9000_probe, takeover dm9000_reset(db),
+        * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo
+        * while probe stage.
+        */
+
+       iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST);
 
        /* try multiple times, DM9000 sometimes gets the read wrong */
        for (i = 0; i < 8; i++) {
index 55688bd..9ce058a 100644 (file)
@@ -69,7 +69,9 @@
 #define NCR_WAKEEN          (1<<6)
 #define NCR_FCOL            (1<<4)
 #define NCR_FDX             (1<<3)
-#define NCR_LBK             (3<<1)
+
+#define NCR_RESERVED        (3<<1)
+#define NCR_MAC_LBK         (1<<1)
 #define NCR_RST                    (1<<0)
 
 #define NSR_SPEED           (1<<7)
 #define ISR_LNKCHNG            (1<<5)
 #define ISR_UNDERRUN           (1<<4)
 
+/* Davicom MII registers.
+ */
+
+#define MII_DM_DSPCR           0x1b    /* DSP Control Register */
+
+#define DSPCR_INIT_PARAM       0xE100  /* DSP init parameter */
+
 #endif /* _DM9000X_H_ */
 
index 911d025..f292c3a 100644 (file)
@@ -345,6 +345,53 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        return NETDEV_TX_OK;
 }
 
+/* Init RX & TX buffer descriptors
+ */
+static void fec_enet_bd_init(struct net_device *dev)
+{
+       struct fec_enet_private *fep = netdev_priv(dev);
+       struct bufdesc *bdp;
+       unsigned int i;
+
+       /* Initialize the receive buffer descriptors. */
+       bdp = fep->rx_bd_base;
+       for (i = 0; i < RX_RING_SIZE; i++) {
+
+               /* Initialize the BD for every fragment in the page. */
+               if (bdp->cbd_bufaddr)
+                       bdp->cbd_sc = BD_ENET_RX_EMPTY;
+               else
+                       bdp->cbd_sc = 0;
+               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+       }
+
+       /* Set the last buffer to wrap */
+       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       fep->cur_rx = fep->rx_bd_base;
+
+       /* ...and the same for transmit */
+       bdp = fep->tx_bd_base;
+       fep->cur_tx = bdp;
+       for (i = 0; i < TX_RING_SIZE; i++) {
+
+               /* Initialize the BD for every fragment in the page. */
+               bdp->cbd_sc = 0;
+               if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) {
+                       dev_kfree_skb_any(fep->tx_skbuff[i]);
+                       fep->tx_skbuff[i] = NULL;
+               }
+               bdp->cbd_bufaddr = 0;
+               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+       }
+
+       /* Set the last buffer to wrap */
+       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+       bdp->cbd_sc |= BD_SC_WRAP;
+       fep->dirty_tx = bdp;
+}
+
 /* This function is called to start or restart the FEC during a link
  * change.  This only happens when switching between half and full
  * duplex.
@@ -388,6 +435,8 @@ fec_restart(struct net_device *ndev, int duplex)
        /* Set maximum receive buffer size. */
        writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
 
+       fec_enet_bd_init(ndev);
+
        /* Set receive and transmit descriptor base. */
        writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
        if (fep->bufdesc_ex)
@@ -397,7 +446,6 @@ fec_restart(struct net_device *ndev, int duplex)
                writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc)
                        * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
 
-       fep->cur_rx = fep->rx_bd_base;
 
        for (i = 0; i <= TX_RING_MOD_MASK; i++) {
                if (fep->tx_skbuff[i]) {
@@ -1597,8 +1645,6 @@ static int fec_enet_init(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
        struct bufdesc *cbd_base;
-       struct bufdesc *bdp;
-       unsigned int i;
 
        /* Allocate memory for buffer descriptors. */
        cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
@@ -1608,6 +1654,7 @@ static int fec_enet_init(struct net_device *ndev)
                return -ENOMEM;
        }
 
+       memset(cbd_base, 0, PAGE_SIZE);
        spin_lock_init(&fep->hw_lock);
 
        fep->netdev = ndev;
@@ -1631,35 +1678,6 @@ static int fec_enet_init(struct net_device *ndev)
        writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
        netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT);
 
-       /* Initialize the receive buffer descriptors. */
-       bdp = fep->rx_bd_base;
-       for (i = 0; i < RX_RING_SIZE; i++) {
-
-               /* Initialize the BD for every fragment in the page. */
-               bdp->cbd_sc = 0;
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
-       }
-
-       /* Set the last buffer to wrap */
-       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
-       bdp->cbd_sc |= BD_SC_WRAP;
-
-       /* ...and the same for transmit */
-       bdp = fep->tx_bd_base;
-       fep->cur_tx = bdp;
-       for (i = 0; i < TX_RING_SIZE; i++) {
-
-               /* Initialize the BD for every fragment in the page. */
-               bdp->cbd_sc = 0;
-               bdp->cbd_bufaddr = 0;
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
-       }
-
-       /* Set the last buffer to wrap */
-       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
-       bdp->cbd_sc |= BD_SC_WRAP;
-       fep->dirty_tx = bdp;
-
        fec_restart(ndev, 0);
 
        return 0;
index 43462d5..ffd2871 100644 (file)
@@ -1053,6 +1053,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
                txdr->buffer_info[i].dma =
                        dma_map_single(&pdev->dev, skb->data, skb->len,
                                       DMA_TO_DEVICE);
+               if (dma_mapping_error(&pdev->dev, txdr->buffer_info[i].dma)) {
+                       ret_val = 4;
+                       goto err_nomem;
+               }
                tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma);
                tx_desc->lower.data = cpu_to_le32(skb->len);
                tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
@@ -1069,7 +1073,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
        rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_buffer),
                                    GFP_KERNEL);
        if (!rxdr->buffer_info) {
-               ret_val = 4;
+               ret_val = 5;
                goto err_nomem;
        }
 
@@ -1077,7 +1081,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
        rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
                                        GFP_KERNEL);
        if (!rxdr->desc) {
-               ret_val = 5;
+               ret_val = 6;
                goto err_nomem;
        }
        memset(rxdr->desc, 0, rxdr->size);
@@ -1101,7 +1105,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 
                skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
                if (!skb) {
-                       ret_val = 6;
+                       ret_val = 7;
                        goto err_nomem;
                }
                skb_reserve(skb, NET_IP_ALIGN);
@@ -1110,6 +1114,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
                rxdr->buffer_info[i].dma =
                        dma_map_single(&pdev->dev, skb->data,
                                       E1000_RXBUFFER_2048, DMA_FROM_DEVICE);
+               if (dma_mapping_error(&pdev->dev, rxdr->buffer_info[i].dma)) {
+                       ret_val = 8;
+                       goto err_nomem;
+               }
                rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma);
                memset(skb->data, 0x00, skb->len);
        }
index 948b86f..7e615e2 100644 (file)
@@ -848,11 +848,16 @@ check_page:
                        }
                }
 
-               if (!buffer_info->dma)
+               if (!buffer_info->dma) {
                        buffer_info->dma = dma_map_page(&pdev->dev,
                                                        buffer_info->page, 0,
                                                        PAGE_SIZE,
                                                        DMA_FROM_DEVICE);
+                       if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
+                               adapter->alloc_rx_buff_failed++;
+                               break;
+                       }
+               }
 
                rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
                rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
index ea48083..b5f94ab 100644 (file)
@@ -2159,6 +2159,10 @@ map_skb:
                                                  skb->data,
                                                  adapter->rx_buffer_len,
                                                  DMA_FROM_DEVICE);
+               if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
+                       adapter->alloc_rx_buff_failed++;
+                       break;
+               }
 
                rx_desc = IXGB_RX_DESC(*rx_ring, i);
                rx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
@@ -2168,7 +2172,8 @@ map_skb:
                rx_desc->status = 0;
 
 
-               if (++i == rx_ring->count) i = 0;
+               if (++i == rx_ring->count)
+                       i = 0;
                buffer_info = &rx_ring->buffer_info[i];
        }
 
index fc07ca3..6a0e671 100644 (file)
@@ -1067,7 +1067,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space)
                sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
                sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
 
-               tp = space - 2048/8;
+               tp = space - 8192/8;
                sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
                sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
        } else {
index 615ac63..ec6dcd8 100644 (file)
@@ -2074,7 +2074,7 @@ enum {
        GM_IS_RX_FF_OR  = 1<<1, /* Receive FIFO Overrun */
        GM_IS_RX_COMPL  = 1<<0, /* Frame Reception Complete */
 
-#define GMAC_DEF_MSK     GM_IS_TX_FF_UR
+#define GMAC_DEF_MSK     (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR)
 };
 
 /*     GMAC_LINK_CTRL  16 bit  GMAC Link Control Reg (YUKON only) */
index f278b10..30d78f8 100644 (file)
@@ -411,8 +411,8 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 
 static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac)
 {
-       unsigned int i;
-       for (i = ETH_ALEN - 1; i; --i) {
+       int i;
+       for (i = ETH_ALEN - 1; i >= 0; --i) {
                dst_mac[i] = src_mac & 0xff;
                src_mac >>= 8;
        }
index 33bcb63..8fb4812 100644 (file)
@@ -528,7 +528,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
        for (; rxfc != 0; rxfc--) {
                rxh = ks8851_rdreg32(ks, KS_RXFHSR);
                rxstat = rxh & 0xffff;
-               rxlen = rxh >> 16;
+               rxlen = (rxh >> 16) & 0xfff;
 
                netif_dbg(ks, rx_status, ks->netdev,
                          "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen);
index bf5e3cf..6ed333f 100644 (file)
@@ -1216,10 +1216,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
                if (felic_stat & ECSR_LCHNG) {
                        /* Link Changed */
                        if (mdp->cd->no_psr || mdp->no_ether_link) {
-                               if (mdp->link == PHY_DOWN)
-                                       link_stat = 0;
-                               else
-                                       link_stat = PHY_ST_LINK;
+                               goto ignore_link;
                        } else {
                                link_stat = (sh_eth_read(ndev, PSR));
                                if (mdp->ether_link_active_low)
@@ -1242,6 +1239,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
                }
        }
 
+ignore_link:
        if (intr_status & EESR_TWB) {
                /* Write buck end. unused write back interrupt */
                if (intr_status & EESR_TABT)    /* Transmit Abort int */
@@ -1326,12 +1324,18 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
        struct sh_eth_private *mdp = netdev_priv(ndev);
        struct sh_eth_cpu_data *cd = mdp->cd;
        irqreturn_t ret = IRQ_NONE;
-       u32 intr_status = 0;
+       unsigned long intr_status;
 
        spin_lock(&mdp->lock);
 
-       /* Get interrpt stat */
+       /* Get interrupt status */
        intr_status = sh_eth_read(ndev, EESR);
+       /* Mask it with the interrupt mask, forcing ECI interrupt to be always
+        * enabled since it's the one that  comes thru regardless of the mask,
+        * and we need to fully handle it in sh_eth_error() in order to quench
+        * it as it doesn't get cleared by just writing 1 to the ECI bit...
+        */
+       intr_status &= sh_eth_read(ndev, EESIPR) | DMAC_M_ECI;
        /* Clear interrupt */
        if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
                        EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
@@ -1373,7 +1377,7 @@ static void sh_eth_adjust_link(struct net_device *ndev)
        struct phy_device *phydev = mdp->phydev;
        int new_state = 0;
 
-       if (phydev->link != PHY_DOWN) {
+       if (phydev->link) {
                if (phydev->duplex != mdp->duplex) {
                        new_state = 1;
                        mdp->duplex = phydev->duplex;
@@ -1387,17 +1391,21 @@ static void sh_eth_adjust_link(struct net_device *ndev)
                        if (mdp->cd->set_rate)
                                mdp->cd->set_rate(ndev);
                }
-               if (mdp->link == PHY_DOWN) {
+               if (!mdp->link) {
                        sh_eth_write(ndev,
                                (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR);
                        new_state = 1;
                        mdp->link = phydev->link;
+                       if (mdp->cd->no_psr || mdp->no_ether_link)
+                               sh_eth_rcv_snd_enable(ndev);
                }
        } else if (mdp->link) {
                new_state = 1;
-               mdp->link = PHY_DOWN;
+               mdp->link = 0;
                mdp->speed = 0;
                mdp->duplex = -1;
+               if (mdp->cd->no_psr || mdp->no_ether_link)
+                       sh_eth_rcv_snd_disable(ndev);
        }
 
        if (new_state && netif_msg_link(mdp))
@@ -1414,7 +1422,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
        snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
                mdp->mii_bus->id , mdp->phy_id);
 
-       mdp->link = PHY_DOWN;
+       mdp->link = 0;
        mdp->speed = 0;
        mdp->duplex = -1;
 
index e665567..828be45 100644 (file)
@@ -723,7 +723,7 @@ struct sh_eth_private {
        u32 phy_id;                                     /* PHY ID */
        struct mii_bus *mii_bus;        /* MDIO bus control */
        struct phy_device *phydev;      /* PHY device control */
-       enum phy_state link;
+       int link;
        phy_interface_t phy_interface;
        int msg_enable;
        int speed;
index df32a09..80cad06 100644 (file)
@@ -436,7 +436,7 @@ void cpsw_tx_handler(void *token, int len, int status)
         * queue is stopped then start the queue as we have free desc for tx
         */
        if (unlikely(netif_queue_stopped(ndev)))
-               netif_start_queue(ndev);
+               netif_wake_queue(ndev);
        cpts_tx_timestamp(priv->cpts, skb);
        priv->stats.tx_packets++;
        priv->stats.tx_bytes += len;
index ae1b77a..72300bc 100644 (file)
@@ -1053,7 +1053,7 @@ static void emac_tx_handler(void *token, int len, int status)
         * queue is stopped then start the queue as we have free desc for tx
         */
        if (unlikely(netif_queue_stopped(ndev)))
-               netif_start_queue(ndev);
+               netif_wake_queue(ndev);
        ndev->stats.tx_packets++;
        ndev->stats.tx_bytes += len;
        dev_kfree_skb_any(skb);
index 9abe517..1a15ec1 100644 (file)
@@ -914,8 +914,12 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
 static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
 {
        struct usbnet *dev = netdev_priv(netdev);
+       int ret;
+
+       if (new_mtu > MAX_SINGLE_PACKET_SIZE)
+               return -EINVAL;
 
-       int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
+       ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN);
        if (ret < 0) {
                netdev_warn(dev->net, "Failed to set mac rx frame length\n");
                return ret;
@@ -1324,7 +1328,7 @@ static int smsc75xx_reset(struct usbnet *dev)
 
        netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf);
 
-       ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
+       ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN);
        if (ret < 0) {
                netdev_warn(dev->net, "Failed to set max rx frame length\n");
                return ret;
@@ -2134,8 +2138,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
                        else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
                                dev->net->stats.rx_frame_errors++;
                } else {
-                       /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
-                       if (unlikely(size > (ETH_FRAME_LEN + 12))) {
+                       /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */
+                       if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) {
                                netif_dbg(dev, rx_err, dev->net,
                                          "size err rx_cmd_a=0x%08x\n",
                                          rx_cmd_a);
index 39c84ec..7fdac6c 100644 (file)
@@ -170,7 +170,8 @@ void ath_rx_poll(unsigned long data)
 {
        struct ath_softc *sc = (struct ath_softc *)data;
 
-       ieee80211_queue_work(sc->hw, &sc->hw_check_work);
+       if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
+               ieee80211_queue_work(sc->hw, &sc->hw_check_work);
 }
 
 /*
index 38bc5a7..1221469 100644 (file)
@@ -1487,8 +1487,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
        const struct b43_dma_ops *ops;
        struct b43_dmaring *ring;
        struct b43_dmadesc_meta *meta;
+       static const struct b43_txstatus fake; /* filled with 0 */
+       const struct b43_txstatus *txstat;
        int slot, firstused;
        bool frame_succeed;
+       int skip;
+       static u8 err_out1, err_out2;
 
        ring = parse_cookie(dev, status->cookie, &slot);
        if (unlikely(!ring))
@@ -1501,13 +1505,36 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
        firstused = ring->current_slot - ring->used_slots + 1;
        if (firstused < 0)
                firstused = ring->nr_slots + firstused;
+
+       skip = 0;
        if (unlikely(slot != firstused)) {
                /* This possibly is a firmware bug and will result in
-                * malfunction, memory leaks and/or stall of DMA functionality. */
-               b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. "
-                      "Expected %d, but got %d\n",
-                      ring->index, firstused, slot);
-               return;
+                * malfunction, memory leaks and/or stall of DMA functionality.
+                */
+               if (slot == next_slot(ring, next_slot(ring, firstused))) {
+                       /* If a single header/data pair was missed, skip over
+                        * the first two slots in an attempt to recover.
+                        */
+                       slot = firstused;
+                       skip = 2;
+                       if (!err_out1) {
+                               /* Report the error once. */
+                               b43dbg(dev->wl,
+                                      "Skip on DMA ring %d slot %d.\n",
+                                      ring->index, slot);
+                               err_out1 = 1;
+                       }
+               } else {
+                       /* More than a single header/data pair were missed.
+                        * Report this error once.
+                        */
+                       if (!err_out2)
+                               b43dbg(dev->wl,
+                                      "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n",
+                                      ring->index, firstused, slot);
+                       err_out2 = 1;
+                       return;
+               }
        }
 
        ops = ring->ops;
@@ -1522,11 +1549,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                               slot, firstused, ring->index);
                        break;
                }
+
                if (meta->skb) {
                        struct b43_private_tx_info *priv_info =
-                               b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
+                            b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
 
-                       unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
+                       unmap_descbuffer(ring, meta->dmaaddr,
+                                        meta->skb->len, 1);
                        kfree(priv_info->bouncebuffer);
                        priv_info->bouncebuffer = NULL;
                } else {
@@ -1538,8 +1567,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                        struct ieee80211_tx_info *info;
 
                        if (unlikely(!meta->skb)) {
-                               /* This is a scatter-gather fragment of a frame, so
-                                * the skb pointer must not be NULL. */
+                               /* This is a scatter-gather fragment of a frame,
+                                * so the skb pointer must not be NULL.
+                                */
                                b43dbg(dev->wl, "TX status unexpected NULL skb "
                                       "at slot %d (first=%d) on ring %d\n",
                                       slot, firstused, ring->index);
@@ -1550,9 +1580,18 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
 
                        /*
                         * Call back to inform the ieee80211 subsystem about
-                        * the status of the transmission.
+                        * the status of the transmission. When skipping over
+                        * a missed TX status report, use a status structure
+                        * filled with zeros to indicate that the frame was not
+                        * sent (frame_count 0) and not acknowledged
                         */
-                       frame_succeed = b43_fill_txstatus_report(dev, info, status);
+                       if (unlikely(skip))
+                               txstat = &fake;
+                       else
+                               txstat = status;
+
+                       frame_succeed = b43_fill_txstatus_report(dev, info,
+                                                                txstat);
 #ifdef CONFIG_B43_DEBUG
                        if (frame_succeed)
                                ring->nr_succeed_tx_packets++;
@@ -1580,12 +1619,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                /* Everything unmapped and free'd. So it's not used anymore. */
                ring->used_slots--;
 
-               if (meta->is_last_fragment) {
+               if (meta->is_last_fragment && !skip) {
                        /* This is the last scatter-gather
                         * fragment of the frame. We are done. */
                        break;
                }
                slot = next_slot(ring, slot);
+               if (skip > 0)
+                       --skip;
        }
        if (ring->stopped) {
                B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
index 3c35382..e8486c1 100644 (file)
@@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
        u16 clip_off[2] = { 0xFFFF, 0xFFFF };
 
        u8 vcm_final = 0;
-       s8 offset[4];
+       s32 offset[4];
        s32 results[8][4] = { };
        s32 results_min[4] = { };
        s32 poll_results[4] = { };
@@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
                }
                for (i = 0; i < 4; i += 2) {
                        s32 curr;
-                       s32 mind = 40;
+                       s32 mind = 0x100000;
                        s32 minpoll = 249;
                        u8 minvcm = 0;
                        if (2 * core != i)
@@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
        u8 regs_save_radio[2];
        u16 regs_save_phy[2];
 
-       s8 offset[4];
+       s32 offset[4];
        u8 core;
        u8 rail;
 
@@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
        }
 
        for (i = 0; i < 4; i++) {
-               s32 mind = 40;
+               s32 mind = 0x100000;
                u8 minvcm = 0;
                s32 minpoll = 249;
                s32 curr;
index 21a8242..18d3764 100644 (file)
@@ -1137,9 +1137,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
        gain0_15 = ((biq1 & 0xf) << 12) |
                   ((tia & 0xf) << 8) |
                   ((lna2 & 0x3) << 6) |
-                  ((lna2 & 0x3) << 4) |
-                  ((lna1 & 0x3) << 2) |
-                  ((lna1 & 0x3) << 0);
+                  ((lna2 &
+                    0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
 
        mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
        mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1157,8 +1156,6 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
        }
 
        mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
-       mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
-       mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
 
 }
 
@@ -1331,43 +1328,6 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
        return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
 }
 
-static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
-                                     u16 tia_gain, u16 lna2_gain)
-{
-       u32 i_thresh_l, q_thresh_l;
-       u32 i_thresh_h, q_thresh_h;
-       struct lcnphy_iq_est iq_est_h, iq_est_l;
-
-       wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
-                                              lna2_gain, 0);
-
-       wlc_lcnphy_rx_gain_override_enable(pi, true);
-       wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
-       udelay(500);
-       write_radio_reg(pi, RADIO_2064_REG112, 0);
-       if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
-               return false;
-
-       wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
-       udelay(500);
-       write_radio_reg(pi, RADIO_2064_REG112, 0);
-       if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
-               return false;
-
-       i_thresh_l = (iq_est_l.i_pwr << 1);
-       i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
-
-       q_thresh_l = (iq_est_l.q_pwr << 1);
-       q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
-       if ((iq_est_h.i_pwr > i_thresh_l) &&
-           (iq_est_h.i_pwr < i_thresh_h) &&
-           (iq_est_h.q_pwr > q_thresh_l) &&
-           (iq_est_h.q_pwr < q_thresh_h))
-               return true;
-
-       return false;
-}
-
 static bool
 wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
                     const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1382,8 +1342,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
            RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
            rfoverride3_old, rfoverride3val_old, rfoverride4_old,
            rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
-       int tia_gain, lna2_gain, biq1_gain;
-       bool set_gain;
+       int tia_gain;
+       u32 received_power, rx_pwr_threshold;
        u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
        u16 values_to_save[11];
        s16 *ptr;
@@ -1408,134 +1368,126 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
                goto cal_done;
        }
 
-       WARN_ON(module != 1);
-       tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
-       wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
-
-       for (i = 0; i < 11; i++)
-               values_to_save[i] =
-                       read_radio_reg(pi, rxiq_cal_rf_reg[i]);
-       Core1TxControl_old = read_phy_reg(pi, 0x631);
-
-       or_phy_reg(pi, 0x631, 0x0015);
-
-       RFOverride0_old = read_phy_reg(pi, 0x44c);
-       RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
-       rfoverride2_old = read_phy_reg(pi, 0x4b0);
-       rfoverride2val_old = read_phy_reg(pi, 0x4b1);
-       rfoverride3_old = read_phy_reg(pi, 0x4f9);
-       rfoverride3val_old = read_phy_reg(pi, 0x4fa);
-       rfoverride4_old = read_phy_reg(pi, 0x938);
-       rfoverride4val_old = read_phy_reg(pi, 0x939);
-       afectrlovr_old = read_phy_reg(pi, 0x43b);
-       afectrlovrval_old = read_phy_reg(pi, 0x43c);
-       old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
-       old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
-
-       tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
-       if (tx_gain_override_old) {
-               wlc_lcnphy_get_tx_gain(pi, &old_gains);
-               tx_gain_index_old = pi_lcn->lcnphy_current_index;
-       }
-
-       wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+       if (module == 1) {
 
-       mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
-       mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+               tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+               wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
 
-       mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
-       mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+               for (i = 0; i < 11; i++)
+                       values_to_save[i] =
+                               read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+               Core1TxControl_old = read_phy_reg(pi, 0x631);
+
+               or_phy_reg(pi, 0x631, 0x0015);
+
+               RFOverride0_old = read_phy_reg(pi, 0x44c);
+               RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+               rfoverride2_old = read_phy_reg(pi, 0x4b0);
+               rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+               rfoverride3_old = read_phy_reg(pi, 0x4f9);
+               rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+               rfoverride4_old = read_phy_reg(pi, 0x938);
+               rfoverride4val_old = read_phy_reg(pi, 0x939);
+               afectrlovr_old = read_phy_reg(pi, 0x43b);
+               afectrlovrval_old = read_phy_reg(pi, 0x43c);
+               old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+               old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
+
+               tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+               if (tx_gain_override_old) {
+                       wlc_lcnphy_get_tx_gain(pi, &old_gains);
+                       tx_gain_index_old = pi_lcn->lcnphy_current_index;
+               }
 
-       write_radio_reg(pi, RADIO_2064_REG116, 0x06);
-       write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
-       write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
-       write_radio_reg(pi, RADIO_2064_REG098, 0x03);
-       write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
-       mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
-       write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
-       write_radio_reg(pi, RADIO_2064_REG114, 0x01);
-       write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
-       write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
-
-       mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
-       mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
-       mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
-       mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
-       mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
-       mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
-       mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
-       mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
-       mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
-       mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
+               wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
 
-       mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
-       mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+               mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+               mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
 
-       write_phy_reg(pi, 0x6da, 0xffff);
-       or_phy_reg(pi, 0x6db, 0x3);
+               mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+               mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
 
-       wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
-       set_gain = false;
-
-       lna2_gain = 3;
-       while ((lna2_gain >= 0) && !set_gain) {
-               tia_gain = 4;
-
-               while ((tia_gain >= 0) && !set_gain) {
-                       biq1_gain = 6;
-
-                       while ((biq1_gain >= 0) && !set_gain) {
-                               set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
-                                                                    (u16)
-                                                                    biq1_gain,
-                                                                    (u16)
-                                                                    tia_gain,
-                                                                    (u16)
-                                                                    lna2_gain);
-                               biq1_gain -= 1;
-                       }
+               write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+               write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+               write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+               write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+               write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+               mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+               write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+               write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+               write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+               write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+
+               mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+               mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+               mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+               mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+               mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+               mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+               mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+               mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+               mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+               mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
+
+               mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+               mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+
+               wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
+               write_phy_reg(pi, 0x6da, 0xffff);
+               or_phy_reg(pi, 0x6db, 0x3);
+               wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+               wlc_lcnphy_rx_gain_override_enable(pi, true);
+
+               tia_gain = 8;
+               rx_pwr_threshold = 950;
+               while (tia_gain > 0) {
                        tia_gain -= 1;
+                       wlc_lcnphy_set_rx_gain_by_distribution(pi,
+                                                              0, 0, 2, 2,
+                                                              (u16)
+                                                              tia_gain, 1, 0);
+                       udelay(500);
+
+                       received_power =
+                               wlc_lcnphy_measure_digital_power(pi, 2000);
+                       if (received_power < rx_pwr_threshold)
+                               break;
                }
-               lna2_gain -= 1;
-       }
+               result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
 
-       if (set_gain)
-               result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
-       else
-               result = false;
+               wlc_lcnphy_stop_tx_tone(pi);
 
-       wlc_lcnphy_stop_tx_tone(pi);
+               write_phy_reg(pi, 0x631, Core1TxControl_old);
 
-       write_phy_reg(pi, 0x631, Core1TxControl_old);
-
-       write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
-       write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
-       write_phy_reg(pi, 0x4b0, rfoverride2_old);
-       write_phy_reg(pi, 0x4b1, rfoverride2val_old);
-       write_phy_reg(pi, 0x4f9, rfoverride3_old);
-       write_phy_reg(pi, 0x4fa, rfoverride3val_old);
-       write_phy_reg(pi, 0x938, rfoverride4_old);
-       write_phy_reg(pi, 0x939, rfoverride4val_old);
-       write_phy_reg(pi, 0x43b, afectrlovr_old);
-       write_phy_reg(pi, 0x43c, afectrlovrval_old);
-       write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
-       write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+               write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+               write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+               write_phy_reg(pi, 0x4b0, rfoverride2_old);
+               write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+               write_phy_reg(pi, 0x4f9, rfoverride3_old);
+               write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+               write_phy_reg(pi, 0x938, rfoverride4_old);
+               write_phy_reg(pi, 0x939, rfoverride4val_old);
+               write_phy_reg(pi, 0x43b, afectrlovr_old);
+               write_phy_reg(pi, 0x43c, afectrlovrval_old);
+               write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+               write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
 
-       wlc_lcnphy_clear_trsw_override(pi);
+               wlc_lcnphy_clear_trsw_override(pi);
 
-       mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+               mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
 
-       for (i = 0; i < 11; i++)
-               write_radio_reg(pi, rxiq_cal_rf_reg[i],
-                               values_to_save[i]);
+               for (i = 0; i < 11; i++)
+                       write_radio_reg(pi, rxiq_cal_rf_reg[i],
+                                       values_to_save[i]);
 
-       if (tx_gain_override_old)
-               wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
-       else
-               wlc_lcnphy_disable_tx_gain_override(pi);
+               if (tx_gain_override_old)
+                       wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+               else
+                       wlc_lcnphy_disable_tx_gain_override(pi);
 
-       wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
-       wlc_lcnphy_rx_gain_override_enable(pi, false);
+               wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+               wlc_lcnphy_rx_gain_override_enable(pi, false);
+       }
 
 cal_done:
        kfree(ptr);
@@ -1829,17 +1781,6 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
                write_radio_reg(pi, RADIO_2064_REG038, 3);
                write_radio_reg(pi, RADIO_2064_REG091, 7);
        }
-
-       if (!(pi->sh->boardflags & BFL_FEM)) {
-               u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
-                       0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
-
-               write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
-               write_radio_reg(pi, RADIO_2064_REG091, 0x3);
-               write_radio_reg(pi, RADIO_2064_REG038, 0x3);
-
-               write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
-       }
 }
 
 static int
@@ -2034,16 +1975,6 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
                } else {
                        mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
                        mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
-                       mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
-                       mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
-                       mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
-                       mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
-                       mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
-                       mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
-                       mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
-                       mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
-                       mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
-                       mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
                }
        } else {
                mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2130,14 +2061,12 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
                    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
 
        mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
-       mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
 }
 
 static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 {
        struct phytbl_info tab;
        u32 rfseq, ind;
-       u8 tssi_sel;
 
        tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
        tab.tbl_width = 32;
@@ -2159,13 +2088,7 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 
        mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
 
-       if (pi->sh->boardflags & BFL_FEM) {
-               tssi_sel = 0x1;
-               wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
-       } else {
-               tssi_sel = 0xe;
-               wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
-       }
+       wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
        mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
 
        mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2201,10 +2124,9 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
        mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
 
        if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
-               mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
+               mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
                mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
        } else {
-               mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
                mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
                mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
        }
@@ -2251,10 +2173,6 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
 
        mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
 
-       mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
-       mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
-       mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
-
        wlc_lcnphy_pwrctrl_rssiparams(pi);
 }
 
@@ -2873,8 +2791,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
                read_radio_reg(pi, RADIO_2064_REG007) & 1;
        u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
        u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
-       u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
-
        idleTssi = read_phy_reg(pi, 0x4ab);
        suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
                         MCTL_EN_MAC));
@@ -2892,12 +2808,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
        mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
        mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
        wlc_lcnphy_tssi_setup(pi);
-
-       mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
-       mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
-
-       wlc_lcnphy_set_bbmult(pi, 0x0);
-
        wlc_phy_do_dummy_tx(pi, true, OFF);
        idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
                    >> 0);
@@ -2919,7 +2829,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
 
        mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
 
-       wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
        wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
        wlc_lcnphy_set_tx_gain(pi, &old_gains);
        wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3133,11 +3042,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
                        wlc_lcnphy_write_table(pi, &tab);
                        tab.tbl_offset++;
                }
-               mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
-               mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
-               mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
-               mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
-               mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
 
                mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
 
@@ -3939,6 +3843,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
        target_gains.pad_gain = 21;
        target_gains.dac_gain = 0;
        wlc_lcnphy_set_tx_gain(pi, &target_gains);
+       wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
 
        if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
 
@@ -3949,7 +3854,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
                                        lcnphy_recal ? LCNPHY_CAL_RECAL :
                                        LCNPHY_CAL_FULL), false);
        } else {
-               wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
                wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
        }
 
@@ -4374,22 +4278,17 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
        if (CHSPEC_IS5G(pi->radio_chanspec))
                pa_gain = 0x70;
        else
-               pa_gain = 0x60;
+               pa_gain = 0x70;
 
        if (pi->sh->boardflags & BFL_FEM)
                pa_gain = 0x10;
-
        tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
        tab.tbl_width = 32;
        tab.tbl_len = 1;
        tab.tbl_ptr = &val;
 
        for (j = 0; j < 128; j++) {
-               if (pi->sh->boardflags & BFL_FEM)
-                       gm_gain = gain_table[j].gm;
-               else
-                       gm_gain = 15;
-
+               gm_gain = gain_table[j].gm;
                val = (((u32) pa_gain << 24) |
                       (gain_table[j].pad << 16) |
                       (gain_table[j].pga << 8) | gm_gain);
@@ -4600,10 +4499,7 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
 
        write_phy_reg(pi, 0x4ea, 0x4688);
 
-       if (pi->sh->boardflags & BFL_FEM)
-               mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
-       else
-               mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
+       mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
 
        mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
 
@@ -4614,13 +4510,6 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
        wlc_lcnphy_rcal(pi);
 
        wlc_lcnphy_rc_cal(pi);
-
-       if (!(pi->sh->boardflags & BFL_FEM)) {
-               write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
-               write_radio_reg(pi, RADIO_2064_REG033, 0x19);
-               write_radio_reg(pi, RADIO_2064_REG039, 0xe);
-       }
-
 }
 
 static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4650,20 +4539,22 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
                wlc_lcnphy_write_table(pi, &tab);
        }
 
-       if (!(pi->sh->boardflags & BFL_FEM)) {
-               tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
-               tab.tbl_width = 16;
-               tab.tbl_ptr = &val;
-               tab.tbl_len = 1;
+       tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+       tab.tbl_width = 16;
+       tab.tbl_ptr = &val;
+       tab.tbl_len = 1;
 
-               val = 150;
-               tab.tbl_offset = 0;
-               wlc_lcnphy_write_table(pi, &tab);
+       val = 114;
+       tab.tbl_offset = 0;
+       wlc_lcnphy_write_table(pi, &tab);
 
-               val = 220;
-               tab.tbl_offset = 1;
-               wlc_lcnphy_write_table(pi, &tab);
-       }
+       val = 130;
+       tab.tbl_offset = 1;
+       wlc_lcnphy_write_table(pi, &tab);
+
+       val = 6;
+       tab.tbl_offset = 8;
+       wlc_lcnphy_write_table(pi, &tab);
 
        if (CHSPEC_IS2G(pi->radio_chanspec)) {
                if (pi->sh->boardflags & BFL_FEM)
@@ -5055,7 +4946,6 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
                wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
 
        mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
-       wlc_lcnphy_tssi_setup(pi);
 }
 
 void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
@@ -5094,7 +4984,8 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
        if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
                return false;
 
-       if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+       if ((pi->sh->boardflags & BFL_FEM) &&
+           (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
                if (pi_lcn->lcnphy_tempsense_option == 3) {
                        pi->hwpwrctrl = true;
                        pi->hwpwrctrl_capable = true;
index b7e95ac..622c01c 100644 (file)
@@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
 };
 
 static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
-       0x0009,
        0x000a,
-       0x0005,
-       0x0006,
        0x0009,
-       0x000a,
-       0x0005,
        0x0006,
-       0x0009,
-       0x000a,
        0x0005,
-       0x0006,
-       0x0009,
        0x000a,
-       0x0005,
-       0x0006,
        0x0009,
-       0x000a,
-       0x0005,
        0x0006,
-       0x0009,
-       0x000a,
        0x0005,
-       0x0006,
-       0x0009,
        0x000a,
-       0x0005,
-       0x0006,
        0x0009,
-       0x000a,
-       0x0005,
        0x0006,
-       0x0009,
-       0x000a,
        0x0005,
-       0x0006,
-       0x0009,
        0x000a,
-       0x0005,
-       0x0006,
        0x0009,
-       0x000a,
-       0x0005,
        0x0006,
-       0x0009,
-       0x000a,
        0x0005,
-       0x0006,
+       0x000a,
        0x0009,
+       0x0006,
+       0x0005,
        0x000a,
+       0x0009,
+       0x0006,
        0x0005,
+       0x000a,
+       0x0009,
        0x0006,
+       0x0005,
+       0x000a,
        0x0009,
+       0x0006,
+       0x0005,
        0x000a,
+       0x0009,
+       0x0006,
        0x0005,
+       0x000a,
+       0x0009,
        0x0006,
+       0x0005,
+       0x000a,
        0x0009,
+       0x0006,
+       0x0005,
        0x000a,
+       0x0009,
+       0x0006,
        0x0005,
+       0x000a,
+       0x0009,
        0x0006,
+       0x0005,
+       0x000a,
        0x0009,
+       0x0006,
+       0x0005,
        0x000a,
+       0x0009,
+       0x0006,
        0x0005,
+       0x000a,
+       0x0009,
        0x0006,
+       0x0005,
 };
 
 static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
index e8324b5..6c7493c 100644 (file)
@@ -2152,7 +2152,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
        int rate_idx;
        int i;
        u32 rate;
-       u8 use_green = il4965_rs_use_green(il, sta);
+       u8 use_green;
        u8 active_tbl = 0;
        u8 valid_tx_ant;
        struct il_station_priv *sta_priv;
@@ -2160,6 +2160,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
        if (!sta || !lq_sta)
                return;
 
+       use_green = il4965_rs_use_green(il, sta);
        sta_priv = (void *)sta->drv_priv;
 
        i = lq_sta->last_txrate_idx;
index 86ea5f4..44ca0e5 100644 (file)
@@ -1262,6 +1262,15 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        }
 
        /*
+        * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag
+        * in iwl_down but cancel the workers only later.
+        */
+       if (!priv->ucode_loaded) {
+               IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id);
+               return -EIO;
+       }
+
+       /*
         * Synchronous commands from this op-mode must hold
         * the mutex, this ensures we don't try to send two
         * (or more) synchronous commands at a time.
index 736fe9b..1a4ac92 100644 (file)
@@ -367,6 +367,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
                return -EIO;
        }
 
+       priv->ucode_loaded = true;
+
        if (ucode_type != IWL_UCODE_WOWLAN) {
                /* delay a bit to give rfkill time to run */
                msleep(5);
@@ -380,8 +382,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
                return ret;
        }
 
-       priv->ucode_loaded = true;
-
        return 0;
 }
 
index 17bedc5..12c4f31 100644 (file)
@@ -475,6 +475,10 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
 
        /* If platform's RF_KILL switch is NOT set to KILL */
        hw_rfkill = iwl_is_rfkill_set(trans);
+       if (hw_rfkill)
+               set_bit(STATUS_RFKILL, &trans_pcie->status);
+       else
+               clear_bit(STATUS_RFKILL, &trans_pcie->status);
        iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
        if (hw_rfkill && !run_in_rfkill)
                return -ERFKILL;
@@ -641,6 +645,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
 
 static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        bool hw_rfkill;
        int err;
 
@@ -656,6 +661,10 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
        iwl_enable_rfkill_int(trans);
 
        hw_rfkill = iwl_is_rfkill_set(trans);
+       if (hw_rfkill)
+               set_bit(STATUS_RFKILL, &trans_pcie->status);
+       else
+               clear_bit(STATUS_RFKILL, &trans_pcie->status);
        iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
        return 0;
@@ -694,6 +703,10 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
                 * op_mode.
                 */
                hw_rfkill = iwl_is_rfkill_set(trans);
+               if (hw_rfkill)
+                       set_bit(STATUS_RFKILL, &trans_pcie->status);
+               else
+                       clear_bit(STATUS_RFKILL, &trans_pcie->status);
                iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
        }
 }
index 8595c16..cb5c679 100644 (file)
@@ -1264,7 +1264,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
        for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
                int copy = 0;
 
-               if (!cmd->len)
+               if (!cmd->len[i])
                        continue;
 
                /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
index 5c395e2..feb2046 100644 (file)
@@ -1508,6 +1508,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
                }
                memcpy(adapter->upld_buf, skb->data,
                       min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
+               skb_push(skb, INTF_HEADER_LEN);
                if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
                                           PCI_DMA_FROMDEVICE))
                        return -1;
index 5ac9c93..e9b9c83 100644 (file)
@@ -307,7 +307,7 @@ static void scm_blk_handle_error(struct scm_request *scmrq)
        case EQC_WR_PROHIBIT:
                spin_lock_irqsave(&bdev->lock, flags);
                if (bdev->state != SCM_WR_PROHIBIT)
-                       pr_info("%lu: Write access to the SCM increment is suspended\n",
+                       pr_info("%lx: Write access to the SCM increment is suspended\n",
                                (unsigned long) bdev->scmdev->address);
                bdev->state = SCM_WR_PROHIBIT;
                spin_unlock_irqrestore(&bdev->lock, flags);
@@ -445,7 +445,7 @@ void scm_blk_set_available(struct scm_blk_dev *bdev)
 
        spin_lock_irqsave(&bdev->lock, flags);
        if (bdev->state == SCM_WR_PROHIBIT)
-               pr_info("%lu: Write access to the SCM increment is restored\n",
+               pr_info("%lx: Write access to the SCM increment is restored\n",
                        (unsigned long) bdev->scmdev->address);
        bdev->state = SCM_OPER;
        spin_unlock_irqrestore(&bdev->lock, flags);
@@ -463,12 +463,15 @@ static int __init scm_blk_init(void)
                goto out;
 
        scm_major = ret;
-       if (scm_alloc_rqs(nr_requests))
+       ret = scm_alloc_rqs(nr_requests);
+       if (ret)
                goto out_unreg;
 
        scm_debug = debug_register("scm_log", 16, 1, 16);
-       if (!scm_debug)
+       if (!scm_debug) {
+               ret = -ENOMEM;
                goto out_free;
+       }
 
        debug_register_view(scm_debug, &debug_hex_ascii_view);
        debug_set_level(scm_debug, 2);
index 5f6180d..c98cf52 100644 (file)
@@ -19,7 +19,7 @@ static void scm_notify(struct scm_device *scmdev, enum scm_event event)
 
        switch (event) {
        case SCM_CHANGE:
-               pr_info("%lu: The capabilities of the SCM increment changed\n",
+               pr_info("%lx: The capabilities of the SCM increment changed\n",
                        (unsigned long) scmdev->address);
                SCM_LOG(2, "State changed");
                SCM_LOG_STATE(2, scmdev);
index b907dba..cee69da 100644 (file)
@@ -915,7 +915,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
        int i, rc;
 
        /* Check if the tty3270 is already there. */
-       view = raw3270_find_view(&tty3270_fn, tty->index);
+       view = raw3270_find_view(&tty3270_fn, tty->index + RAW3270_FIRSTMINOR);
        if (!IS_ERR(view)) {
                tp = container_of(view, struct tty3270, view);
                tty->driver_data = tp;
@@ -927,15 +927,16 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
                tp->inattr = TF_INPUT;
                return tty_port_install(&tp->port, driver, tty);
        }
-       if (tty3270_max_index < tty->index)
-               tty3270_max_index = tty->index;
+       if (tty3270_max_index < tty->index + 1)
+               tty3270_max_index = tty->index + 1;
 
        /* Allocate tty3270 structure on first open. */
        tp = tty3270_alloc_view();
        if (IS_ERR(tp))
                return PTR_ERR(tp);
 
-       rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
+       rc = raw3270_add_view(&tp->view, &tty3270_fn,
+                             tty->index + RAW3270_FIRSTMINOR);
        if (rc) {
                tty3270_free_view(tp);
                return rc;
@@ -1846,12 +1847,12 @@ static const struct tty_operations tty3270_ops = {
 
 void tty3270_create_cb(int minor)
 {
-       tty_register_device(tty3270_driver, minor, NULL);
+       tty_register_device(tty3270_driver, minor - RAW3270_FIRSTMINOR, NULL);
 }
 
 void tty3270_destroy_cb(int minor)
 {
-       tty_unregister_device(tty3270_driver, minor);
+       tty_unregister_device(tty3270_driver, minor - RAW3270_FIRSTMINOR);
 }
 
 struct raw3270_notifier tty3270_notifier =
@@ -1884,7 +1885,8 @@ static int __init tty3270_init(void)
        driver->driver_name = "tty3270";
        driver->name = "3270/tty";
        driver->major = IBM_TTY3270_MAJOR;
-       driver->minor_start = 0;
+       driver->minor_start = RAW3270_FIRSTMINOR;
+       driver->name_base = RAW3270_FIRSTMINOR;
        driver->type = TTY_DRIVER_TYPE_SYSTEM;
        driver->subtype = SYSTEM_TYPE_TTY;
        driver->init_termios = tty_std_termios;
index 2daf4b0..90bc7bd 100644 (file)
@@ -940,6 +940,7 @@ static int bnx2fc_libfc_config(struct fc_lport *lport)
        fc_exch_init(lport);
        fc_rport_init(lport);
        fc_disc_init(lport);
+       fc_disc_config(lport, lport);
        return 0;
 }
 
@@ -2133,6 +2134,7 @@ static int _bnx2fc_create(struct net_device *netdev,
        }
 
        ctlr = bnx2fc_to_ctlr(interface);
+       cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
        interface->vlan_id = vlan_id;
 
        interface->timer_work_queue =
@@ -2143,7 +2145,7 @@ static int _bnx2fc_create(struct net_device *netdev,
                goto ifput_err;
        }
 
-       lport = bnx2fc_if_create(interface, &interface->hba->pcidev->dev, 0);
+       lport = bnx2fc_if_create(interface, &cdev->dev, 0);
        if (!lport) {
                printk(KERN_ERR PFX "Failed to create interface (%s)\n",
                        netdev->name);
@@ -2159,8 +2161,6 @@ static int _bnx2fc_create(struct net_device *netdev,
        /* Make this master N_port */
        ctlr->lp = lport;
 
-       cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
-
        if (link_state == BNX2FC_CREATE_LINK_UP)
                cdev->enabled = FCOE_CTLR_ENABLED;
        else
index b5d92fc..9bfdc9a 100644 (file)
@@ -490,7 +490,6 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
 {
        struct net_device *netdev = fcoe->netdev;
        struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
-       struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
 
        rtnl_lock();
        if (!fcoe->removed)
@@ -501,7 +500,6 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
        /* tear-down the FCoE controller */
        fcoe_ctlr_destroy(fip);
        scsi_host_put(fip->lp->host);
-       fcoe_ctlr_device_delete(ctlr_dev);
        dev_put(netdev);
        module_put(THIS_MODULE);
 }
@@ -2194,6 +2192,8 @@ out_nodev:
  */
 static void fcoe_destroy_work(struct work_struct *work)
 {
+       struct fcoe_ctlr_device *cdev;
+       struct fcoe_ctlr *ctlr;
        struct fcoe_port *port;
        struct fcoe_interface *fcoe;
        struct Scsi_Host *shost;
@@ -2224,10 +2224,15 @@ static void fcoe_destroy_work(struct work_struct *work)
        mutex_lock(&fcoe_config_mutex);
 
        fcoe = port->priv;
+       ctlr = fcoe_to_ctlr(fcoe);
+       cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
+
        fcoe_if_destroy(port->lport);
        fcoe_interface_cleanup(fcoe);
 
        mutex_unlock(&fcoe_config_mutex);
+
+       fcoe_ctlr_device_delete(cdev);
 }
 
 /**
@@ -2335,7 +2340,9 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode,
                rc = -EIO;
                rtnl_unlock();
                fcoe_interface_cleanup(fcoe);
-               goto out_nortnl;
+               mutex_unlock(&fcoe_config_mutex);
+               fcoe_ctlr_device_delete(ctlr_dev);
+               goto out;
        }
 
        /* Make this the "master" N_Port */
@@ -2375,8 +2382,8 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode,
 
 out_nodev:
        rtnl_unlock();
-out_nortnl:
        mutex_unlock(&fcoe_config_mutex);
+out:
        return rc;
 }
 
index 08c3bc3..a762472 100644 (file)
@@ -2815,6 +2815,47 @@ unlock:
 }
 
 /**
+ * fcoe_ctlr_mode_set() - Set or reset the ctlr's mode
+ * @lport: The local port to be (re)configured
+ * @fip:   The FCoE controller whose mode is changing
+ * @fip_mode: The new fip mode
+ *
+ * Note that the we shouldn't be changing the libfc discovery settings
+ * (fc_disc_config) while an lport is going through the libfc state
+ * machine. The mode can only be changed when a fcoe_ctlr device is
+ * disabled, so that should ensure that this routine is only called
+ * when nothing is happening.
+ */
+void fcoe_ctlr_mode_set(struct fc_lport *lport, struct fcoe_ctlr *fip,
+                       enum fip_state fip_mode)
+{
+       void *priv;
+
+       WARN_ON(lport->state != LPORT_ST_RESET &&
+               lport->state != LPORT_ST_DISABLED);
+
+       if (fip_mode == FIP_MODE_VN2VN) {
+               lport->rport_priv_size = sizeof(struct fcoe_rport);
+               lport->point_to_multipoint = 1;
+               lport->tt.disc_recv_req = fcoe_ctlr_disc_recv;
+               lport->tt.disc_start = fcoe_ctlr_disc_start;
+               lport->tt.disc_stop = fcoe_ctlr_disc_stop;
+               lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final;
+               priv = fip;
+       } else {
+               lport->rport_priv_size = 0;
+               lport->point_to_multipoint = 0;
+               lport->tt.disc_recv_req = NULL;
+               lport->tt.disc_start = NULL;
+               lport->tt.disc_stop = NULL;
+               lport->tt.disc_stop_final = NULL;
+               priv = lport;
+       }
+
+       fc_disc_config(lport, priv);
+}
+
+/**
  * fcoe_libfc_config() - Sets up libfc related properties for local port
  * @lport:    The local port to configure libfc for
  * @fip:      The FCoE controller in use by the local port
@@ -2833,21 +2874,9 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip,
        fc_exch_init(lport);
        fc_elsct_init(lport);
        fc_lport_init(lport);
-       if (fip->mode == FIP_MODE_VN2VN)
-               lport->rport_priv_size = sizeof(struct fcoe_rport);
        fc_rport_init(lport);
-       if (fip->mode == FIP_MODE_VN2VN) {
-               lport->point_to_multipoint = 1;
-               lport->tt.disc_recv_req = fcoe_ctlr_disc_recv;
-               lport->tt.disc_start = fcoe_ctlr_disc_start;
-               lport->tt.disc_stop = fcoe_ctlr_disc_stop;
-               lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final;
-               mutex_init(&lport->disc.disc_mutex);
-               INIT_LIST_HEAD(&lport->disc.rports);
-               lport->disc.priv = fip;
-       } else {
-               fc_disc_init(lport);
-       }
+       fc_disc_init(lport);
+       fcoe_ctlr_mode_set(lport, fip, fip->mode);
        return 0;
 }
 EXPORT_SYMBOL_GPL(fcoe_libfc_config);
@@ -2875,6 +2904,7 @@ EXPORT_SYMBOL(fcoe_fcf_get_selected);
 void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
 {
        struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
+       struct fc_lport *lport = ctlr->lp;
 
        mutex_lock(&ctlr->ctlr_mutex);
        switch (ctlr_dev->mode) {
@@ -2888,5 +2918,7 @@ void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
        }
 
        mutex_unlock(&ctlr->ctlr_mutex);
+
+       fcoe_ctlr_mode_set(lport, ctlr, ctlr->mode);
 }
 EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode);
index 8e561e6..880a906 100644 (file)
@@ -712,12 +712,13 @@ static void fc_disc_stop_final(struct fc_lport *lport)
 }
 
 /**
- * fc_disc_init() - Initialize the discovery layer for a local port
- * @lport: The local port that needs the discovery layer to be initialized
+ * fc_disc_config() - Configure the discovery layer for a local port
+ * @lport: The local port that needs the discovery layer to be configured
+ * @priv: Private data structre for users of the discovery layer
  */
-int fc_disc_init(struct fc_lport *lport)
+void fc_disc_config(struct fc_lport *lport, void *priv)
 {
-       struct fc_disc *disc;
+       struct fc_disc *disc = &lport->disc;
 
        if (!lport->tt.disc_start)
                lport->tt.disc_start = fc_disc_start;
@@ -732,12 +733,21 @@ int fc_disc_init(struct fc_lport *lport)
                lport->tt.disc_recv_req = fc_disc_recv_req;
 
        disc = &lport->disc;
+
+       disc->priv = priv;
+}
+EXPORT_SYMBOL(fc_disc_config);
+
+/**
+ * fc_disc_init() - Initialize the discovery layer for a local port
+ * @lport: The local port that needs the discovery layer to be initialized
+ */
+void fc_disc_init(struct fc_lport *lport)
+{
+       struct fc_disc *disc = &lport->disc;
+
        INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout);
        mutex_init(&disc->disc_mutex);
        INIT_LIST_HEAD(&disc->rports);
-
-       disc->priv = lport;
-
-       return 0;
 }
 EXPORT_SYMBOL(fc_disc_init);
index f80eee7..2be0de9 100644 (file)
@@ -55,6 +55,7 @@ comment "SPI Master Controller Drivers"
 
 config SPI_ALTERA
        tristate "Altera SPI Controller"
+       depends on GENERIC_HARDIRQS
        select SPI_BITBANG
        help
          This is the driver for the Altera SPI Controller.
@@ -310,7 +311,7 @@ config SPI_PXA2XX_DMA
 
 config SPI_PXA2XX
        tristate "PXA2xx SSP SPI master"
-       depends on ARCH_PXA || PCI || ACPI
+       depends on (ARCH_PXA || PCI || ACPI) && GENERIC_HARDIRQS
        select PXA_SSP if ARCH_PXA
        help
          This enables using a PXA2xx or Sodaville SSP port as a SPI master
index 63203ac..0264704 100644 (file)
@@ -858,6 +858,7 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
        tmp = ((mode->xres & 7) << 24) | ((display_h_total & 7) << 16)
            | ((mode->hsync_len & 7) << 8) | (hsync_pos & 7);
        lcdc_write_chan(ch, LDHAJR, tmp);
+       lcdc_write_chan_mirror(ch, LDHAJR, tmp);
 }
 
 static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay *ovl)
index aea605c..aae187a 100644 (file)
@@ -551,6 +551,7 @@ struct block_device *bdgrab(struct block_device *bdev)
        ihold(bdev->bd_inode);
        return bdev;
 }
+EXPORT_SYMBOL(bdgrab);
 
 long nr_blockdev_pages(void)
 {
index 0116886..a272007 100644 (file)
@@ -264,7 +264,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                iattr->ia_valid |= ATTR_SIZE;
        }
        if (bmval[0] & FATTR4_WORD0_ACL) {
-               int nace;
+               u32 nace;
                struct nfs4_ace *ace;
 
                READ_BUF(4); len += 4;
index c196369..4cce1d9 100644 (file)
@@ -187,8 +187,8 @@ fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset,
        if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
                return -ENOSPC;
 
-       if (name[0] == '.' && (name[1] == '\0' ||
-                              (name[1] == '.' && name[2] == '\0')))
+       if (name[0] == '.' && (namelen < 2 ||
+                              (namelen == 2 && name[1] == '.')))
                return 0;
 
        dentry = lookup_one_len(name, dbuf->xadir, namelen);
index 76a87fb..377cd8c 100644 (file)
@@ -141,11 +141,11 @@ typedef struct {
 } compat_sigset_t;
 
 struct compat_sigaction {
-#ifndef __ARCH_HAS_ODD_SIGACTION
+#ifndef __ARCH_HAS_IRIX_SIGACTION
        compat_uptr_t                   sa_handler;
        compat_ulong_t                  sa_flags;
 #else
-       compat_ulong_t                  sa_flags;
+       compat_uint_t                   sa_flags;
        compat_uptr_t                   sa_handler;
 #endif
 #ifdef __ARCH_HAS_SA_RESTORER
index b3d00fa..8bfa956 100644 (file)
@@ -895,7 +895,7 @@ struct netdev_fcoe_hbainfo {
  *
  * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh)
  * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
- *                          struct net_device *dev)
+ *                          struct net_device *dev, u32 filter_mask)
  *
  * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier);
  *     Called to change device carrier. Soft-devices (like dummy, team, etc)
index a2dcb94..9475c5c 100644 (file)
@@ -250,11 +250,11 @@ extern int show_unhandled_signals;
 extern int sigsuspend(sigset_t *);
 
 struct sigaction {
-#ifndef __ARCH_HAS_ODD_SIGACTION
+#ifndef __ARCH_HAS_IRIX_SIGACTION
        __sighandler_t  sa_handler;
        unsigned long   sa_flags;
 #else
-       unsigned long   sa_flags;
+       unsigned int    sa_flags;
        __sighandler_t  sa_handler;
 #endif
 #ifdef __ARCH_HAS_SA_RESTORER
index 399162b..e1379b4 100644 (file)
@@ -1074,7 +1074,8 @@ void fc_rport_terminate_io(struct fc_rport *);
 /*
  * DISCOVERY LAYER
  *****************************/
-int fc_disc_init(struct fc_lport *);
+void fc_disc_init(struct fc_lport *);
+void fc_disc_config(struct fc_lport *, void *);
 
 static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc)
 {
index 31cd1bf..fede1d0 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -872,6 +872,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
                                                        goto out_unlock;
                                                break;
                                        }
+                                       msg = ERR_PTR(-EAGAIN);
                                } else
                                        break;
                                msg_counter++;
index b13e5c7..13e6447 100644 (file)
@@ -1624,7 +1624,6 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
        }
 
        skb_orphan(skb);
-       nf_reset(skb);
 
        if (unlikely(!is_skb_forwardable(dev, skb))) {
                atomic_long_inc(&dev->rx_dropped);
@@ -3314,6 +3313,7 @@ int netdev_rx_handler_register(struct net_device *dev,
        if (dev->rx_handler)
                return -EBUSY;
 
+       /* Note: rx_handler_data must be set before rx_handler */
        rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
        rcu_assign_pointer(dev->rx_handler, rx_handler);
 
@@ -3334,6 +3334,11 @@ void netdev_rx_handler_unregister(struct net_device *dev)
 
        ASSERT_RTNL();
        RCU_INIT_POINTER(dev->rx_handler, NULL);
+       /* a reader seeing a non NULL rx_handler in a rcu_read_lock()
+        * section has a guarantee to see a non NULL rx_handler_data
+        * as well.
+        */
+       synchronize_net();
        RCU_INIT_POINTER(dev->rx_handler_data, NULL);
 }
 EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
index c56ea6f..2bfd081 100644 (file)
@@ -328,7 +328,7 @@ static void flow_cache_flush_per_cpu(void *data)
        struct flow_flush_info *info = data;
        struct tasklet_struct *tasklet;
 
-       tasklet = this_cpu_ptr(&info->cache->percpu->flush_tasklet);
+       tasklet = &this_cpu_ptr(info->cache->percpu)->flush_tasklet;
        tasklet->data = (unsigned long)info;
        tasklet_schedule(tasklet);
 }
index 5fb8d7e..b65441d 100644 (file)
@@ -496,8 +496,10 @@ static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
        }
        if (ops->fill_info) {
                data = nla_nest_start(skb, IFLA_INFO_DATA);
-               if (data == NULL)
+               if (data == NULL) {
+                       err = -EMSGSIZE;
                        goto err_cancel_link;
+               }
                err = ops->fill_info(skb, dev);
                if (err < 0)
                        goto err_cancel_data;
index 2651225..a459c4f 100644 (file)
@@ -2529,6 +2529,9 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
 static void init_loopback(struct net_device *dev)
 {
        struct inet6_dev  *idev;
+       struct net_device *sp_dev;
+       struct inet6_ifaddr *sp_ifa;
+       struct rt6_info *sp_rt;
 
        /* ::1 */
 
@@ -2540,6 +2543,30 @@ static void init_loopback(struct net_device *dev)
        }
 
        add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
+
+       /* Add routes to other interface's IPv6 addresses */
+       for_each_netdev(dev_net(dev), sp_dev) {
+               if (!strcmp(sp_dev->name, dev->name))
+                       continue;
+
+               idev = __in6_dev_get(sp_dev);
+               if (!idev)
+                       continue;
+
+               read_lock_bh(&idev->lock);
+               list_for_each_entry(sp_ifa, &idev->addr_list, if_list) {
+
+                       if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE))
+                               continue;
+
+                       sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
+
+                       /* Failure cases are ignored */
+                       if (!IS_ERR(sp_rt))
+                               ip6_ins_rt(sp_rt);
+               }
+               read_unlock_bh(&idev->lock);
+       }
 }
 
 static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
index e33fe0a..2bab2aa 100644 (file)
@@ -118,6 +118,18 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
            ipv6_addr_loopback(&hdr->daddr))
                goto err;
 
+       /* RFC4291 Errata ID: 3480
+        * Interface-Local scope spans only a single interface on a
+        * node and is useful only for loopback transmission of
+        * multicast.  Packets with interface-local scope received
+        * from another node must be discarded.
+        */
+       if (!(skb->pkt_type == PACKET_LOOPBACK ||
+             dev->flags & IFF_LOOPBACK) &&
+           ipv6_addr_is_multicast(&hdr->daddr) &&
+           IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1)
+               goto err;
+
        /* RFC4291 2.7
         * Nodes must not originate a packet to a multicast address whose scope
         * field contains the reserved value 0; if such a packet is received, it
index 8555f33..5b1e5af 100644 (file)
@@ -2693,6 +2693,7 @@ static int key_notify_policy_flush(const struct km_event *c)
        hdr->sadb_msg_pid = c->portid;
        hdr->sadb_msg_version = PF_KEY_V2;
        hdr->sadb_msg_errno = (uint8_t) 0;
+       hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
        hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
        pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
        return 0;
index baaa860..3bfe261 100644 (file)
@@ -349,21 +349,19 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
 static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
-       int ret = 0;
+       int ret;
 
        if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))
                return 0;
 
-       mutex_lock(&local->iflist_mtx);
+       ASSERT_RTNL();
 
        if (local->monitor_sdata)
-               goto out_unlock;
+               return 0;
 
        sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
-       if (!sdata) {
-               ret = -ENOMEM;
-               goto out_unlock;
-       }
+       if (!sdata)
+               return -ENOMEM;
 
        /* set up data */
        sdata->local = local;
@@ -377,13 +375,13 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
        if (WARN_ON(ret)) {
                /* ok .. stupid driver, it asked for this! */
                kfree(sdata);
-               goto out_unlock;
+               return ret;
        }
 
        ret = ieee80211_check_queues(sdata);
        if (ret) {
                kfree(sdata);
-               goto out_unlock;
+               return ret;
        }
 
        ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
@@ -391,13 +389,14 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
        if (ret) {
                drv_remove_interface(local, sdata);
                kfree(sdata);
-               goto out_unlock;
+               return ret;
        }
 
+       mutex_lock(&local->iflist_mtx);
        rcu_assign_pointer(local->monitor_sdata, sdata);
- out_unlock:
        mutex_unlock(&local->iflist_mtx);
-       return ret;
+
+       return 0;
 }
 
 static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
@@ -407,14 +406,20 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
        if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))
                return;
 
+       ASSERT_RTNL();
+
        mutex_lock(&local->iflist_mtx);
 
        sdata = rcu_dereference_protected(local->monitor_sdata,
                                          lockdep_is_held(&local->iflist_mtx));
-       if (!sdata)
-               goto out_unlock;
+       if (!sdata) {
+               mutex_unlock(&local->iflist_mtx);
+               return;
+       }
 
        rcu_assign_pointer(local->monitor_sdata, NULL);
+       mutex_unlock(&local->iflist_mtx);
+
        synchronize_net();
 
        ieee80211_vif_release_channel(sdata);
@@ -422,8 +427,6 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
        drv_remove_interface(local, sdata);
 
        kfree(sdata);
- out_unlock:
-       mutex_unlock(&local->iflist_mtx);
 }
 
 /*
index 29ce2aa..4749b38 100644 (file)
@@ -1060,7 +1060,8 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
 
        rcu_read_lock();
        list_for_each_entry_rcu(sdata, &local->interfaces, list)
-               if (ieee80211_vif_is_mesh(&sdata->vif))
+               if (ieee80211_vif_is_mesh(&sdata->vif) &&
+                   ieee80211_sdata_running(sdata))
                        ieee80211_queue_work(&local->hw, &sdata->work);
        rcu_read_unlock();
 }
index 1415774..82cc303 100644 (file)
@@ -3608,8 +3608,10 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
 
        /* Restart STA timers */
        rcu_read_lock();
-       list_for_each_entry_rcu(sdata, &local->interfaces, list)
-               ieee80211_restart_sta_timer(sdata);
+       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+               if (ieee80211_sdata_running(sdata))
+                       ieee80211_restart_sta_timer(sdata);
+       }
        rcu_read_unlock();
 }
 
index bb73ed2..c6844ad 100644 (file)
@@ -2675,7 +2675,19 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
 
                memset(nskb->cb, 0, sizeof(nskb->cb));
 
-               ieee80211_tx_skb(rx->sdata, nskb);
+               if (rx->sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) {
+                       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(nskb);
+
+                       info->flags = IEEE80211_TX_CTL_TX_OFFCHAN |
+                                     IEEE80211_TX_INTFL_OFFCHAN_TX_OK |
+                                     IEEE80211_TX_CTL_NO_CCK_RATE;
+                       if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
+                               info->hw_queue =
+                                       local->hw.offchannel_tx_hw_queue;
+               }
+
+               __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7,
+                                           status->band);
        }
        dev_kfree_skb(rx->skb);
        return RX_QUEUED;
index a79ce82..238a0cc 100644 (file)
@@ -766,6 +766,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
        struct ieee80211_local *local;
        struct ieee80211_sub_if_data *sdata;
        int ret, i;
+       bool have_key = false;
 
        might_sleep();
 
@@ -793,12 +794,19 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
        list_del_rcu(&sta->list);
 
        mutex_lock(&local->key_mtx);
-       for (i = 0; i < NUM_DEFAULT_KEYS; i++)
+       for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
                __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
-       if (sta->ptk)
+               have_key = true;
+       }
+       if (sta->ptk) {
                __ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
+               have_key = true;
+       }
        mutex_unlock(&local->key_mtx);
 
+       if (!have_key)
+               synchronize_net();
+
        sta->dead = true;
 
        local->num_sta--;
index 13aa47a..1bc210f 100644 (file)
@@ -962,8 +962,11 @@ cbq_dequeue(struct Qdisc *sch)
                cbq_update(q);
                if ((incr -= incr2) < 0)
                        incr = 0;
+               q->now += incr;
+       } else {
+               if (now > q->now)
+                       q->now = now;
        }
-       q->now += incr;
        q->now_rt = now;
 
        for (;;) {
index 4e606fc..5578628 100644 (file)
@@ -195,7 +195,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                flow->deficit = q->quantum;
                flow->dropped = 0;
        }
-       if (++sch->q.qlen < sch->limit)
+       if (++sch->q.qlen <= sch->limit)
                return NET_XMIT_SUCCESS;
 
        q->drop_overlimit++;
index ffad481..eac7e0e 100644 (file)
@@ -904,7 +904,7 @@ void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate)
        u64 mult;
        int shift;
 
-       r->rate_bps = rate << 3;
+       r->rate_bps = (u64)rate << 3;
        r->shift = 0;
        r->mult = 1;
        /*
index ca511c4..d8079da 100644 (file)
@@ -207,7 +207,7 @@ static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr)
        struct vsock_sock *vsk;
 
        list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table)
-               if (vsock_addr_equals_addr_any(addr, &vsk->local_addr))
+               if (addr->svm_port == vsk->local_addr.svm_port)
                        return sk_vsock(vsk);
 
        return NULL;
@@ -220,8 +220,8 @@ static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src,
 
        list_for_each_entry(vsk, vsock_connected_sockets(src, dst),
                            connected_table) {
-               if (vsock_addr_equals_addr(src, &vsk->remote_addr)
-                   && vsock_addr_equals_addr(dst, &vsk->local_addr)) {
+               if (vsock_addr_equals_addr(src, &vsk->remote_addr) &&
+                   dst->svm_port == vsk->local_addr.svm_port) {
                        return sk_vsock(vsk);
                }
        }
index a70ace8..1f6508e 100644 (file)
@@ -464,19 +464,16 @@ static struct sock *vmci_transport_get_pending(
        struct vsock_sock *vlistener;
        struct vsock_sock *vpending;
        struct sock *pending;
+       struct sockaddr_vm src;
+
+       vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
 
        vlistener = vsock_sk(listener);
 
        list_for_each_entry(vpending, &vlistener->pending_links,
                            pending_links) {
-               struct sockaddr_vm src;
-               struct sockaddr_vm dst;
-
-               vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
-               vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port);
-
                if (vsock_addr_equals_addr(&src, &vpending->remote_addr) &&
-                   vsock_addr_equals_addr(&dst, &vpending->local_addr)) {
+                   pkt->dst_port == vpending->local_addr.svm_port) {
                        pending = sk_vsock(vpending);
                        sock_hold(pending);
                        goto found;
@@ -739,10 +736,15 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
         */
        bh_lock_sock(sk);
 
-       if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED)
-               vmci_trans(vsk)->notify_ops->handle_notify_pkt(
-                               sk, pkt, true, &dst, &src,
-                               &bh_process_pkt);
+       if (!sock_owned_by_user(sk)) {
+               /* The local context ID may be out of date, update it. */
+               vsk->local_addr.svm_cid = dst.svm_cid;
+
+               if (sk->sk_state == SS_CONNECTED)
+                       vmci_trans(vsk)->notify_ops->handle_notify_pkt(
+                                       sk, pkt, true, &dst, &src,
+                                       &bh_process_pkt);
+       }
 
        bh_unlock_sock(sk);
 
@@ -902,6 +904,9 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
 
        lock_sock(sk);
 
+       /* The local context ID may be out of date. */
+       vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context;
+
        switch (sk->sk_state) {
        case SS_LISTEN:
                vmci_transport_recv_listen(sk, pkt);
@@ -958,6 +963,10 @@ static int vmci_transport_recv_listen(struct sock *sk,
        pending = vmci_transport_get_pending(sk, pkt);
        if (pending) {
                lock_sock(pending);
+
+               /* The local context ID may be out of date. */
+               vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context;
+
                switch (pending->sk_state) {
                case SS_CONNECTING:
                        err = vmci_transport_recv_connecting_server(sk,
index b7df1ae..ec2611b 100644 (file)
@@ -64,16 +64,6 @@ bool vsock_addr_equals_addr(const struct sockaddr_vm *addr,
 }
 EXPORT_SYMBOL_GPL(vsock_addr_equals_addr);
 
-bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr,
-                               const struct sockaddr_vm *other)
-{
-       return (addr->svm_cid == VMADDR_CID_ANY ||
-               other->svm_cid == VMADDR_CID_ANY ||
-               addr->svm_cid == other->svm_cid) &&
-              addr->svm_port == other->svm_port;
-}
-EXPORT_SYMBOL_GPL(vsock_addr_equals_addr_any);
-
 int vsock_addr_cast(const struct sockaddr *addr,
                    size_t len, struct sockaddr_vm **out_addr)
 {
index cdfbcef..9ccd531 100644 (file)
@@ -24,8 +24,6 @@ bool vsock_addr_bound(const struct sockaddr_vm *addr);
 void vsock_addr_unbind(struct sockaddr_vm *addr);
 bool vsock_addr_equals_addr(const struct sockaddr_vm *addr,
                            const struct sockaddr_vm *other);
-bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr,
-                               const struct sockaddr_vm *other);
 int vsock_addr_cast(const struct sockaddr *addr, size_t len,
                    struct sockaddr_vm **out_addr);
 
index ea4155f..6ddf74f 100644 (file)
@@ -212,6 +212,39 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
        rdev_rfkill_poll(rdev);
 }
 
+void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
+                             struct wireless_dev *wdev)
+{
+       lockdep_assert_held(&rdev->devlist_mtx);
+       lockdep_assert_held(&rdev->sched_scan_mtx);
+
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE))
+               return;
+
+       if (!wdev->p2p_started)
+               return;
+
+       rdev_stop_p2p_device(rdev, wdev);
+       wdev->p2p_started = false;
+
+       rdev->opencount--;
+
+       if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
+               bool busy = work_busy(&rdev->scan_done_wk);
+
+               /*
+                * If the work isn't pending or running (in which case it would
+                * be waiting for the lock we hold) the driver didn't properly
+                * cancel the scan when the interface was removed. In this case
+                * warn and leak the scan request object to not crash later.
+                */
+               WARN_ON(!busy);
+
+               rdev->scan_req->aborted = true;
+               ___cfg80211_scan_done(rdev, !busy);
+       }
+}
+
 static int cfg80211_rfkill_set_block(void *data, bool blocked)
 {
        struct cfg80211_registered_device *rdev = data;
@@ -221,7 +254,8 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
                return 0;
 
        rtnl_lock();
-       mutex_lock(&rdev->devlist_mtx);
+
+       /* read-only iteration need not hold the devlist_mtx */
 
        list_for_each_entry(wdev, &rdev->wdev_list, list) {
                if (wdev->netdev) {
@@ -231,18 +265,18 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
                /* otherwise, check iftype */
                switch (wdev->iftype) {
                case NL80211_IFTYPE_P2P_DEVICE:
-                       if (!wdev->p2p_started)
-                               break;
-                       rdev_stop_p2p_device(rdev, wdev);
-                       wdev->p2p_started = false;
-                       rdev->opencount--;
+                       /* but this requires it */
+                       mutex_lock(&rdev->devlist_mtx);
+                       mutex_lock(&rdev->sched_scan_mtx);
+                       cfg80211_stop_p2p_device(rdev, wdev);
+                       mutex_unlock(&rdev->sched_scan_mtx);
+                       mutex_unlock(&rdev->devlist_mtx);
                        break;
                default:
                        break;
                }
        }
 
-       mutex_unlock(&rdev->devlist_mtx);
        rtnl_unlock();
 
        return 0;
@@ -745,17 +779,13 @@ static void wdev_cleanup_work(struct work_struct *work)
        wdev = container_of(work, struct wireless_dev, cleanup_work);
        rdev = wiphy_to_dev(wdev->wiphy);
 
-       cfg80211_lock_rdev(rdev);
+       mutex_lock(&rdev->sched_scan_mtx);
 
        if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
                rdev->scan_req->aborted = true;
                ___cfg80211_scan_done(rdev, true);
        }
 
-       cfg80211_unlock_rdev(rdev);
-
-       mutex_lock(&rdev->sched_scan_mtx);
-
        if (WARN_ON(rdev->sched_scan_req &&
                    rdev->sched_scan_req->dev == wdev->netdev)) {
                __cfg80211_stop_sched_scan(rdev, false);
@@ -781,21 +811,19 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
                return;
 
        mutex_lock(&rdev->devlist_mtx);
+       mutex_lock(&rdev->sched_scan_mtx);
        list_del_rcu(&wdev->list);
        rdev->devlist_generation++;
 
        switch (wdev->iftype) {
        case NL80211_IFTYPE_P2P_DEVICE:
-               if (!wdev->p2p_started)
-                       break;
-               rdev_stop_p2p_device(rdev, wdev);
-               wdev->p2p_started = false;
-               rdev->opencount--;
+               cfg80211_stop_p2p_device(rdev, wdev);
                break;
        default:
                WARN_ON_ONCE(1);
                break;
        }
+       mutex_unlock(&rdev->sched_scan_mtx);
        mutex_unlock(&rdev->devlist_mtx);
 }
 EXPORT_SYMBOL(cfg80211_unregister_wdev);
@@ -936,6 +964,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
                cfg80211_update_iface_num(rdev, wdev->iftype, 1);
                cfg80211_lock_rdev(rdev);
                mutex_lock(&rdev->devlist_mtx);
+               mutex_lock(&rdev->sched_scan_mtx);
                wdev_lock(wdev);
                switch (wdev->iftype) {
 #ifdef CONFIG_CFG80211_WEXT
@@ -967,6 +996,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
                        break;
                }
                wdev_unlock(wdev);
+               mutex_unlock(&rdev->sched_scan_mtx);
                rdev->opencount++;
                mutex_unlock(&rdev->devlist_mtx);
                cfg80211_unlock_rdev(rdev);
index 3aec0e4..5845c2b 100644 (file)
@@ -503,6 +503,9 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
 void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
                               enum nl80211_iftype iftype, int num);
 
+void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
+                             struct wireless_dev *wdev);
+
 #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
 
 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
index d44ab21..58e13a8 100644 (file)
@@ -4702,14 +4702,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->scan)
                return -EOPNOTSUPP;
 
-       if (rdev->scan_req)
-               return -EBUSY;
+       mutex_lock(&rdev->sched_scan_mtx);
+       if (rdev->scan_req) {
+               err = -EBUSY;
+               goto unlock;
+       }
 
        if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
                n_channels = validate_scan_freqs(
                                info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
-               if (!n_channels)
-                       return -EINVAL;
+               if (!n_channels) {
+                       err = -EINVAL;
+                       goto unlock;
+               }
        } else {
                enum ieee80211_band band;
                n_channels = 0;
@@ -4723,23 +4728,29 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
                        n_ssids++;
 
-       if (n_ssids > wiphy->max_scan_ssids)
-               return -EINVAL;
+       if (n_ssids > wiphy->max_scan_ssids) {
+               err = -EINVAL;
+               goto unlock;
+       }
 
        if (info->attrs[NL80211_ATTR_IE])
                ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
        else
                ie_len = 0;
 
-       if (ie_len > wiphy->max_scan_ie_len)
-               return -EINVAL;
+       if (ie_len > wiphy->max_scan_ie_len) {
+               err = -EINVAL;
+               goto unlock;
+       }
 
        request = kzalloc(sizeof(*request)
                        + sizeof(*request->ssids) * n_ssids
                        + sizeof(*request->channels) * n_channels
                        + ie_len, GFP_KERNEL);
-       if (!request)
-               return -ENOMEM;
+       if (!request) {
+               err = -ENOMEM;
+               goto unlock;
+       }
 
        if (n_ssids)
                request->ssids = (void *)&request->channels[n_channels];
@@ -4876,6 +4887,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                kfree(request);
        }
 
+ unlock:
+       mutex_unlock(&rdev->sched_scan_mtx);
        return err;
 }
 
@@ -7749,20 +7762,9 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->stop_p2p_device)
                return -EOPNOTSUPP;
 
-       if (!wdev->p2p_started)
-               return 0;
-
-       rdev_stop_p2p_device(rdev, wdev);
-       wdev->p2p_started = false;
-
-       mutex_lock(&rdev->devlist_mtx);
-       rdev->opencount--;
-       mutex_unlock(&rdev->devlist_mtx);
-
-       if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
-               rdev->scan_req->aborted = true;
-               ___cfg80211_scan_done(rdev, true);
-       }
+       mutex_lock(&rdev->sched_scan_mtx);
+       cfg80211_stop_p2p_device(rdev, wdev);
+       mutex_unlock(&rdev->sched_scan_mtx);
 
        return 0;
 }
@@ -8486,7 +8488,7 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
        struct nlattr *nest;
        int i;
 
-       ASSERT_RDEV_LOCK(rdev);
+       lockdep_assert_held(&rdev->sched_scan_mtx);
 
        if (WARN_ON(!req))
                return 0;
index 674aadc..fd99ea4 100644 (file)
@@ -169,7 +169,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
        union iwreq_data wrqu;
 #endif
 
-       ASSERT_RDEV_LOCK(rdev);
+       lockdep_assert_held(&rdev->sched_scan_mtx);
 
        request = rdev->scan_req;
 
@@ -230,9 +230,9 @@ void __cfg80211_scan_done(struct work_struct *wk)
        rdev = container_of(wk, struct cfg80211_registered_device,
                            scan_done_wk);
 
-       cfg80211_lock_rdev(rdev);
+       mutex_lock(&rdev->sched_scan_mtx);
        ___cfg80211_scan_done(rdev, false);
-       cfg80211_unlock_rdev(rdev);
+       mutex_unlock(&rdev->sched_scan_mtx);
 }
 
 void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
@@ -698,11 +698,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
        found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR);
 
        if (found) {
-               found->pub.beacon_interval = tmp->pub.beacon_interval;
-               found->pub.signal = tmp->pub.signal;
-               found->pub.capability = tmp->pub.capability;
-               found->ts = tmp->ts;
-
                /* Update IEs */
                if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
                        const struct cfg80211_bss_ies *old;
@@ -723,6 +718,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
 
                        if (found->pub.hidden_beacon_bss &&
                            !list_empty(&found->hidden_list)) {
+                               const struct cfg80211_bss_ies *f;
+
                                /*
                                 * The found BSS struct is one of the probe
                                 * response members of a group, but we're
@@ -732,6 +729,10 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
                                 * SSID to showing it, which is confusing so
                                 * drop this information.
                                 */
+
+                               f = rcu_access_pointer(tmp->pub.beacon_ies);
+                               kfree_rcu((struct cfg80211_bss_ies *)f,
+                                         rcu_head);
                                goto drop;
                        }
 
@@ -761,6 +762,11 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
                                kfree_rcu((struct cfg80211_bss_ies *)old,
                                          rcu_head);
                }
+
+               found->pub.beacon_interval = tmp->pub.beacon_interval;
+               found->pub.signal = tmp->pub.signal;
+               found->pub.capability = tmp->pub.capability;
+               found->ts = tmp->ts;
        } else {
                struct cfg80211_internal_bss *new;
                struct cfg80211_internal_bss *hidden;
@@ -1056,6 +1062,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
+       mutex_lock(&rdev->sched_scan_mtx);
        if (rdev->scan_req) {
                err = -EBUSY;
                goto out;
@@ -1162,6 +1169,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
                dev_hold(dev);
        }
  out:
+       mutex_unlock(&rdev->sched_scan_mtx);
        kfree(creq);
        cfg80211_unlock_rdev(rdev);
        return err;
index f432bd3..09d994d 100644 (file)
@@ -85,6 +85,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
        ASSERT_RTNL();
        ASSERT_RDEV_LOCK(rdev);
        ASSERT_WDEV_LOCK(wdev);
+       lockdep_assert_held(&rdev->sched_scan_mtx);
 
        if (rdev->scan_req)
                return -EBUSY;
@@ -320,11 +321,9 @@ void cfg80211_sme_scan_done(struct net_device *dev)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
-       mutex_lock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
        wdev_lock(wdev);
        __cfg80211_sme_scan_done(dev);
        wdev_unlock(wdev);
-       mutex_unlock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
 }
 
 void cfg80211_sme_rx_auth(struct net_device *dev,
@@ -924,9 +923,12 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
        int err;
 
        mutex_lock(&rdev->devlist_mtx);
+       /* might request scan - scan_mtx -> wdev_mtx dependency */
+       mutex_lock(&rdev->sched_scan_mtx);
        wdev_lock(dev->ieee80211_ptr);
        err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
        wdev_unlock(dev->ieee80211_ptr);
+       mutex_unlock(&rdev->sched_scan_mtx);
        mutex_unlock(&rdev->devlist_mtx);
 
        return err;
index b7a5313..7586de7 100644 (file)
@@ -27,7 +27,8 @@
 #define WIPHY_PR_ARG   __entry->wiphy_name
 
 #define WDEV_ENTRY     __field(u32, id)
-#define WDEV_ASSIGN    (__entry->id) = (wdev ? wdev->identifier : 0)
+#define WDEV_ASSIGN    (__entry->id) = (!IS_ERR_OR_NULL(wdev)  \
+                                        ? wdev->identifier : 0)
 #define WDEV_PR_FMT    "wdev(%u)"
 #define WDEV_PR_ARG    (__entry->id)
 
@@ -1778,7 +1779,7 @@ TRACE_EVENT(rdev_set_mac_acl,
        ),
        TP_fast_assign(
                WIPHY_ASSIGN;
-               WIPHY_ASSIGN;
+               NETDEV_ASSIGN;
                __entry->acl_policy = params->acl_policy;
        ),
        TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", acl policy: %d",
index fb9622f..e79cb5c 100644 (file)
@@ -89,6 +89,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
 
        cfg80211_lock_rdev(rdev);
        mutex_lock(&rdev->devlist_mtx);
+       mutex_lock(&rdev->sched_scan_mtx);
        wdev_lock(wdev);
 
        if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -135,6 +136,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
        err = cfg80211_mgd_wext_connect(rdev, wdev);
  out:
        wdev_unlock(wdev);
+       mutex_unlock(&rdev->sched_scan_mtx);
        mutex_unlock(&rdev->devlist_mtx);
        cfg80211_unlock_rdev(rdev);
        return err;
@@ -190,6 +192,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
 
        cfg80211_lock_rdev(rdev);
        mutex_lock(&rdev->devlist_mtx);
+       mutex_lock(&rdev->sched_scan_mtx);
        wdev_lock(wdev);
 
        err = 0;
@@ -223,6 +226,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
        err = cfg80211_mgd_wext_connect(rdev, wdev);
  out:
        wdev_unlock(wdev);
+       mutex_unlock(&rdev->sched_scan_mtx);
        mutex_unlock(&rdev->devlist_mtx);
        cfg80211_unlock_rdev(rdev);
        return err;
@@ -285,6 +289,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
 
        cfg80211_lock_rdev(rdev);
        mutex_lock(&rdev->devlist_mtx);
+       mutex_lock(&rdev->sched_scan_mtx);
        wdev_lock(wdev);
 
        if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -313,6 +318,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
        err = cfg80211_mgd_wext_connect(rdev, wdev);
  out:
        wdev_unlock(wdev);
+       mutex_unlock(&rdev->sched_scan_mtx);
        mutex_unlock(&rdev->devlist_mtx);
        cfg80211_unlock_rdev(rdev);
        return err;
index 35754cc..8dafe6d 100644 (file)
@@ -334,6 +334,70 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
                x->xflags &= ~XFRM_TIME_DEFER;
 }
 
+static void xfrm_replay_notify_esn(struct xfrm_state *x, int event)
+{
+       u32 seq_diff, oseq_diff;
+       struct km_event c;
+       struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
+       struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn;
+
+       /* we send notify messages in case
+        *  1. we updated on of the sequence numbers, and the seqno difference
+        *     is at least x->replay_maxdiff, in this case we also update the
+        *     timeout of our timer function
+        *  2. if x->replay_maxage has elapsed since last update,
+        *     and there were changes
+        *
+        *  The state structure must be locked!
+        */
+
+       switch (event) {
+       case XFRM_REPLAY_UPDATE:
+               if (!x->replay_maxdiff)
+                       break;
+
+               if (replay_esn->seq_hi == preplay_esn->seq_hi)
+                       seq_diff = replay_esn->seq - preplay_esn->seq;
+               else
+                       seq_diff = ~preplay_esn->seq + replay_esn->seq + 1;
+
+               if (replay_esn->oseq_hi == preplay_esn->oseq_hi)
+                       oseq_diff = replay_esn->oseq - preplay_esn->oseq;
+               else
+                       oseq_diff = ~preplay_esn->oseq + replay_esn->oseq + 1;
+
+               if (seq_diff < x->replay_maxdiff &&
+                   oseq_diff < x->replay_maxdiff) {
+
+                       if (x->xflags & XFRM_TIME_DEFER)
+                               event = XFRM_REPLAY_TIMEOUT;
+                       else
+                               return;
+               }
+
+               break;
+
+       case XFRM_REPLAY_TIMEOUT:
+               if (memcmp(x->replay_esn, x->preplay_esn,
+                          xfrm_replay_state_esn_len(replay_esn)) == 0) {
+                       x->xflags |= XFRM_TIME_DEFER;
+                       return;
+               }
+
+               break;
+       }
+
+       memcpy(x->preplay_esn, x->replay_esn,
+              xfrm_replay_state_esn_len(replay_esn));
+       c.event = XFRM_MSG_NEWAE;
+       c.data.aevent = event;
+       km_state_notify(x, &c);
+
+       if (x->replay_maxage &&
+           !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
+               x->xflags &= ~XFRM_TIME_DEFER;
+}
+
 static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err = 0;
@@ -510,7 +574,7 @@ static struct xfrm_replay xfrm_replay_esn = {
        .advance        = xfrm_replay_advance_esn,
        .check          = xfrm_replay_check_esn,
        .recheck        = xfrm_replay_recheck_esn,
-       .notify         = xfrm_replay_notify_bmp,
+       .notify         = xfrm_replay_notify_esn,
        .overflow       = xfrm_replay_overflow_esn,
 };