diff options
289 files changed, 4814 insertions, 2958 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 4d3aa519ead..c1d1fd0c299 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -172,6 +172,16 @@ Who: Len Brown <len.brown@intel.com> --------------------------- +What: ide-tape driver +When: July 2008 +Files: drivers/ide/ide-tape.c +Why: This driver might not have any users anymore and maintaining it for no + reason is an effort no one wants to make. +Who: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>, Borislav Petkov + <petkovbb@googlemail.com> + +--------------------------- + What: libata spindown skipping and warning When: Dec 2008 Why: Some halt(8) implementations synchronize caches for and spin @@ -306,3 +316,15 @@ Why: Largely unmaintained and almost entirely unused. File system is largely pointless as without a lot of work only the most trivial of Solaris binaries can work with the emulation code. Who: David S. Miller <davem@davemloft.net> + +--------------------------- + +What: init_mm export +When: 2.6.26 +Why: Not used in-tree. The current out-of-tree users used it to + work around problems in the CPA code which should be resolved + by now. One usecase was described to provide verification code + of the CPA operation. That's a good idea in general, but such + code / infrastructure should be in the kernel and not in some + out-of-tree driver. +Who: Thomas Gleixner <tglx@linutronix.de> diff --git a/Documentation/ide.txt b/Documentation/ide.txt index 94e2e3b9e77..bcd7cd1278e 100644 --- a/Documentation/ide.txt +++ b/Documentation/ide.txt @@ -258,8 +258,6 @@ Summary of ide driver parameters for kernel command line As for VLB, it is safest to not specify it. Bigger values are safer than smaller ones. - "idex=noprobe" : do not attempt to access/use this interface - "idex=base" : probe for an interface at the addr specified, where "base" is usually 0x1f0 or 0x170 and "ctl" is assumed to be "base"+0x206 @@ -309,53 +307,6 @@ are detected automatically). ================================================================================ -IDE ATAPI streaming tape driver -------------------------------- - -This driver is a part of the Linux ide driver and works in co-operation -with linux/drivers/block/ide.c. - -The driver, in co-operation with ide.c, basically traverses the -request-list for the block device interface. The character device -interface, on the other hand, creates new requests, adds them -to the request-list of the block device, and waits for their completion. - -Pipelined operation mode is now supported on both reads and writes. - -The block device major and minor numbers are determined from the -tape's relative position in the ide interfaces, as explained in ide.c. - -The character device interface consists of the following devices: - - ht0 major 37, minor 0 first IDE tape, rewind on close. - ht1 major 37, minor 1 second IDE tape, rewind on close. - ... - nht0 major 37, minor 128 first IDE tape, no rewind on close. - nht1 major 37, minor 129 second IDE tape, no rewind on close. - ... - -Run /dev/MAKEDEV to create the above entries. - -The general magnetic tape commands compatible interface, as defined by -include/linux/mtio.h, is accessible through the character device. - -General ide driver configuration options, such as the interrupt-unmask -flag, can be configured by issuing an ioctl to the block device interface, -as any other ide device. - -Our own ide-tape ioctl's can be issued to either the block device or -the character device interface. - -Maximal throughput with minimal bus load will usually be achieved in the -following scenario: - - 1. ide-tape is operating in the pipelined operation mode. - 2. No buffering is performed by the user backup program. - - - -================================================================================ - Some Terminology ---------------- IDE = Integrated Drive Electronics, meaning that each drive has a built-in diff --git a/MAINTAINERS b/MAINTAINERS index 36c7bc641db..fed09b54733 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -767,14 +767,14 @@ S: Maintained BLACKFIN ARCHITECTURE P: Bryan Wu -M: bryan.wu@analog.com +M: cooloney@kernel.org L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported BLACKFIN EMAC DRIVER P: Bryan Wu -M: bryan.wu@analog.com +M: cooloney@kernel.org L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported @@ -982,6 +982,12 @@ M: mchan@broadcom.com L: netdev@vger.kernel.org S: Supported +BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER +P: Eliezer Tamir +M: eliezert@broadcom.com +L: netdev@vger.kernel.org +S: Supported + BROADCOM TG3 GIGABIT ETHERNET DRIVER P: Michael Chan M: mchan@broadcom.com @@ -2744,6 +2750,8 @@ S: Maintained NETEFFECT IWARP RNIC DRIVER (IW_NES) P: Faisal Latif M: flatif@neteffect.com +P: Nishi Gupta +M: ngupta@neteffect.com P: Glenn Streiff M: gstreiff@neteffect.com L: general@lists.openfabrics.org @@ -3884,10 +3892,13 @@ M: trivial@kernel.org L: linux-kernel@vger.kernel.org S: Maintained -TULIP NETWORK DRIVER -L: tulip-users@lists.sourceforge.net -W: http://sourceforge.net/projects/tulip/ -S: Orphan +TULIP NETWORK DRIVERS +P: Grant Grundler +M: grundler@parisc-linux.org +P: Kyle McMartin +M: kyle@parisc-linux.org +L: netdev@vger.kernel.org +S: Maintained TUN/TAP driver P: Maxim Krasnyansky diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9619c43783f..16b82e1272b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -939,7 +939,8 @@ config KEXEC config ATAGS_PROC bool "Export atags in procfs" - default n + depends on KEXEC + default y help Should the atags used to boot the kernel be exported in an "atags" file in procfs. Useful with kexec. diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c index 939a3867f77..4b21479332a 100644 --- a/arch/arm/mach-pxa/cpu-pxa.c +++ b/arch/arm/mach-pxa/cpu-pxa.c @@ -43,7 +43,7 @@ #ifdef DEBUG static unsigned int freq_debug; -MODULE_PARM(freq_debug, "i"); +module_param(freq_debug, uint, 0); MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); #else #define freq_debug 0 diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 7cd9ef8deb0..35f25fdaeba 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -129,28 +129,20 @@ static void clk_pxa3xx_cken_enable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); - local_irq_disable(); - if (clk->cken < 32) CKENA |= mask; else CKENB |= mask; - - local_irq_enable(); } static void clk_pxa3xx_cken_disable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); - local_irq_disable(); - if (clk->cken < 32) CKENA &= ~mask; else CKENB &= ~mask; - - local_irq_enable(); } static const struct clkops clk_pxa3xx_cken_ops = { diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 7731d50dd86..afd2cbfca0d 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -58,7 +58,7 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES) +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) static void zylonite_backlight_power(int on) { gpio_set_value(gpio_backlight, on); diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 2728b0e7d2b..3f6dc40b835 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -120,6 +120,8 @@ full_search: */ int valid_phys_addr_range(unsigned long addr, size_t size) { + if (addr < PHYS_OFFSET) + return 0; if (addr + size > __pa(high_memory)) return 0; diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 500c9610ab3..e0f19ab9116 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -75,7 +75,7 @@ no_pgd: void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) { pmd_t *pmd; - struct page *pte; + pgtable_t pte; if (!pgd) return; @@ -90,10 +90,8 @@ void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) goto free; } - pte = pmd_page(*pmd); + pte = pmd_pgtable(*pmd); pmd_clear(pmd); - dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); - pte_lock_deinit(pte); pte_free(mm, pte); pmd_free(mm, pmd); free: diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c index 5a77030e07a..e765a8652b3 100644 --- a/arch/avr32/boards/atstk1000/atstk1004.c +++ b/arch/avr32/boards/atstk1000/atstk1004.c @@ -129,7 +129,7 @@ static int __init atstk1004_init(void) #ifdef CONFIG_BOARD_ATSTK100X_SPI1 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif -#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM +#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM at32_add_device_mci(0); #endif at32_add_device_lcdc(0, &atstk1000_lcdc_data, diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index eaaa69bbdc3..7f4af0b1e11 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -11,6 +11,7 @@ #include <linux/fs.h> #include <linux/ptrace.h> #include <linux/reboot.h> +#include <linux/tick.h> #include <linux/uaccess.h> #include <linux/unistd.h> @@ -30,8 +31,10 @@ void cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { + tick_nohz_stop_sched_tick(); while (!need_resched()) cpu_idle_sleep(); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); @@ -345,6 +348,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, p->thread.cpu_context.ksp = (unsigned long)childregs; p->thread.cpu_context.pc = (unsigned long)ret_from_fork; + clear_tsk_thread_flag(p, TIF_DEBUG); if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) ocd_enable(p); diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index 6560cb18b4e..ce4e4296b95 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -189,6 +189,8 @@ no_context: page = sysreg_read(PTBR); printk(KERN_ALERT "ptbr = %08lx", page); + if (address >= TASK_SIZE) + page = (unsigned long)swapper_pg_dir; if (page) { page = ((unsigned long *)page)[address >> 22]; printk(" pgd = %08lx", page); diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index fe254f886a6..75eba2ca788 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -98,8 +98,11 @@ drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ # them changed. We use .mach to indicate when they were updated # last, otherwise make uses the target directory mtime. + show_mach_symlink = : + quiet_show_mach_symlink = echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' +silent_show_mach_symlink = : include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf - @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' + @$($(quiet)show_mach_symlink) ifneq ($(KBUILD_SRC),) $(Q)mkdir -p include/asm-$(ARCH) $(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index d59ee1530bd..ae320dcfede 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -1,7 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.14 -# Thu Nov 29 17:32:47 2007 +# Linux kernel version: 2.6.22.16 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -116,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y # Processor and Board Settings # # CONFIG_BF522 is not set +# CONFIG_BF523 is not set +# CONFIG_BF524 is not set # CONFIG_BF525 is not set +# CONFIG_BF526 is not set CONFIG_BF527=y # CONFIG_BF531 is not set # CONFIG_BF532 is not set @@ -306,6 +308,7 @@ CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_WB is not set CONFIG_BFIN_WT=y CONFIG_L1_MAX_PIECE=16 +# CONFIG_MPU is not set # # Asynchonous Memory Configuration @@ -354,6 +357,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # Networking @@ -496,7 +500,6 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_INTELEXT is not set # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_MW320D=m CONFIG_MTD_RAM=y CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set @@ -506,9 +509,6 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_BF5xx=m -CONFIG_BFIN_FLASH_SIZE=0x400000 -CONFIG_EBIU_FLASH_BASE=0x20000000 # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -684,7 +684,6 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_UINPUT is not set -# CONFIG_BF53X_PFBUTTONS is not set # CONFIG_TWI_KEYPAD is not set # @@ -702,12 +701,12 @@ CONFIG_INPUT_MISC=y # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set # CONFIG_AD5304 is not set -# CONFIG_BF5xx_TEA5764 is not set -# CONFIG_BF5xx_FBDMA is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -772,7 +771,6 @@ CONFIG_I2C_CHARDEV=m # # I2C Hardware Bus support # -# CONFIG_I2C_BLACKFIN_GPIO is not set CONFIG_I2C_BLACKFIN_TWI=m CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_GPIO is not set diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 811711f59a2..9621caa60b5 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -322,10 +322,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x80 # # CPU Frequency scaling @@ -697,7 +696,6 @@ CONFIG_SERIAL_BFIN_DMA=y # CONFIG_SERIAL_BFIN_PIO is not set CONFIG_SERIAL_BFIN_UART0=y # CONFIG_BFIN_UART0_CTSRTS is not set -# CONFIG_SERIAL_BFIN_UART1 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index 198f4123af4..b51e76ce7f4 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -323,10 +323,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x80 # # CPU Frequency scaling @@ -714,7 +713,6 @@ CONFIG_SERIAL_BFIN_DMA=y # CONFIG_SERIAL_BFIN_PIO is not set CONFIG_SERIAL_BFIN_UART0=y # CONFIG_BFIN_UART0_CTSRTS is not set -# CONFIG_SERIAL_BFIN_UART1 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index b37ccc681e7..d45fa535dad 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig @@ -330,10 +330,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x8 # # CPU Frequency scaling @@ -1013,6 +1012,7 @@ CONFIG_SND_BFIN_AD73311_SE=4 CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC=m CONFIG_SND_BF5XX_SOC=m +CONFIG_SND_MMAP_SUPPORT=y CONFIG_SND_BF5XX_SOC_AC97=m # CONFIG_SND_BF5XX_SOC_WM8750 is not set # CONFIG_SND_BF5XX_SOC_WM8731 is not set diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index fd702161ef5..c9707f7665a 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -396,6 +396,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # CPU Frequency scaling @@ -1075,6 +1076,7 @@ CONFIG_SND_VERBOSE_PROCFS=y CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC=y CONFIG_SND_BF5XX_SOC=y +CONFIG_SND_MMAP_SUPPORT=y CONFIG_SND_BF5XX_SOC_AC97=y CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y # CONFIG_SND_BF5XX_SOC_WM8750 is not set diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index 8546994939f..4d8a6333130 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -367,6 +367,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # Networking diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 5453bc3664f..8fd5d22cec3 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -105,13 +105,14 @@ int request_dma(unsigned int channel, char *device_id) mutex_unlock(&(dma_ch[channel].dmalock)); #ifdef CONFIG_BF54x - if (channel >= CH_UART2_RX && channel <= CH_UART3_TX && - strncmp(device_id, "BFIN_UART", 9) == 0) - dma_ch[channel].regs->peripheral_map |= - (channel - CH_UART2_RX + 0xC); - else - dma_ch[channel].regs->peripheral_map |= - (channel - CH_UART2_RX + 0x6); + if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { + if (strncmp(device_id, "BFIN_UART", 9) == 0) + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0xC); + else + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0x6); + } #endif dma_ch[channel].device_id = device_id; diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index 5cf4bdb1df3..1904d8b5332 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c @@ -1,9 +1,9 @@ /* - * bfin_gptimers.c - derived from bf53x_timers.c - * Driver for General Purpose Timer functions on the Blackfin processor + * gptimers.c - Blackfin General Purpose Timer core API * - * Copyright (C) 2005 John DeHority - * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) + * Copyright (c) 2005-2008 Analog Devices Inc. + * Copyright (C) 2005 John DeHority + * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) * * Licensed under the GPLv2. */ diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8229b1090eb..2255c289a71 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -32,6 +32,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); u16 _bfin_swrst; +EXPORT_SYMBOL(_bfin_swrst); unsigned long memory_start, memory_end, physical_mem_end; unsigned long reserved_mem_dcache_on; @@ -514,6 +515,7 @@ static __init void memory_setup(void) printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); printk(KERN_INFO "Memory map:\n" + KERN_INFO " fixedcode = 0x%p-0x%p\n" KERN_INFO " text = 0x%p-0x%p\n" KERN_INFO " rodata = 0x%p-0x%p\n" KERN_INFO " bss = 0x%p-0x%p\n" @@ -527,7 +529,8 @@ static __init void memory_setup(void) #if DMA_UNCACHED_REGION > 0 KERN_INFO " DMA Zone = 0x%p-0x%p\n" #endif - , _stext, _etext, + , (void *)FIXED_CODE_START, (void *)FIXED_CODE_END, + _stext, _etext, __start_rodata, __end_rodata, __bss_start, __bss_stop, _sdata, _edata, diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index aed832540b3..cb01a9de268 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -147,44 +147,64 @@ SECTIONS __l1_lma_start = .; +#if L1_CODE_LENGTH +# define LDS_L1_CODE *(.l1.text) +#else +# define LDS_L1_CODE +#endif .text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs)) { . = ALIGN(4); __stext_l1 = .; - *(.l1.text) - + LDS_L1_CODE . = ALIGN(4); __etext_l1 = .; } +#if L1_DATA_A_LENGTH +# define LDS_L1_A_DATA *(.l1.data) +# define LDS_L1_A_BSS *(.l1.bss) +# define LDS_L1_A_CACHE *(.data_l1.cacheline_aligned) +#else +# define LDS_L1_A_DATA +# define LDS_L1_A_BSS +# define LDS_L1_A_CACHE +#endif .data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1)) { . = ALIGN(4); __sdata_l1 = .; - *(.l1.data) + LDS_L1_A_DATA __edata_l1 = .; . = ALIGN(4); __sbss_l1 = .; - *(.l1.bss) + LDS_L1_A_BSS . = ALIGN(32); - *(.data_l1.cacheline_aligned) + LDS_L1_A_CACHE . = ALIGN(4); __ebss_l1 = .; } +#if L1_DATA_B_LENGTH +# define LDS_L1_B_DATA *(.l1.data.B) +# define LDS_L1_B_BSS *(.l1.bss.B) +#else +# define LDS_L1_B_DATA +# define LDS_L1_B_BSS +#endif .data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1)) { . = ALIGN(4); __sdata_b_l1 = .; - *(.l1.data.B) + LDS_L1_B_DATA __edata_b_l1 = .; . = ALIGN(4); __sbss_b_l1 = .; - *(.l1.bss.B) + LDS_L1_B_BSS . = ALIGN(4); __ebss_b_l1 = .; diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 337515fba61..cf4bc0d8335 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -180,8 +180,8 @@ static struct mtd_partition partition_info[] = { }, { .name = "File System", - .offset = 4 * SIZE_1M, - .size = (256 - 4) * SIZE_1M, + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, }, }; @@ -422,11 +422,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -484,13 +484,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -611,17 +604,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -818,6 +800,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) &bf5xx_nand_device, @@ -895,6 +890,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, }; static int __init stamp_init(void) @@ -921,13 +918,18 @@ void native_machine_restart(char *cmd) bfin_gpio_reset_spi0_ssel1(); } -/* - * Currently the MAC address is saved in Flash by U-Boot - */ -#define FLASH_MAC 0x203f0000 void bfin_get_ether_addr(char *addr) { - *(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC); - *(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4); + /* the MAC is stored in OTP memory page 0xDF */ + u32 ret; + u64 otp_mac; + u32 (*otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)0xEF00001A; + + ret = otp_read(0xDF, 0x00, &otp_mac); + if (!(ret & 0x1)) { + char *otp_mac_p = (char *)&otp_mac; + for (ret = 0; ret < 6; ++ret) + addr[ret] = otp_mac_p[5 - ret]; + } } EXPORT_SYMBOL(bfin_get_ether_addr); diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 2b09aa39f56..241b5a20a36 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -99,11 +99,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -298,6 +298,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include <linux/i2c-gpio.h> @@ -350,6 +363,8 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) &i2c_gpio_device, #endif + + &bfin_gpios_device, }; static int __init ezkit_init(void) diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index a645f6fd091..b2ac4816ae6 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -112,7 +112,7 @@ static struct platform_device net2272_bfin_device = { static struct mtd_partition stamp_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -160,17 +160,17 @@ static struct platform_device stamp_flash_device = { static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader", - .size = 0x00020000, + .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -212,13 +212,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) static struct bfin5xx_spi_chip spi_mmc_chip_info = { .enable_dma = 1, @@ -308,17 +301,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", @@ -457,6 +439,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include <linux/i2c-gpio.h> @@ -518,6 +513,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) &i2c_gpio_device, #endif + + &bfin_gpios_device, &stamp_flash_device, }; diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c index 8a3397db1d2..c95395ba7bf 100644 --- a/arch/blackfin/mach-bf537/boards/generic_board.c +++ b/arch/blackfin/mach-bf537/boards/generic_board.c @@ -371,13 +371,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -483,17 +476,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 9e2277e0d25..ea83148993d 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -128,6 +128,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) static struct resource bfin_pcmcia_cf_resources[] = { { @@ -343,7 +356,7 @@ static struct platform_device net2272_bfin_device = { static struct mtd_partition stamp_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -351,7 +364,7 @@ static struct mtd_partition stamp_partitions[] = { .offset = MTDPART_OFS_APPEND, }, { .name = "RootFS", - .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000, + .size = 0x400000 - 0x40000 - 0xE0000 - 0x10000, .offset = MTDPART_OFS_APPEND, }, { .name = "MAC Address", @@ -391,17 +404,17 @@ static struct platform_device stamp_flash_device = { static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader", - .size = 0x00020000, + .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -459,13 +472,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -578,17 +584,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -821,6 +816,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, &stamp_flash_device, }; diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 916e963e83b..a0950c1fd80 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -285,8 +285,8 @@ static struct mtd_partition partition_info[] = { }, { .name = "File System", - .offset = 4 * SIZE_1M, - .size = (256 - 4) * SIZE_1M, + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, }, }; @@ -333,7 +333,7 @@ static struct platform_device bf54x_sdh_device = { static struct mtd_partition ezkit_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -381,8 +381,8 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { .mask_flags = MTD_CAP_ROM }, { .name = "linux kernel", - .size = 0x1c0000, - .offset = 0x40000 + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -594,6 +594,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, @@ -646,6 +659,8 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, &ezkit_flash_device, }; diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c index 374803a8d2e..f5479298bb7 100644 --- a/arch/blackfin/mach-bf548/dma.c +++ b/arch/blackfin/mach-bf548/dma.c @@ -27,6 +27,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <linux/module.h> + #include <asm/blackfin.h> #include <asm/dma.h> diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index 74fe258421a..46222a75321 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S @@ -28,6 +28,7 @@ */ #include <linux/linkage.h> +#include <linux/init.h> #include <asm/blackfin.h> #include <asm/trace.h> #if CONFIG_BFIN_KERNEL_CLOCK @@ -44,10 +45,9 @@ #define INITIAL_STACK 0xFFB01000 -.text +__INIT ENTRY(__start) -ENTRY(__stext) /* R0: argument of command line string, passed from uboot, save it */ R7 = R0; /* Enable Cycle Counter and Nesting Of Interrupts */ @@ -213,6 +213,7 @@ ENTRY(__stext) .LWAIT_HERE: jump .LWAIT_HERE; +ENDPROC(__start) ENTRY(_real_start) [ -- sp ] = reti; @@ -285,6 +286,9 @@ ENTRY(_real_start) call _start_kernel; .L_exit: jump.s .L_exit; +ENDPROC(_real_start) + +__FINIT .section .l1.text #if CONFIG_BFIN_KERNEL_CLOCK @@ -450,6 +454,7 @@ ENTRY(_start_dma_code) SSYNC; RTS; +ENDPROC(_start_dma_code) #endif /* CONFIG_BFIN_KERNEL_CLOCK */ .data diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 43c1b098281..d357f648d96 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -223,7 +223,7 @@ static struct platform_device bfin_uart_device = { static struct mtd_partition ezkit_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -389,6 +389,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include <linux/i2c-gpio.h> @@ -446,6 +459,7 @@ static struct platform_device *ezkit_devices[] __initdata = { &isp1362_hcd_device, #endif + &bfin_gpios_device, &ezkit_flash_device, }; diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S index b80ddd8b232..9d45aa3265b 100644 --- a/arch/blackfin/mach-common/dpmc.S +++ b/arch/blackfin/mach-common/dpmc.S @@ -31,140 +31,6 @@ #include <asm/blackfin.h> #include <asm/mach/irq.h> -.text - -ENTRY(_unmask_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.H = hi(SICA_IWR1); - P0.L = lo(SICA_IWR1); -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x) - P0.h = HI(SIC_IWR0); - P0.l = LO(SIC_IWR0); -#else - P0.h = HI(SIC_IWR); - P0.l = LO(SIC_IWR); -#endif - R7 = [P0]; -#if defined(CONFIG_BF561) - BITSET(R7, 27); -#else - BITSET(R7,(IRQ_WATCH - IVG7)); -#endif - [P0] = R7; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -.LWRITE_TO_STAT: - /* When watch dog timer is enabled, a write to STAT will load the - * contents of CNT to STAT - */ - R7 = 0x0000(z); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_STAT); - P0.l = LO(WDOGA_STAT); -#else - P0.h = HI(WDOG_STAT); - P0.l = LO(WDOG_STAT); -#endif - [P0] = R7; - SSYNC; - JUMP .LSKIP_WRITE_TO_STAT; - -ENTRY(_program_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CNT); - P0.l = LO(WDOGA_CNT); -#else - P0.h = HI(WDOG_CNT); - P0.l = LO(WDOG_CNT); -#endif - [P0] = R0; - SSYNC; - -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = W[P0](Z); - CC = BITTST(R7,1); - if !CC JUMP .LWRITE_TO_STAT; - CC = BITTST(R7,2); - if !CC JUMP .LWRITE_TO_STAT; - -.LSKIP_WRITE_TO_STAT: -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = W[P0](Z); - BITCLR(R7,1); /* Enable GP event */ - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - NOP; - - R7 = W[P0](Z); - BITCLR(R7,4); /* Enable the wdog counter */ - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_clear_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); - -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = 0x0AD6(Z); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,15); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,1); - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_disable_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = 0xAD6(Z); - W[P0] = R7.L; - SSYNC; - ( R7:0, P5:0 ) = [SP++]; - RTS; - -#if !defined(CONFIG_BF561) .section .l1.text @@ -459,10 +325,12 @@ ENTRY(_set_sic_iwr) RTS; ENTRY(_set_rtc_istat) +#ifndef CONFIG_BF561 P0.H = hi(RTC_ISTAT); P0.L = lo(RTC_ISTAT); w[P0] = R0.L; SSYNC; +#endif RTS; ENTRY(_test_pll_locked) @@ -473,4 +341,3 @@ ENTRY(_test_pll_locked) CC = BITTST(R0,5); IF !CC JUMP 1b; RTS; -#endif diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 880595afe98..225ef14af75 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -74,7 +74,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ #endif struct ivgx { - /* irq number for request_irq, available in mach-bf533/irq.h */ + /* irq number for request_irq, available in mach-bf5xx/irq.h */ unsigned int irqno; /* corresponding bit in the SIC_ISR register */ unsigned int isrflag; @@ -86,7 +86,6 @@ struct ivg_slice { struct ivgx *istop; } ivg7_13[IVG13 - IVG7 + 1]; -static void search_IAR(void); /* * Search SIC_IAR and fill tables with the irqvalues @@ -120,10 +119,10 @@ static void __init search_IAR(void) } /* - * This is for BF533 internal IRQs + * This is for core internal IRQs */ -static void ack_noop(unsigned int irq) +static void bfin_ack_noop(unsigned int irq) { /* Dummy function. */ } @@ -156,11 +155,11 @@ static void bfin_internal_mask_irq(unsigned int irq) { #ifdef CONFIG_BF53x bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << (irq - (IRQ_CORETMR + 1)))); + ~(1 << SIC_SYSIRQ(irq))); #else unsigned mask_bank, mask_bit; - mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; - mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & ~(1 << mask_bit)); #endif @@ -171,11 +170,11 @@ static void bfin_internal_unmask_irq(unsigned int irq) { #ifdef CONFIG_BF53x bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | - (1 << (irq - (IRQ_CORETMR + 1)))); + (1 << SIC_SYSIRQ(irq))); #else unsigned mask_bank, mask_bit; - mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; - mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | (1 << mask_bit)); #endif @@ -187,8 +186,8 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) { unsigned bank, bit; unsigned long flags; - bank = (irq - (IRQ_CORETMR + 1)) / 32; - bit = (irq - (IRQ_CORETMR + 1)) % 32; + bank = SIC_SYSIRQ(irq) / 32; + bit = SIC_SYSIRQ(irq) % 32; local_irq_save(flags); @@ -204,15 +203,18 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) #endif static struct irq_chip bfin_core_irqchip = { - .ack = ack_noop, + .ack = bfin_ack_noop, .mask = bfin_core_mask_irq, .unmask = bfin_core_unmask_irq, }; static struct irq_chip bfin_internal_irqchip = { - .ack = ack_noop, + .ack = bfin_ack_noop, .mask = bfin_internal_mask_irq, .unmask = bfin_internal_unmask_irq, + .mask_ack = bfin_internal_mask_irq, + .disable = bfin_internal_mask_irq, + .enable = bfin_internal_unmask_irq, #ifdef CONFIG_PM .set_wake = bfin_internal_set_wake, #endif @@ -221,38 +223,23 @@ static struct irq_chip bfin_internal_irqchip = { #ifdef BF537_GENERIC_ERROR_INT_DEMUX static int error_int_mask; -static void bfin_generic_error_ack_irq(unsigned int irq) -{ - -} - static void bfin_generic_error_mask_irq(unsigned int irq) { error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); - if (!error_int_mask) { - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << (IRQ_GENERIC_ERROR - - (IRQ_CORETMR + 1)))); - SSYNC(); - local_irq_enable(); - } + if (!error_int_mask) + bfin_internal_mask_irq(IRQ_GENERIC_ERROR); } static void bfin_generic_error_unmask_irq(unsigned int irq) { - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 << - (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1))); - SSYNC(); - local_irq_enable(); - + bfin_internal_unmask_irq(IRQ_GENERIC_ERROR); error_int_mask |= 1L << (irq - IRQ_PPI_ERROR); } static struct irq_chip bfin_generic_error_irqchip = { - .ack = bfin_generic_error_ack_irq, + .ack = bfin_ack_noop, + .mask_ack = bfin_generic_error_mask_irq, .mask = bfin_generic_error_mask_irq, .unmask = bfin_generic_error_unmask_irq, }; @@ -608,7 +595,7 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { (struct pin_int_t *)PINT3_MASK_SET, }; -unsigned short get_irq_base(u8 bank, u8 bmap) +inline unsigned short get_irq_base(u8 bank, u8 bmap) { u16 irq_base; @@ -969,17 +956,12 @@ int __init init_arch_irq(void) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); bfin_write_SIC_IMASK1(SIC_UNMASK_ALL); - bfin_write_SIC_IWR0(IWR_ENABLE_ALL); - bfin_write_SIC_IWR1(IWR_ENABLE_ALL); # ifdef CONFIG_BF54x bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); - bfin_write_SIC_IWR2(IWR_ENABLE_ALL); # endif #else bfin_write_SIC_IMASK(SIC_UNMASK_ALL); - bfin_write_SIC_IWR(IWR_ENABLE_ALL); #endif - SSYNC(); local_irq_disable(); @@ -1001,90 +983,53 @@ int __init init_arch_irq(void) set_irq_chip(irq, &bfin_core_irqchip); else set_irq_chip(irq, &bfin_internal_irqchip); -#ifdef BF537_GENERIC_ERROR_INT_DEMUX - if (irq != IRQ_GENERIC_ERROR) { -#endif - switch (irq) { + switch (irq) { #if defined(CONFIG_BF53x) - case IRQ_PROG_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PROG_INTA: # if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) - case IRQ_MAC_RX: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_MAC_RX: # endif #elif defined(CONFIG_BF54x) - case IRQ_PINT0: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT1: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT2: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT3: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PINT0: + case IRQ_PINT1: + case IRQ_PINT2: + case IRQ_PINT3: #elif defined(CONFIG_BF52x) - case IRQ_PORTF_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PORTG_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PORTH_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PORTF_INTA: + case IRQ_PORTG_INTA: + case IRQ_PORTH_INTA: #elif defined(CONFIG_BF561) - case IRQ_PROG0_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PROG1_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PROG2_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PROG0_INTA: + case IRQ_PROG1_INTA: + case IRQ_PROG2_INTA: #endif - default: - set_irq_handler(irq, handle_simple_irq); - break; - } - + set_irq_chained_handler(irq, + bfin_demux_gpio_irq); + break; #ifdef BF537_GENERIC_ERROR_INT_DEMUX - } else { + case IRQ_GENERIC_ERROR: set_irq_handler(irq, bfin_demux_error_irq); - } + + break; #endif + default: + set_irq_handler(irq, handle_simple_irq); + break; + } } + #ifdef BF537_GENERIC_ERROR_INT_DEMUX - for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) { - set_irq_chip(irq, &bfin_generic_error_irqchip); - set_irq_handler(irq, handle_level_irq); - } + for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) + set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, + handle_level_irq); #endif - for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) { + /* if configured as edge, then will be changed to do_edge_IRQ */ + for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) + set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, + handle_level_irq); - set_irq_chip(irq, &bfin_gpio_irqchip); - /* if configured as edge, then will be changed to do_edge_IRQ */ - set_irq_handler(irq, handle_level_irq); - } bfin_write_IMASK(0); CSYNC(); @@ -1106,6 +1051,16 @@ int __init init_arch_irq(void) IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; +#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) + bfin_write_SIC_IWR0(IWR_ENABLE_ALL); + bfin_write_SIC_IWR1(IWR_ENABLE_ALL); +# ifdef CONFIG_BF54x + bfin_write_SIC_IWR2(IWR_ENABLE_ALL); +# endif +#else + bfin_write_SIC_IWR(IWR_ENABLE_ALL); +#endif + return 0; } @@ -1122,7 +1077,6 @@ void do_irq(int vec, struct pt_regs *fp) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) unsigned long sic_status[3]; - SSYNC(); sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0(); sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1(); #ifdef CONFIG_BF54x @@ -1138,7 +1092,7 @@ void do_irq(int vec, struct pt_regs *fp) } #else unsigned long sic_status; - SSYNC(); + sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); for (;; ivg++) { diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 1f516c55bde..ec3141fefd2 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -181,7 +181,7 @@ void __init mem_init(void) } } -static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end) +static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) { unsigned long addr; /* next to check that the page we free is not a partial page */ @@ -203,7 +203,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) } #endif -void __init free_initmem(void) +void __init_refok free_initmem(void) { #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU free_init_pages("unused kernel memory", diff --git a/arch/powerpc/boot/cuboot-bamboo.c b/arch/powerpc/boot/cuboot-bamboo.c index 900c7ff2b7e..b5c30f766c4 100644 --- a/arch/powerpc/boot/cuboot-bamboo.c +++ b/arch/powerpc/boot/cuboot-bamboo.c @@ -17,6 +17,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c index c5f37ce172e..56564ba37f6 100644 --- a/arch/powerpc/boot/cuboot-ebony.c +++ b/arch/powerpc/boot/cuboot-ebony.c @@ -17,6 +17,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-katmai.c b/arch/powerpc/boot/cuboot-katmai.c index c021167f938..5434d70b566 100644 --- a/arch/powerpc/boot/cuboot-katmai.c +++ b/arch/powerpc/boot/cuboot-katmai.c @@ -22,6 +22,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-taishan.c b/arch/powerpc/boot/cuboot-taishan.c index f66455a45ab..b55b80467ee 100644 --- a/arch/powerpc/boot/cuboot-taishan.c +++ b/arch/powerpc/boot/cuboot-taishan.c @@ -21,7 +21,9 @@ #include "dcr.h" #include "4xx.h" +#define TARGET_4xx #define TARGET_44x +#define TARGET_440GX #include "ppcboot.h" static bd_t bd; diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c index bdedebe1bc1..3db93e85e9e 100644 --- a/arch/powerpc/boot/cuboot-warp.c +++ b/arch/powerpc/boot/cuboot-warp.c @@ -11,6 +11,7 @@ #include "4xx.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts index 5dd3d15f0fe..ae68fefc01b 100644 --- a/arch/powerpc/boot/dts/haleakala.dts +++ b/arch/powerpc/boot/dts/haleakala.dts @@ -235,7 +235,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex"; + compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; port = <0>; /* port number */ reg = <a0000000 20000000 /* Config space access */ diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index bc32ac7250e..fc86e5a3afc 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -38,8 +38,8 @@ timebase-frequency = <0>; /* Filled in by zImage */ i-cache-line-size = <20>; d-cache-line-size = <20>; - i-cache-size = <20000>; - d-cache-size = <20000>; + i-cache-size = <8000>; + d-cache-size = <8000>; dcr-controller; dcr-access-method = "native"; }; @@ -136,11 +136,11 @@ }; POB0: opb { - compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; + compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 4 e0000000 20000000>; - clock-frequency = <0>; /* Filled in by zImage */ + ranges = <00000000 4 e0000000 20000000>; + clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; @@ -153,38 +153,38 @@ }; UART0: serial@10000200 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000200 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000200 8>; virtual-reg = <a0000200>; - clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; - interrupt-parent = <&UIC0>; - interrupts = <0 4>; - }; + clock-frequency = <0>; /* Filled in by zImage */ + current-speed = <1c200>; + interrupt-parent = <&UIC0>; + interrupts = <0 4>; + }; UART1: serial@10000300 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000300 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000300 8>; virtual-reg = <a0000300>; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC0>; - interrupts = <1 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC0>; + interrupts = <1 4>; + }; UART2: serial@10000600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000600 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000600 8>; virtual-reg = <a0000600>; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC1>; - interrupts = <5 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC1>; + interrupts = <5 4>; + }; IIC0: i2c@10000400 { compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 13929771bee..9eed1f68fca 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs, for (i = 0; i < num_counters; ++i) { if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i)) && ctr[i].enabled) { - oprofile_add_pc(pc, is_kernel, i); + oprofile_add_ext_sample(pc, regs, i, is_kernel); cbe_write_ctr(cpu, i, reset_value[i]); } } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 9aa4425d80b..4d5fd1dbd40 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -199,6 +199,7 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv) return 0; } +EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv); /** * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index edab631a8dc..20ea0e118f2 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -113,7 +113,7 @@ /* IOMMU sizing */ #define IO_SEGMENT_SHIFT 28 -#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT) +#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift)) /* The high bit needs to be set on every DMA address */ #define SPIDER_DMA_OFFSET 0x80000000ul @@ -123,7 +123,6 @@ struct iommu_window { struct cbe_iommu *iommu; unsigned long offset; unsigned long size; - unsigned long pte_offset; unsigned int ioid; struct iommu_table table; }; @@ -200,7 +199,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages, (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); + io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); @@ -232,7 +231,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages) | (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); + io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); for (i = 0; i < npages; i++) io_pte[i] = pte; @@ -307,76 +306,84 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base) return -ENODEV; } -static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu, +static void cell_iommu_setup_stab(struct cbe_iommu *iommu, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { struct page *page; - int i; - unsigned long reg, segments, pages_per_segment, ptab_size, stab_size, - n_pte_pages, base; - - base = dbase; - if (fsize != 0) - base = min(fbase, dbase); + unsigned long segments, stab_size; segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT; - pages_per_segment = 1ull << IO_PAGENO_BITS; - pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n", - __FUNCTION__, iommu->nid, segments, pages_per_segment); + pr_debug("%s: iommu[%d]: segments: %lu\n", + __FUNCTION__, iommu->nid, segments); /* set up the segment table */ stab_size = segments * sizeof(unsigned long); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); BUG_ON(!page); iommu->stab = page_address(page); - clear_page(iommu->stab); + memset(iommu->stab, 0, stab_size); +} + +static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu, + unsigned long base, unsigned long size, unsigned long gap_base, + unsigned long gap_size, unsigned long page_shift) +{ + struct page *page; + int i; + unsigned long reg, segments, pages_per_segment, ptab_size, + n_pte_pages, start_seg, *ptab; + + start_seg = base >> IO_SEGMENT_SHIFT; + segments = size >> IO_SEGMENT_SHIFT; + pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift); + /* PTEs for each segment must start on a 4K bounday */ + pages_per_segment = max(pages_per_segment, + (1 << 12) / sizeof(unsigned long)); - /* ... and the page tables. Since these are contiguous, we can treat - * the page tables as one array of ptes, like pSeries does. - */ ptab_size = segments * pages_per_segment * sizeof(unsigned long); pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__, iommu->nid, ptab_size, get_order(ptab_size)); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size)); BUG_ON(!page); - iommu->ptab = page_address(page); - memset(iommu->ptab, 0, ptab_size); + ptab = page_address(page); + memset(ptab, 0, ptab_size); - /* allocate a bogus page for the end of each mapping */ - page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); - BUG_ON(!page); - iommu->pad_page = page_address(page); - clear_page(iommu->pad_page); - - /* number of pages needed for a page table */ - n_pte_pages = (pages_per_segment * - sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT; + /* number of 4K pages needed for a page table */ + n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12; pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n", - __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab, + __FUNCTION__, iommu->nid, iommu->stab, ptab, n_pte_pages); /* initialise the STEs */ reg = IOSTE_V | ((n_pte_pages - 1) << 5); - if (IOMMU_PAGE_SIZE == 0x1000) - reg |= IOSTE_PS_4K; - else if (IOMMU_PAGE_SIZE == 0x10000) - reg |= IOSTE_PS_64K; - else { - extern void __unknown_page_size_error(void); - __unknown_page_size_error(); + switch (page_shift) { + case 12: reg |= IOSTE_PS_4K; break; + case 16: reg |= IOSTE_PS_64K; break; + case 20: reg |= IOSTE_PS_1M; break; + case 24: reg |= IOSTE_PS_16M; break; + default: BUG(); } + gap_base = gap_base >> IO_SEGMENT_SHIFT; + gap_size = gap_size >> IO_SEGMENT_SHIFT; + pr_debug("Setting up IOMMU stab:\n"); - for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) { - iommu->stab[i] = reg | - (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i); + for (i = start_seg; i < (start_seg + segments); i++) { + if (i >= gap_base && i < (gap_base + gap_size)) { + pr_debug("\toverlap at %d, skipping\n", i); + continue; + } + iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) * + (i - start_seg)); pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]); } + + return ptab; } static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) @@ -423,7 +430,9 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long base, unsigned long size) { - cell_iommu_setup_page_tables(iommu, base, size, 0, 0); + cell_iommu_setup_stab(iommu, base, size, 0, 0); + iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0, + IOMMU_PAGE_SHIFT); cell_iommu_enable_hardware(iommu); } @@ -464,6 +473,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, unsigned long pte_offset) { struct iommu_window *window; + struct page *page; u32 ioid; ioid = cell_iommu_get_ioid(np); @@ -475,13 +485,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, window->size = size; window->ioid = ioid; window->iommu = iommu; - window->pte_offset = pte_offset; window->table.it_blocksize = 16; window->table.it_base = (unsigned long)iommu->ptab; window->table.it_index = iommu->nid; - window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + - window->pte_offset; + window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset; window->table.it_size = size >> IOMMU_PAGE_SHIFT; iommu_init_table(&window->table, iommu->nid); @@ -504,6 +512,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, * This code also assumes that we have a window that starts at 0, * which is the case on all spider based blades. */ + page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); + BUG_ON(!page); + iommu->pad_page = page_address(page); + clear_page(iommu->pad_page); + __set_bit(0, window->table.it_map); tce_build_cell(&window->table, window->table.it_offset, 1, (unsigned long)iommu->pad_page, DMA_TO_DEVICE); @@ -549,7 +562,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev) archdata->dma_data = &window->table; } -static void cell_dma_dev_setup_static(struct device *dev); +static void cell_dma_dev_setup_fixed(struct device *dev); static void cell_dma_dev_setup(struct device *dev) { @@ -557,7 +570,7 @@ static void cell_dma_dev_setup(struct device *dev) /* Order is important here, these are not mutually exclusive */ if (get_dma_ops(dev) == &dma_iommu_fixed_ops) - cell_dma_dev_setup_static(dev); + cell_dma_dev_setup_fixed(dev); else if (get_pci_dma_ops() == &dma_iommu_ops) cell_dma_dev_setup_iommu(dev); else if (get_pci_dma_ops() == &dma_direct_ops) @@ -858,7 +871,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) return 0; } -static void cell_dma_dev_setup_static(struct device *dev) +static void cell_dma_dev_setup_fixed(struct device *dev) { struct dev_archdata *archdata = &dev->archdata; u64 addr; @@ -869,35 +882,45 @@ static void cell_dma_dev_setup_static(struct device *dev) dev_dbg(dev, "iommu: fixed addr = %lx\n", addr); } +static void insert_16M_pte(unsigned long addr, unsigned long *ptab, + unsigned long base_pte) +{ + unsigned long segment, offset; + + segment = addr >> IO_SEGMENT_SHIFT; + offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24)); + ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long)); + + pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n", + addr, ptab, segment, offset); + + ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask); +} + static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, struct device_node *np, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { - unsigned long base_pte, uaddr, *io_pte; - int i; + unsigned long base_pte, uaddr, ioaddr, *ptab; - dma_iommu_fixed_base = fbase; + ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24); - /* convert from bytes into page table indices */ - dbase = dbase >> IOMMU_PAGE_SHIFT; - dsize = dsize >> IOMMU_PAGE_SHIFT; - fbase = fbase >> IOMMU_PAGE_SHIFT; - fsize = fsize >> IOMMU_PAGE_SHIFT; + dma_iommu_fixed_base = fbase; pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase); - io_pte = iommu->ptab; base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask); - uaddr = 0; - for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) { + for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) { /* Don't touch the dynamic region */ - if (i >= dbase && i < (dbase + dsize)) { - pr_debug("iommu: static/dynamic overlap, skipping\n"); + ioaddr = uaddr + fbase; + if (ioaddr >= dbase && ioaddr < (dbase + dsize)) { + pr_debug("iommu: fixed/dynamic overlap, skipping\n"); continue; } - io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); + + insert_16M_pte(uaddr, ptab, base_pte); } mb(); @@ -995,7 +1018,9 @@ static int __init cell_iommu_fixed_mapping_init(void) "fixed window 0x%lx-0x%lx\n", iommu->nid, dbase, dbase + dsize, fbase, fbase + fsize); - cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize); + cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize); + iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0, + IOMMU_PAGE_SHIFT); cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize, fbase, fsize); cell_iommu_enable_hardware(iommu); diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index a7f609b3b87..dda34650cb0 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -149,6 +149,11 @@ static void __init cell_init_irq(void) mpic_init_IRQ(); } +static void __init cell_set_dabrx(void) +{ + mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); +} + static void __init cell_setup_arch(void) { #ifdef CONFIG_SPU_BASE @@ -158,6 +163,8 @@ static void __init cell_setup_arch(void) cbe_regs_init(); + cell_set_dabrx(); + #ifdef CONFIG_CBE_RAS cbe_ras_init(); #endif diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 87eb07f94c5..712001f6b7d 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -81,9 +81,12 @@ struct spu_slb { void spu_invalidate_slbs(struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; + unsigned long flags; + spin_lock_irqsave(&spu->register_lock, flags); if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) out_be64(&priv2->slb_invalidate_all_W, 0UL); + spin_unlock_irqrestore(&spu->register_lock, flags); } EXPORT_SYMBOL_GPL(spu_invalidate_slbs); @@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) __func__, slbe, slb->vsid, slb->esid); out_be64(&priv2->slb_index_W, slbe); + /* set invalid before writing vsid */ + out_be64(&priv2->slb_esid_RW, 0); + /* now it's safe to write the vsid */ out_be64(&priv2->slb_vsid_RW, slb->vsid); + /* setting the new esid makes the entry valid again */ out_be64(&priv2->slb_esid_RW, slb->esid); } @@ -290,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, nr_slbs++; } + spin_lock_irq(&spu->register_lock); /* Add the set of SLBs */ for (i = 0; i < nr_slbs; i++) spu_load_slb(spu, i, &slbs[i]); + spin_unlock_irq(&spu->register_lock); } EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs); @@ -337,13 +346,14 @@ spu_irq_class_1(int irq, void *data) if (stat & CLASS1_STORAGE_FAULT_INTR) spu_mfc_dsisr_set(spu, 0ul); spu_int_stat_clear(spu, 1, stat); - spin_unlock(&spu->register_lock); - pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, - dar, dsisr); if (stat & CLASS1_SEGMENT_FAULT_INTR) __spu_trap_data_seg(spu, dar); + spin_unlock(&spu->register_lock); + pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, + dar, dsisr); + if (stat & CLASS1_STORAGE_FAULT_INTR) __spu_trap_data_map(spu, dar, dsisr); diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 133995ed5cc..cf6c2c89211 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -109,13 +109,12 @@ void spu_forget(struct spu_context *ctx) /* * This is basically an open-coded spu_acquire_saved, except that - * we don't acquire the state mutex interruptible. + * we don't acquire the state mutex interruptible, and we don't + * want this context to be rescheduled on release. */ mutex_lock(&ctx->state_mutex); - if (ctx->state != SPU_STATE_SAVED) { - set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); + if (ctx->state != SPU_STATE_SAVED) spu_deactivate(ctx); - } mm = ctx->owner; ctx->owner = NULL; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index c66c3756970..f7a7e8635fb 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -367,6 +367,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, return NOPFN_SIGBUS; /* + * Because we release the mmap_sem, the context may be destroyed while + * we're in spu_wait. Grab an extra reference so it isn't destroyed + * in the meantime. + */ + get_spu_context(ctx); + + /* * We have to wait for context to be loaded before we have * pages to hand out to the user, but we don't want to wait * with the mmap_sem held. @@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, * hanged. */ if (spu_acquire(ctx)) - return NOPFN_REFAULT; + goto refault; if (ctx->state == SPU_STATE_SAVED) { up_read(¤t->mm->mmap_sem); @@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, if (!ret) spu_release(ctx); + +refault: + put_spu_context(ctx); return NOPFN_REFAULT; } diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 3a5972117de..5d5f680cd0b 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) spu_switch_notify(spu, ctx); ctx->state = SPU_STATE_RUNNABLE; - spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); + spuctx_switch_state(ctx, SPU_UTIL_USER); } /* diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 01974f7776e..79aa773f3c9 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n) ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start)); return snprintf(tbuf, n, - "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n", + "[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n", (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec, - t->owner_tid, - t->name, t->curr_tid, + t->name, + t->owner_tid, t->number); } @@ -188,6 +188,7 @@ struct spu_probe spu_probes[] = { { "spufs_ps_nopfn__insert", "%p %p", spu_context_event }, { "spu_acquire_saved__enter", "%p", spu_context_nospu_event }, { "destroy_spu_context__enter", "%p", spu_context_nospu_event }, + { "spufs_stop_callback__enter", "%p %p", spu_context_event }, }; static int __init sputrace_init(void) diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 6f5886c7b1f..e9dc7a55d1b 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -34,6 +34,7 @@ #include <linux/module.h> #include <linux/errno.h> +#include <linux/hardirq.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> @@ -117,6 +118,8 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) * Write INT_MASK_class1 with value of 0. * Save INT_Mask_class2 in CSA. * Write INT_MASK_class2 with value of 0. + * Synchronize all three interrupts to be sure + * we no longer execute a handler on another CPU. */ spin_lock_irq(&spu->register_lock); if (csa) { @@ -129,6 +132,9 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) spu_int_mask_set(spu, 2, 0ul); eieio(); spin_unlock_irq(&spu->register_lock); + synchronize_irq(spu->irqs[0]); + synchronize_irq(spu->irqs[1]); + synchronize_irq(spu->irqs[2]); } static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu) diff --git a/arch/powerpc/platforms/celleb/beat.h b/arch/powerpc/platforms/celleb/beat.h index b2e292df13c..ac82ac35b99 100644 --- a/arch/powerpc/platforms/celleb/beat.h +++ b/arch/powerpc/platforms/celleb/beat.h @@ -21,9 +21,6 @@ #ifndef _CELLEB_BEAT_H #define _CELLEB_BEAT_H -#define DABRX_KERNEL (1UL<<1) -#define DABRX_USER (1UL<<0) - int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*); int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t); int64_t beat_repository_encode(int, const char *, uint64_t[4]); diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b3400b5ad5c..783cfbbf87c 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -330,6 +330,7 @@ config CPU_SUBTYPE_SH5_101 config CPU_SUBTYPE_SH5_103 bool "Support SH5-103 processor" + select CPU_SH5 endchoice diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 5c3359756a9..71ff3d6f26e 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -90,7 +90,7 @@ static irqreturn_t dma_tei(int irq, void *dev_id) static int sh_dmac_request_dma(struct dma_channel *chan) { - if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) + if (unlikely(!(chan->flags & DMA_TEI_CAPABLE))) return 0; return request_irq(get_dmte_irq(chan->chan), dma_tei, diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index b76a14f12ce..ab77b0e0fa0 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -93,7 +93,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev) } hd->base = ioremap_nocache(res->start, res->end - res->start + 1); - if (!unlikely(hd->base)) { + if (unlikely(!hd->base)) { dev_err(&pdev->dev, "ioremap failed\n"); if (!pdev->dev.platform_data) diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index 0dac87b1962..e1284fc6936 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c @@ -83,9 +83,9 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: *val = ctrl_inb(GAPSPCI_BBA_CONFIG+where); break; - case 2: *val = ctrl_inw(GAPSPCI_BBA_CONFIG+where); break; - case 4: *val = ctrl_inl(GAPSPCI_BBA_CONFIG+where); break; + case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; + case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; + case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -97,9 +97,9 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: ctrl_outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; - case 2: ctrl_outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; - case 4: ctrl_outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; + case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; + case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; + case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -127,36 +127,36 @@ int __init gapspci_init(void) */ for (i=0; i<16; i++) - idbuf[i] = ctrl_inb(GAPSPCI_REGS+i); + idbuf[i] = inb(GAPSPCI_REGS+i); if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) return -ENODEV; - ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18); + outl(0x5a14a501, GAPSPCI_REGS+0x18); for (i=0; i<1000000; i++) ; - if (ctrl_inl(GAPSPCI_REGS+0x18) != 1) + if (inl(GAPSPCI_REGS+0x18) != 1) return -EINVAL; - ctrl_outl(0x01000000, GAPSPCI_REGS+0x20); - ctrl_outl(0x01000000, GAPSPCI_REGS+0x24); + outl(0x01000000, GAPSPCI_REGS+0x20); + outl(0x01000000, GAPSPCI_REGS+0x24); - ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); - ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); + outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); + outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); - ctrl_outl(1, GAPSPCI_REGS+0x14); - ctrl_outl(1, GAPSPCI_REGS+0x34); + outl(1, GAPSPCI_REGS+0x14); + outl(1, GAPSPCI_REGS+0x34); /* Setting Broadband Adapter */ - ctrl_outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); - ctrl_outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); - ctrl_outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); - ctrl_outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); - ctrl_outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); - ctrl_outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); - ctrl_outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); + outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); + outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); + outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); + outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); + outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); + outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); + outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); return 0; } diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index b230eb278ce..cc530f4d84d 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -10,7 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c index 3feb95a4fcb..fb781329848 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c @@ -21,8 +21,8 @@ #include <asm/freq.h> #include <asm/io.h> -const static int pll1rate[]={8,12,16,0}; -const static int pfc_divisors[]={1,2,3,4,6,8,12}; +static const int pll1rate[]={8,12,16,0}; +static const int pfc_divisors[]={1,2,3,4,6,8,12}; #define ifc_divisors pfc_divisors #if (CONFIG_SH_CLK_MD == 0) diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index db6ef5cecde..e98dc445035 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -10,7 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index a564425b905..e6d4ec445dd 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -10,7 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index fcc80bb7bee..10f2a760c5e 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void) boot_cpu_data.dcache.way_incr = (1 << 13); boot_cpu_data.dcache.entry_mask = 0x1ff0; boot_cpu_data.dcache.sets = 512; - ctrl_outl(CCR_CACHE_32KB, CCR3); + ctrl_outl(CCR_CACHE_32KB, CCR3_REG); #else - ctrl_outl(CCR_CACHE_16KB, CCR3); + ctrl_outl(CCR_CACHE_16KB, CCR3_REG); #endif #endif } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index dd0a20a685f..f581534cb73 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> #include <asm/rtc.h> enum { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 969804bb523..d3733b13ea5 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -16,7 +16,7 @@ #include <linux/irq.h> #include <linux/platform_device.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> enum { UNUSED = 0, @@ -123,15 +123,15 @@ static struct resource rtc_resources[] = { .flags = IORESOURCE_IO, }, [1] = { - .start = 20, + .start = 21, .flags = IORESOURCE_IRQ, }, [2] = { - .start = 21, + .start = 22, .flags = IORESOURCE_IRQ, }, [3] = { - .start = 22, + .start = 20, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 0cc0e2bf135..7406c9ad925 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> #include <asm/rtc.h> enum { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 3855ea4c21c..8028082527c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -16,7 +16,7 @@ #include <linux/init.h> #include <linux/serial.h> #include <linux/io.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> #include <asm/rtc.h> #define INTC_ICR1 0xA4140010UL diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index dab193293f2..7371abf64f8 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -10,7 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index ae3603aca61..ec884039b91 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/serial.h> #include <linux/io.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 85f81579b97..254c5c55ab9 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -10,7 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index c0a3f079dfd..6d4f50cd4aa 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -10,7 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 967e8b69a2f..f26b5cdad0d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -12,7 +12,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 73c778d40d1..b98b4bc93ec 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -10,9 +10,9 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> +#include <linux/serial_sci.h> #include <linux/mm.h> #include <asm/mmzone.h> -#include <asm/sci.h> static struct resource usbf_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index eabd5386812..07c988dc9de 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/serial.h> #include <linux/io.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 32f4f59a837..b9cec48b180 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -10,7 +10,7 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 293004b526f..18dbbe23fea 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -11,7 +11,7 @@ #include <linux/init.h> #include <linux/serial.h> #include <linux/io.h> -#include <asm/sci.h> +#include <linux/serial_sci.h> static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 74b60e96cdf..621e7329ec6 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -10,10 +10,10 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> +#include <linux/serial_sci.h> #include <linux/io.h> #include <linux/mm.h> #include <asm/mmzone.h> -#include <asm/sci.h> static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 4dc958b6b31..bd35f32534b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -10,9 +10,9 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> +#include <linux/serial_sci.h> #include <linux/io.h> #include <asm/mmzone.h> -#include <asm/sci.h> static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index 313d1620ae8..59e9344e7a0 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c @@ -3,6 +3,9 @@ #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/string.h> +#include <linux/jiffies.h> +#include <linux/timer.h> +#include <linux/uaccess.h> #include <asm/auxio.h> diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c index eeb5a2fc788..bd76482077b 100644 --- a/arch/sparc64/kernel/ds.c +++ b/arch/sparc64/kernel/ds.c @@ -525,10 +525,10 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus, } } -static int dr_cpu_configure(struct ds_info *dp, - struct ds_cap_state *cp, - u64 req_num, - cpumask_t *mask) +static int __cpuinit dr_cpu_configure(struct ds_info *dp, + struct ds_cap_state *cp, + u64 req_num, + cpumask_t *mask) { struct ds_data *resp; int resp_len, ncpus, cpu; @@ -623,9 +623,9 @@ static int dr_cpu_unconfigure(struct ds_info *dp, return 0; } -static void dr_cpu_data(struct ds_info *dp, - struct ds_cap_state *cp, - void *buf, int len) +static void __cpuinit dr_cpu_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) { struct ds_data *data = buf; struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 856659bb131..91008358956 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c @@ -758,7 +758,7 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp, get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } -void __devinit mdesc_fill_in_cpu_data(cpumask_t mask) +void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask) { struct mdesc_handle *hp = mdesc_grab(); u64 mp; diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index e2027f27c0f..2650d0d33ac 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, if (regs->tstate & TSTATE_PRIV) { const struct exception_table_entry *entry; - if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) { - if (insn & 0x2000) - asi = (regs->tstate >> 24); - else - asi = (insn >> 5); - } - - /* Look in asi.h: All _S asis have LS bit set */ - if ((asi & 0x1) && - (entry = search_exception_tables(regs->tpc))) { + entry = search_exception_tables(regs->tpc); + if (entry) { regs->tpc = entry->fixup; regs->tnpc = regs->tpc + 4; return; @@ -294,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) unsigned long tpc = regs->tpc; /* Sanity check the PC. */ - if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) || + if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) || (tpc >= MODULES_VADDR && tpc < MODULES_END)) { /* Valid, no problems... */ } else { diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 9e6bca266d8..b5c30416fda 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1010,7 +1010,8 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata; static int pall_ents __initdata; #ifdef CONFIG_DEBUG_PAGEALLOC -static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot) +static unsigned long __ref kernel_map_range(unsigned long pstart, + unsigned long pend, pgprot_t prot) { unsigned long vstart = PAGE_OFFSET + pstart; unsigned long vend = PAGE_OFFSET + pend; diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index 5b3ce793436..3d01e47777d 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c @@ -15,6 +15,7 @@ static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); +EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */ /* * Initial thread structure. diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index a7d50a547dc..be3c7a299f0 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -603,11 +603,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, } #endif +#ifdef X86_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); +#endif if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 43f287744f9..3baf9b9f4c8 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -604,11 +604,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); } +#ifdef X86_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); +#endif } /* diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index d862e396b09..f41fdc98efb 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -544,6 +544,8 @@ static int ptrace_set_debugreg(struct task_struct *child, return 0; } +#ifdef X86_BTS + static int ptrace_bts_get_size(struct task_struct *child) { if (!child->thread.ds_area_msr) @@ -826,6 +828,7 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk, ptrace_bts_write_record(tsk, &rec); } +#endif /* X86_BTS */ /* * Called by kernel/ptrace.c when detaching.. @@ -839,7 +842,9 @@ void ptrace_disable(struct task_struct *child) clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); #endif if (child->thread.ds_area_msr) { +#ifdef X86_BTS ptrace_bts_realloc(child, 0, 0); +#endif child->thread.debugctlmsr &= ~ds_debugctl_mask(); if (!child->thread.debugctlmsr) clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); @@ -961,6 +966,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; #endif + /* + * These bits need more cooking - not enabled yet: + */ +#ifdef X86_BTS case PTRACE_BTS_CONFIG: ret = ptrace_bts_config (child, data, (struct ptrace_bts_config __user *)addr); @@ -988,6 +997,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = ptrace_bts_drain (child, data, (struct bts_struct __user *) addr); break; +#endif default: ret = ptrace_request(child, request, addr, data); @@ -1226,12 +1236,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_SETOPTIONS: case PTRACE_SET_THREAD_AREA: case PTRACE_GET_THREAD_AREA: +#ifdef X86_BTS case PTRACE_BTS_CONFIG: case PTRACE_BTS_STATUS: case PTRACE_BTS_SIZE: case PTRACE_BTS_GET: case PTRACE_BTS_CLEAR: case PTRACE_BTS_DRAIN: +#endif return sys_ptrace(request, pid, addr, data); default: diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 6dfd4e76661..022bcaa3b42 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -91,7 +91,9 @@ int do_set_thread_area(struct task_struct *p, int idx, asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) { - return do_set_thread_area(current, -1, u_info, 1); + int ret = do_set_thread_area(current, -1, u_info, 1); + prevent_tail_call(ret); + return ret; } @@ -139,7 +141,9 @@ int do_get_thread_area(struct task_struct *p, int idx, asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) { - return do_get_thread_area(current, -1, u_info); + int ret = do_get_thread_area(current, -1, u_info); + prevent_tail_call(ret); + return ret; } int regset_tls_active(struct task_struct *target, diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index b6be812fac0..edff4c98548 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -222,10 +222,19 @@ long __vsyscall(3) venosys_1(void) } #ifdef CONFIG_SYSCTL + +static int +vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return proc_dointvec(ctl, write, filp, buffer, lenp, ppos); +} + static ctl_table kernel_table2[] = { { .procname = "vsyscall64", .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), - .mode = 0644 }, + .mode = 0644, + .proc_handler = vsyscall_sysctl_change }, {} }; diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 882328efc3d..ac3c959e271 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -162,7 +162,7 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, area->phys_addr = phys_addr; vaddr = (unsigned long) area->addr; if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) { - remove_vm_area((void *)(vaddr & PAGE_MASK)); + free_vm_area(area); return NULL; } diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index b8bd0c4aa02..0a8f4742ef5 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -48,9 +48,11 @@ obj-$(VDSO64-y) += vdso-syms.lds # Match symbols in the DSO that look like VDSO*; produce a file of constants. # sed-vdsosym := -e 's/^00*/0/' \ - -e 's/^\([[:xdigit:]]*\) . \(VDSO[[:alnum:]_]*\)$$/\2 = 0x\1;/p' + -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' quiet_cmd_vdsosym = VDSOSYM $@ - cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +define cmd_vdsosym + $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +endef $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE $(call if_changed,vdsosym) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 49e5358f481..8b9ee27805f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -153,6 +153,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, if (*ax == 1) maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ (1 << X86_FEATURE_ACPI) | /* disable ACPI */ + (1 << X86_FEATURE_SEP) | /* disable SEP */ (1 << X86_FEATURE_ACC)); /* thermal monitoring */ asm(XEN_EMULATE_PREFIX "cpuid" diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0562b0a49f3..7b1f1ee8131 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1694,12 +1694,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, u8 *rbuf; unsigned int buflen, rc; struct scsi_cmnd *cmd = args->cmd; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &rbuf); memset(rbuf, 0, buflen); rc = actor(args, rbuf, buflen); ata_scsi_rbuf_put(cmd, rbuf); + local_irq_restore(flags); + if (rc == 0) cmd->result = SAM_STAT_GOOD; args->done(cmd); @@ -2473,6 +2478,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { u8 *buf = NULL; unsigned int buflen; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &buf); @@ -2490,6 +2498,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) } ata_scsi_rbuf_put(cmd, buf); + + local_irq_restore(flags); } cmd->result = SAM_STAT_GOOD; diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 69f651e0bc9..840d1c4a785 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -45,6 +45,8 @@ #include <linux/interrupt.h> #include <linux/device.h> #include <scsi/scsi_host.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi.h> #include <linux/libata.h> #ifdef CONFIG_PPC_OF @@ -59,6 +61,7 @@ enum { /* ap->flags bits */ K2_FLAG_SATA_8_PORTS = (1 << 24), K2_FLAG_NO_ATAPI_DMA = (1 << 25), + K2_FLAG_BAR_POS_3 = (1 << 26), /* Taskfile registers offsets */ K2_SATA_TF_CMD_OFFSET = 0x00, @@ -88,8 +91,10 @@ enum { /* Port stride */ K2_SATA_PORT_OFFSET = 0x100, - board_svw4 = 0, - board_svw8 = 1, + chip_svw4 = 0, + chip_svw8 = 1, + chip_svw42 = 2, /* bar 3 */ + chip_svw43 = 3, /* bar 5 */ }; static u8 k2_stat_check_status(struct ata_port *ap); @@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap); static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) { + u8 cmnd = qc->scsicmd->cmnd[0]; + if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) return -1; /* ATAPI DMA not supported */ + else { + switch (cmnd) { + case READ_10: + case READ_12: + case READ_16: + case WRITE_10: + case WRITE_12: + case WRITE_16: + return 0; + + default: + return -1; + } - return 0; + } } static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) @@ -354,7 +374,7 @@ static const struct ata_port_operations k2_sata_ops = { }; static const struct ata_port_info k2_port_info[] = { - /* board_svw4 */ + /* chip_svw4 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, @@ -363,7 +383,7 @@ static const struct ata_port_info k2_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, - /* board_svw8 */ + /* chip_svw8 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | @@ -373,6 +393,24 @@ static const struct ata_port_info k2_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, + /* chip_svw42 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = ATA_UDMA6, + .port_ops = &k2_sata_ops, + }, + /* chip_svw43 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = ATA_UDMA6, + .port_ops = &k2_sata_ops, + }, }; static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) @@ -402,7 +440,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en { &k2_port_info[ent->driver_data], NULL }; struct ata_host *host; void __iomem *mmio_base; - int n_ports, i, rc; + int n_ports, i, rc, bar_pos; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); @@ -416,6 +454,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en if (!host) return -ENOMEM; + bar_pos = 5; + if (ppi[0]->flags & K2_FLAG_BAR_POS_3) + bar_pos = 3; /* * If this driver happens to only be useful on Apple's K2, then * we should check that here as it has a normal Serverworks ID @@ -428,17 +469,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en * Check if we have resources mapped at all (second function may * have been disabled by firmware) */ - if (pci_resource_len(pdev, 5) == 0) + if (pci_resource_len(pdev, bar_pos) == 0) { + /* In IDE mode we need to pin the device to ensure that + pcim_release does not clear the busmaster bit in config + space, clearing causes busmaster DMA to fail on + ports 3 & 4 */ + pcim_pin_device(pdev); return -ENODEV; + } /* Request and iomap PCI regions */ - rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); + rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); if (rc) return rc; host->iomap = pcim_iomap_table(pdev); - mmio_base = host->iomap[5]; + mmio_base = host->iomap[bar_pos]; /* different controllers have different number of ports - currently 4 or 8 */ /* All ports are on the same function. Multi-function device is no @@ -483,11 +530,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en * controller * */ static const struct pci_device_id k2_sata_pci_tbl[] = { - { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 }, - { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 }, + { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 }, + { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 }, { } }; diff --git a/drivers/base/transport_class.c b/drivers/base/transport_class.c index f25e7c6b2d2..40bca48abc1 100644 --- a/drivers/base/transport_class.c +++ b/drivers/base/transport_class.c @@ -126,9 +126,7 @@ static int transport_setup_classdev(struct attribute_container *cont, } /** - * transport_setup_device - declare a new dev for transport class association - * but don't make it visible yet. - * + * transport_setup_device - declare a new dev for transport class association but don't make it visible yet. * @dev: the generic device representing the entity being added * * Usually, dev represents some component in the HBA system (either diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 78b151c4d20..5c3142b6f1f 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -110,8 +110,8 @@ static int rtc_has_irq = 1; #define hpet_set_rtc_irq_bit(arg) 0 #define hpet_rtc_timer_init() do { } while (0) #define hpet_rtc_dropped_irq() 0 -#define hpet_register_irq_handler(h) 0 -#define hpet_unregister_irq_handler(h) 0 +#define hpet_register_irq_handler(h) ({ 0; }) +#define hpet_unregister_irq_handler(h) ({ 0; }) #ifdef RTC_IRQ static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) { diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c index dfea2bde162..f577daedb63 100644 --- a/drivers/char/xilinx_hwicap/buffer_icap.c +++ b/drivers/char/xilinx_hwicap/buffer_icap.c @@ -73,8 +73,8 @@ #define XHI_BUFFER_START 0 /** - * buffer_icap_get_status: Get the contents of the status register. - * @parameter base_address: is the base address of the device + * buffer_icap_get_status - Get the contents of the status register. + * @base_address: is the base address of the device * * The status register contains the ICAP status and the done bit. * @@ -94,9 +94,9 @@ static inline u32 buffer_icap_get_status(void __iomem *base_address) } /** - * buffer_icap_get_bram: Reads data from the storage buffer bram. - * @parameter base_address: contains the base address of the component. - * @parameter offset: The word offset from which the data should be read. + * buffer_icap_get_bram - Reads data from the storage buffer bram. + * @base_address: contains the base address of the component. + * @offset: The word offset from which the data should be read. * * A bram is used as a configuration memory cache. One frame of data can * be stored in this "storage buffer". @@ -108,8 +108,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address, } /** - * buffer_icap_busy: Return true if the icap device is busy - * @parameter base_address: is the base address of the device + * buffer_icap_busy - Return true if the icap device is busy + * @base_address: is the base address of the device * * The queries the low order bit of the status register, which * indicates whether the current configuration or readback operation @@ -121,8 +121,8 @@ static inline bool buffer_icap_busy(void __iomem *base_address) } /** - * buffer_icap_busy: Return true if the icap device is not busy - * @parameter base_address: is the base address of the device + * buffer_icap_busy - Return true if the icap device is not busy + * @base_address: is the base address of the device * * The queries the low order bit of the status register, which * indicates whether the current configuration or readback operation @@ -134,9 +134,9 @@ static inline bool buffer_icap_done(void __iomem *base_address) } /** - * buffer_icap_set_size: Set the size register. - * @parameter base_address: is the base address of the device - * @parameter data: The size in bytes. + * buffer_icap_set_size - Set the size register. + * @base_address: is the base address of the device + * @data: The size in bytes. * * The size register holds the number of 8 bit bytes to transfer between * bram and the icap (or icap to bram). @@ -148,9 +148,9 @@ static inline void buffer_icap_set_size(void __iomem *base_address, } /** - * buffer_icap_mSetoffsetReg: Set the bram offset register. - * @parameter base_address: contains the base address of the device. - * @parameter data: is the value to be written to the data register. + * buffer_icap_set_offset - Set the bram offset register. + * @base_address: contains the base address of the device. + * @data: is the value to be written to the data register. * * The bram offset register holds the starting bram address to transfer * data from during configuration or write data to during readback. @@ -162,9 +162,9 @@ static inline void buffer_icap_set_offset(void __iomem *base_address, } /** - * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register. - * @parameter base_address: contains the base address of the device. - * @parameter data: is the value to be written to the data register. + * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register. + * @base_address: contains the base address of the device. + * @data: is the value to be written to the data register. * * The RNC register determines the direction of the data transfer. It * controls whether a configuration or readback take place. Writing to @@ -178,10 +178,10 @@ static inline void buffer_icap_set_rnc(void __iomem *base_address, } /** - * buffer_icap_set_bram: Write data to the storage buffer bram. - * @parameter base_address: contains the base address of the component. - * @parameter offset: The word offset at which the data should be written. - * @parameter data: The value to be written to the bram offset. + * buffer_icap_set_bram - Write data to the storage buffer bram. + * @base_address: contains the base address of the component. + * @offset: The word offset at which the data should be written. + * @data: The value to be written to the bram offset. * * A bram is used as a configuration memory cache. One frame of data can * be stored in this "storage buffer". @@ -193,10 +193,10 @@ static inline void buffer_icap_set_bram(void __iomem *base_address, } /** - * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer. - * @parameter drvdata: a pointer to the drvdata. - * @parameter offset: The storage buffer start address. - * @parameter count: The number of words (32 bit) to read from the + * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer. + * @drvdata: a pointer to the drvdata. + * @offset: The storage buffer start address. + * @count: The number of words (32 bit) to read from the * device (ICAP). **/ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, @@ -227,10 +227,10 @@ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, }; /** - * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer. - * @parameter drvdata: a pointer to the drvdata. - * @parameter offset: The storage buffer start address. - * @parameter count: The number of words (32 bit) to read from the + * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer. + * @drvdata: a pointer to the drvdata. + * @offset: The storage buffer start address. + * @count: The number of words (32 bit) to read from the * device (ICAP). **/ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, @@ -261,8 +261,8 @@ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, }; /** - * buffer_icap_reset: Reset the logic of the icap device. - * @parameter drvdata: a pointer to the drvdata. + * buffer_icap_reset - Reset the logic of the icap device. + * @drvdata: a pointer to the drvdata. * * Writing to the status register resets the ICAP logic in an internal * version of the core. For the version of the core published in EDK, @@ -274,10 +274,10 @@ void buffer_icap_reset(struct hwicap_drvdata *drvdata) } /** - * buffer_icap_set_configuration: Load a partial bitstream from system memory. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: Kernel address of the partial bitstream. - * @parameter size: the size of the partial bitstream in 32 bit words. + * buffer_icap_set_configuration - Load a partial bitstream from system memory. + * @drvdata: a pointer to the drvdata. + * @data: Kernel address of the partial bitstream. + * @size: the size of the partial bitstream in 32 bit words. **/ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, u32 size) @@ -333,10 +333,10 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, }; /** - * buffer_icap_get_configuration: Read configuration data from the device. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: Address of the data representing the partial bitstream - * @parameter size: the size of the partial bitstream in 32 bit words. + * buffer_icap_get_configuration - Read configuration data from the device. + * @drvdata: a pointer to the drvdata. + * @data: Address of the data representing the partial bitstream + * @size: the size of the partial bitstream in 32 bit words. **/ int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, u32 size) diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c index 0988314694a..6f45dbd4712 100644 --- a/drivers/char/xilinx_hwicap/fifo_icap.c +++ b/drivers/char/xilinx_hwicap/fifo_icap.c @@ -94,9 +94,9 @@ /** - * fifo_icap_fifo_write: Write data to the write FIFO. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: the 32-bit value to be written to the FIFO. + * fifo_icap_fifo_write - Write data to the write FIFO. + * @drvdata: a pointer to the drvdata. + * @data: the 32-bit value to be written to the FIFO. * * This function will silently fail if the fifo is full. **/ @@ -108,8 +108,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_fifo_read: Read data from the Read FIFO. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_fifo_read - Read data from the Read FIFO. + * @drvdata: a pointer to the drvdata. * * This function will silently fail if the fifo is empty. **/ @@ -121,9 +121,9 @@ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_set_read_size: Set the the size register. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: the size of the following read transaction, in words. + * fifo_icap_set_read_size - Set the the size register. + * @drvdata: a pointer to the drvdata. + * @data: the size of the following read transaction, in words. **/ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, u32 data) @@ -132,8 +132,8 @@ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_start_config: Initiate a configuration (write) to the device. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_start_config - Initiate a configuration (write) to the device. + * @drvdata: a pointer to the drvdata. **/ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) { @@ -142,8 +142,8 @@ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_start_readback: Initiate a readback from the device. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_start_readback - Initiate a readback from the device. + * @drvdata: a pointer to the drvdata. **/ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) { @@ -152,8 +152,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_busy: Return true if the ICAP is still processing a transaction. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_busy - Return true if the ICAP is still processing a transaction. + * @drvdata: a pointer to the drvdata. **/ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) { @@ -163,8 +163,8 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_write_fifo_vacancy: Query the write fifo available space. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_write_fifo_vacancy - Query the write fifo available space. + * @drvdata: a pointer to the drvdata. * * Return the number of words that can be safely pushed into the write fifo. **/ @@ -175,8 +175,8 @@ static inline u32 fifo_icap_write_fifo_vacancy( } /** - * fifo_icap_read_fifo_occupancy: Query the read fifo available data. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_read_fifo_occupancy - Query the read fifo available data. + * @drvdata: a pointer to the drvdata. * * Return the number of words that can be safely read from the read fifo. **/ @@ -187,11 +187,11 @@ static inline u32 fifo_icap_read_fifo_occupancy( } /** - * fifo_icap_set_configuration: Send configuration data to the ICAP. - * @parameter drvdata: a pointer to the drvdata. - * @parameter frame_buffer: a pointer to the data to be written to the + * fifo_icap_set_configuration - Send configuration data to the ICAP. + * @drvdata: a pointer to the drvdata. + * @frame_buffer: a pointer to the data to be written to the * ICAP device. - * @parameter num_words: the number of words (32 bit) to write to the ICAP + * @num_words: the number of words (32 bit) to write to the ICAP * device. * This function writes the given user data to the Write FIFO in @@ -266,10 +266,10 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_get_configuration: Read configuration data from the device. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: Address of the data representing the partial bitstream - * @parameter size: the size of the partial bitstream in 32 bit words. + * fifo_icap_get_configuration - Read configuration data from the device. + * @drvdata: a pointer to the drvdata. + * @data: Address of the data representing the partial bitstream + * @size: the size of the partial bitstream in 32 bit words. * * This function reads the specified number of words from the ICAP device in * the polled mode. @@ -335,8 +335,8 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata, } /** - * buffer_icap_reset: Reset the logic of the icap device. - * @parameter drvdata: a pointer to the drvdata. + * buffer_icap_reset - Reset the logic of the icap device. + * @drvdata: a pointer to the drvdata. * * This function forces the software reset of the complete HWICAP device. * All the registers will return to the default value and the FIFO is also @@ -360,8 +360,8 @@ void fifo_icap_reset(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_flush_fifo: This function flushes the FIFOs in the device. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_flush_fifo - This function flushes the FIFOs in the device. + * @drvdata: a pointer to the drvdata. */ void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata) { diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 24f6aef0fd3..2284fa2a5a5 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -84,7 +84,7 @@ #include <linux/init.h> #include <linux/poll.h> #include <linux/proc_fs.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> #include <linux/sysctl.h> #include <linux/version.h> #include <linux/fs.h> @@ -119,6 +119,7 @@ module_param(xhwicap_minor, int, S_IRUGO); /* An array, which is set to true when the device is registered. */ static bool probed_devices[HWICAP_DEVICES]; +static struct mutex icap_sem; static struct class *icap_class; @@ -199,14 +200,14 @@ static const struct config_registers v5_config_registers = { }; /** - * hwicap_command_desync: Send a DESYNC command to the ICAP port. - * @parameter drvdata: a pointer to the drvdata. + * hwicap_command_desync - Send a DESYNC command to the ICAP port. + * @drvdata: a pointer to the drvdata. * * This command desynchronizes the ICAP After this command, a * bitstream containing a NULL packet, followed by a SYNCH packet is * required before the ICAP will recognize commands. */ -int hwicap_command_desync(struct hwicap_drvdata *drvdata) +static int hwicap_command_desync(struct hwicap_drvdata *drvdata) { u32 buffer[4]; u32 index = 0; @@ -228,51 +229,18 @@ int hwicap_command_desync(struct hwicap_drvdata *drvdata) } /** - * hwicap_command_capture: Send a CAPTURE command to the ICAP port. - * @parameter drvdata: a pointer to the drvdata. - * - * This command captures all of the flip flop states so they will be - * available during readback. One can use this command instead of - * enabling the CAPTURE block in the design. - */ -int hwicap_command_capture(struct hwicap_drvdata *drvdata) -{ - u32 buffer[7]; - u32 index = 0; - - /* - * Create the data to be written to the ICAP. - */ - buffer[index++] = XHI_DUMMY_PACKET; - buffer[index++] = XHI_SYNC_PACKET; - buffer[index++] = XHI_NOOP_PACKET; - buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1; - buffer[index++] = XHI_CMD_GCAPTURE; - buffer[index++] = XHI_DUMMY_PACKET; - buffer[index++] = XHI_DUMMY_PACKET; - - /* - * Write the data to the FIFO and intiate the transfer of data - * present in the FIFO to the ICAP device. - */ - return drvdata->config->set_configuration(drvdata, - &buffer[0], index); - -} - -/** - * hwicap_get_configuration_register: Query a configuration register. - * @parameter drvdata: a pointer to the drvdata. - * @parameter reg: a constant which represents the configuration + * hwicap_get_configuration_register - Query a configuration register. + * @drvdata: a pointer to the drvdata. + * @reg: a constant which represents the configuration * register value to be returned. * Examples: XHI_IDCODE, XHI_FLR. - * @parameter RegData: returns the value of the register. + * @reg_data: returns the value of the register. * * Sends a query packet to the ICAP and then receives the response. * The icap is left in Synched state. */ -int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, - u32 reg, u32 *RegData) +static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, + u32 reg, u32 *reg_data) { int status; u32 buffer[6]; @@ -300,14 +268,14 @@ int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, /* * Read the configuration register */ - status = drvdata->config->get_configuration(drvdata, RegData, 1); + status = drvdata->config->get_configuration(drvdata, reg_data, 1); if (status) return status; return 0; } -int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) +static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) { int status; u32 idcode; @@ -344,7 +312,7 @@ int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) } static ssize_t -hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) +hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct hwicap_drvdata *drvdata = file->private_data; ssize_t bytes_to_read = 0; @@ -353,8 +321,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) u32 bytes_remaining; int status; - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + status = mutex_lock_interruptible(&drvdata->sem); + if (status) + return status; if (drvdata->read_buffer_in_use) { /* If there are leftover bytes in the buffer, just */ @@ -370,8 +339,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) goto error; } drvdata->read_buffer_in_use -= bytes_to_read; - memcpy(drvdata->read_buffer + bytes_to_read, - drvdata->read_buffer, 4 - bytes_to_read); + memmove(drvdata->read_buffer, + drvdata->read_buffer + bytes_to_read, + 4 - bytes_to_read); } else { /* Get new data from the ICAP, and return was was requested. */ kbuf = (u32 *) get_zeroed_page(GFP_KERNEL); @@ -414,18 +384,20 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) status = -EFAULT; goto error; } - memcpy(kbuf, drvdata->read_buffer, bytes_remaining); + memcpy(drvdata->read_buffer, + kbuf, + bytes_remaining); drvdata->read_buffer_in_use = bytes_remaining; free_page((unsigned long)kbuf); } status = bytes_to_read; error: - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } static ssize_t -hwicap_write(struct file *file, const char *buf, +hwicap_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct hwicap_drvdata *drvdata = file->private_data; @@ -435,8 +407,9 @@ hwicap_write(struct file *file, const char *buf, ssize_t len; ssize_t status; - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + status = mutex_lock_interruptible(&drvdata->sem); + if (status) + return status; left += drvdata->write_buffer_in_use; @@ -465,7 +438,7 @@ hwicap_write(struct file *file, const char *buf, memcpy(kbuf, drvdata->write_buffer, drvdata->write_buffer_in_use); if (copy_from_user( - (((char *)kbuf) + (drvdata->write_buffer_in_use)), + (((char *)kbuf) + drvdata->write_buffer_in_use), buf + written, len - (drvdata->write_buffer_in_use))) { free_page((unsigned long)kbuf); @@ -508,7 +481,7 @@ hwicap_write(struct file *file, const char *buf, free_page((unsigned long)kbuf); status = written; error: - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } @@ -519,8 +492,9 @@ static int hwicap_open(struct inode *inode, struct file *file) drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + status = mutex_lock_interruptible(&drvdata->sem); + if (status) + return status; if (drvdata->is_open) { status = -EBUSY; @@ -539,7 +513,7 @@ static int hwicap_open(struct inode *inode, struct file *file) drvdata->is_open = 1; error: - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } @@ -549,8 +523,7 @@ static int hwicap_release(struct inode *inode, struct file *file) int i; int status = 0; - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + mutex_lock(&drvdata->sem); if (drvdata->write_buffer_in_use) { /* Flush write buffer. */ @@ -569,7 +542,7 @@ static int hwicap_release(struct inode *inode, struct file *file) error: drvdata->is_open = 0; - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } @@ -592,31 +565,36 @@ static int __devinit hwicap_setup(struct device *dev, int id, dev_info(dev, "Xilinx icap port driver\n"); + mutex_lock(&icap_sem); + if (id < 0) { for (id = 0; id < HWICAP_DEVICES; id++) if (!probed_devices[id]) break; } if (id < 0 || id >= HWICAP_DEVICES) { + mutex_unlock(&icap_sem); dev_err(dev, "%s%i too large\n", DRIVER_NAME, id); return -EINVAL; } if (probed_devices[id]) { + mutex_unlock(&icap_sem); dev_err(dev, "cannot assign to %s%i; it is already in use\n", DRIVER_NAME, id); return -EBUSY; } probed_devices[id] = 1; + mutex_unlock(&icap_sem); devt = MKDEV(xhwicap_major, xhwicap_minor + id); - drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); + drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); if (!drvdata) { dev_err(dev, "Couldn't allocate device private record\n"); - return -ENOMEM; + retval = -ENOMEM; + goto failed0; } - memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata)); dev_set_drvdata(dev, (void *)drvdata); if (!regs_res) { @@ -648,7 +626,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, drvdata->config = config; drvdata->config_regs = config_regs; - init_MUTEX(&drvdata->sem); + mutex_init(&drvdata->sem); drvdata->is_open = 0; dev_info(dev, "ioremap %lx to %p with size %x\n", @@ -663,7 +641,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, goto failed3; } /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */ - class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME); + device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id); return 0; /* success */ failed3: @@ -675,6 +653,11 @@ static int __devinit hwicap_setup(struct device *dev, int id, failed1: kfree(drvdata); + failed0: + mutex_lock(&icap_sem); + probed_devices[id] = 0; + mutex_unlock(&icap_sem); + return retval; } @@ -699,14 +682,16 @@ static int __devexit hwicap_remove(struct device *dev) if (!drvdata) return 0; - class_device_destroy(icap_class, drvdata->devt); + device_destroy(icap_class, drvdata->devt); cdev_del(&drvdata->cdev); iounmap(drvdata->base_address); release_mem_region(drvdata->mem_start, drvdata->mem_size); kfree(drvdata); dev_set_drvdata(dev, NULL); - probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0; + mutex_lock(&icap_sem); + probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0; + mutex_unlock(&icap_sem); return 0; /* success */ } @@ -821,28 +806,29 @@ static struct of_platform_driver hwicap_of_driver = { }; /* Registration helpers to keep the number of #ifdefs to a minimum */ -static inline int __devinit hwicap_of_register(void) +static inline int __init hwicap_of_register(void) { pr_debug("hwicap: calling of_register_platform_driver()\n"); return of_register_platform_driver(&hwicap_of_driver); } -static inline void __devexit hwicap_of_unregister(void) +static inline void __exit hwicap_of_unregister(void) { of_unregister_platform_driver(&hwicap_of_driver); } #else /* CONFIG_OF */ /* CONFIG_OF not enabled; do nothing helpers */ -static inline int __devinit hwicap_of_register(void) { return 0; } -static inline void __devexit hwicap_of_unregister(void) { } +static inline int __init hwicap_of_register(void) { return 0; } +static inline void __exit hwicap_of_unregister(void) { } #endif /* CONFIG_OF */ -static int __devinit hwicap_module_init(void) +static int __init hwicap_module_init(void) { dev_t devt; int retval; icap_class = class_create(THIS_MODULE, "xilinx_config"); + mutex_init(&icap_sem); if (xhwicap_major) { devt = MKDEV(xhwicap_major, xhwicap_minor); @@ -883,7 +869,7 @@ static int __devinit hwicap_module_init(void) return retval; } -static void __devexit hwicap_module_cleanup(void) +static void __exit hwicap_module_cleanup(void) { dev_t devt = MKDEV(xhwicap_major, xhwicap_minor); diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h index ae771cac162..405fee7e189 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h @@ -48,9 +48,9 @@ struct hwicap_drvdata { u8 write_buffer[4]; u32 read_buffer_in_use; /* Always in [0,3] */ u8 read_buffer[4]; - u32 mem_start; /* phys. address of the control registers */ - u32 mem_end; /* phys. address of the control registers */ - u32 mem_size; + resource_size_t mem_start;/* phys. address of the control registers */ + resource_size_t mem_end; /* phys. address of the control registers */ + resource_size_t mem_size; void __iomem *base_address;/* virt. address of the control registers */ struct device *dev; @@ -61,7 +61,7 @@ struct hwicap_drvdata { const struct config_registers *config_regs; void *private_data; bool is_open; - struct semaphore sem; + struct mutex sem; }; struct hwicap_driver_config { @@ -164,29 +164,29 @@ struct config_registers { #define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL /** - * hwicap_type_1_read: Generates a Type 1 read packet header. - * @parameter: Register is the address of the register to be read back. + * hwicap_type_1_read - Generates a Type 1 read packet header. + * @reg: is the address of the register to be read back. * * Generates a Type 1 read packet header, which is used to indirectly * read registers in the configuration logic. This packet must then * be sent through the icap device, and a return packet received with * the information. **/ -static inline u32 hwicap_type_1_read(u32 Register) +static inline u32 hwicap_type_1_read(u32 reg) { return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | - (Register << XHI_REGISTER_SHIFT) | + (reg << XHI_REGISTER_SHIFT) | (XHI_OP_READ << XHI_OP_SHIFT); } /** - * hwicap_type_1_write: Generates a Type 1 write packet header - * @parameter: Register is the address of the register to be read back. + * hwicap_type_1_write - Generates a Type 1 write packet header + * @reg: is the address of the register to be read back. **/ -static inline u32 hwicap_type_1_write(u32 Register) +static inline u32 hwicap_type_1_write(u32 reg) { return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | - (Register << XHI_REGISTER_SHIFT) | + (reg << XHI_REGISTER_SHIFT) | (XHI_OP_WRITE << XHI_OP_SHIFT); } diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index fea2d3ed9cb..85e2ba7fcfb 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -47,7 +47,7 @@ static LIST_HEAD(notify_list); static struct cn_dev cdev; -int cn_already_initialized = 0; +static int cn_already_initialized; /* * msg->seq and msg->ack are used to determine message genealogy. diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 3e9719948a8..a03462750b9 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/errno.h> +#include <linux/delay.h> #include <linux/device.h> #include <linux/mutex.h> #include <linux/crc-itu-t.h> @@ -214,17 +215,29 @@ static void fw_card_bm_work(struct work_struct *work) { struct fw_card *card = container_of(work, struct fw_card, work.work); - struct fw_device *root; + struct fw_device *root_device; + struct fw_node *root_node, *local_node; struct bm_data bmd; unsigned long flags; int root_id, new_root_id, irm_id, gap_count, generation, grace; int do_reset = 0; spin_lock_irqsave(&card->lock, flags); + local_node = card->local_node; + root_node = card->root_node; + + if (local_node == NULL) { + spin_unlock_irqrestore(&card->lock, flags); + return; + } + fw_node_get(local_node); + fw_node_get(root_node); generation = card->generation; - root = card->root_node->data; - root_id = card->root_node->node_id; + root_device = root_node->data; + if (root_device) + fw_device_get(root_device); + root_id = root_node->node_id; grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); if (card->bm_generation + 1 == generation || @@ -243,14 +256,14 @@ fw_card_bm_work(struct work_struct *work) irm_id = card->irm_node->node_id; if (!card->irm_node->link_on) { - new_root_id = card->local_node->node_id; + new_root_id = local_node->node_id; fw_notify("IRM has link off, making local node (%02x) root.\n", new_root_id); goto pick_me; } bmd.lock.arg = cpu_to_be32(0x3f); - bmd.lock.data = cpu_to_be32(card->local_node->node_id); + bmd.lock.data = cpu_to_be32(local_node->node_id); spin_unlock_irqrestore(&card->lock, flags); @@ -267,12 +280,12 @@ fw_card_bm_work(struct work_struct *work) * Another bus reset happened. Just return, * the BM work has been rescheduled. */ - return; + goto out; } if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) /* Somebody else is BM, let them do the work. */ - return; + goto out; spin_lock_irqsave(&card->lock, flags); if (bmd.rcode != RCODE_COMPLETE) { @@ -282,7 +295,7 @@ fw_card_bm_work(struct work_struct *work) * do a bus reset and pick the local node as * root, and thus, IRM. */ - new_root_id = card->local_node->node_id; + new_root_id = local_node->node_id; fw_notify("BM lock failed, making local node (%02x) root.\n", new_root_id); goto pick_me; @@ -295,7 +308,7 @@ fw_card_bm_work(struct work_struct *work) */ spin_unlock_irqrestore(&card->lock, flags); schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); - return; + goto out; } /* @@ -305,20 +318,20 @@ fw_card_bm_work(struct work_struct *work) */ card->bm_generation = generation; - if (root == NULL) { + if (root_device == NULL) { /* * Either link_on is false, or we failed to read the * config rom. In either case, pick another root. */ - new_root_id = card->local_node->node_id; - } else if (atomic_read(&root->state) != FW_DEVICE_RUNNING) { + new_root_id = local_node->node_id; + } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) { /* * If we haven't probed this device yet, bail out now * and let's try again once that's done. */ spin_unlock_irqrestore(&card->lock, flags); - return; - } else if (root->config_rom[2] & BIB_CMC) { + goto out; + } else if (root_device->config_rom[2] & BIB_CMC) { /* * FIXME: I suppose we should set the cmstr bit in the * STATE_CLEAR register of this node, as described in @@ -332,7 +345,7 @@ fw_card_bm_work(struct work_struct *work) * successfully read the config rom, but it's not * cycle master capable. */ - new_root_id = card->local_node->node_id; + new_root_id = local_node->node_id; } pick_me: @@ -341,8 +354,8 @@ fw_card_bm_work(struct work_struct *work) * the typically much larger 1394b beta repeater delays though. */ if (!card->beta_repeaters_present && - card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) - gap_count = gap_count_table[card->root_node->max_hops]; + root_node->max_hops < ARRAY_SIZE(gap_count_table)) + gap_count = gap_count_table[root_node->max_hops]; else gap_count = 63; @@ -364,6 +377,11 @@ fw_card_bm_work(struct work_struct *work) fw_send_phy_config(card, new_root_id, generation, gap_count); fw_core_initiate_bus_reset(card, 1); } + out: + if (root_device) + fw_device_put(root_device); + fw_node_put(root_node); + fw_node_put(local_node); } static void @@ -381,6 +399,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, static atomic_t index = ATOMIC_INIT(-1); kref_init(&card->kref); + atomic_set(&card->device_count, 0); card->index = atomic_inc_return(&index); card->driver = driver; card->device = device; @@ -511,8 +530,14 @@ fw_core_remove_card(struct fw_card *card) card->driver = &dummy_driver; fw_destroy_nodes(card); - flush_scheduled_work(); + /* + * Wait for all device workqueue jobs to finish. Otherwise the + * firewire-core module could be unloaded before the jobs ran. + */ + while (atomic_read(&card->device_count) > 0) + msleep(100); + cancel_delayed_work_sync(&card->work); fw_flush_transactions(card); del_timer_sync(&card->flush_timer); diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 2ab13e0f346..870125a3638 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -150,21 +150,10 @@ struct bus_type fw_bus_type = { }; EXPORT_SYMBOL(fw_bus_type); -struct fw_device *fw_device_get(struct fw_device *device) -{ - get_device(&device->device); - - return device; -} - -void fw_device_put(struct fw_device *device) -{ - put_device(&device->device); -} - static void fw_device_release(struct device *dev) { struct fw_device *device = fw_device(dev); + struct fw_card *card = device->card; unsigned long flags; /* @@ -176,9 +165,9 @@ static void fw_device_release(struct device *dev) spin_unlock_irqrestore(&device->card->lock, flags); fw_node_put(device->node); - fw_card_put(device->card); kfree(device->config_rom); kfree(device); + atomic_dec(&card->device_count); } int fw_device_enable_phys_dma(struct fw_device *device) @@ -668,7 +657,8 @@ static void fw_device_init(struct work_struct *work) */ if (read_bus_info_block(device, device->generation) < 0) { - if (device->config_rom_retries < MAX_RETRIES) { + if (device->config_rom_retries < MAX_RETRIES && + atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { device->config_rom_retries++; schedule_delayed_work(&device->work, RETRY_DELAY); } else { @@ -805,7 +795,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) */ device_initialize(&device->device); atomic_set(&device->state, FW_DEVICE_INITIALIZING); - device->card = fw_card_get(card); + atomic_inc(&card->device_count); + device->card = card; device->node = fw_node_get(node); device->node_id = node->node_id; device->generation = card->generation; diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index 43808c02793..78ecd3991b7 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -76,9 +76,21 @@ fw_device_is_shutdown(struct fw_device *device) return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; } -struct fw_device *fw_device_get(struct fw_device *device); +static inline struct fw_device * +fw_device_get(struct fw_device *device) +{ + get_device(&device->device); + + return device; +} + +static inline void +fw_device_put(struct fw_device *device) +{ + put_device(&device->device); +} + struct fw_device *fw_device_get_by_devt(dev_t devt); -void fw_device_put(struct fw_device *device); int fw_device_enable_phys_dma(struct fw_device *device); void fw_device_cdev_update(struct fw_device *device); diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 5259491580f..03069a454c0 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -122,7 +122,6 @@ static const char sbp2_driver_name[] = "sbp2"; struct sbp2_logical_unit { struct sbp2_target *tgt; struct list_head link; - struct scsi_device *sdev; struct fw_address_handler address_handler; struct list_head orb_list; @@ -139,6 +138,7 @@ struct sbp2_logical_unit { int generation; int retries; struct delayed_work work; + bool has_sdev; bool blocked; }; @@ -751,20 +751,34 @@ static void sbp2_unblock(struct sbp2_target *tgt) scsi_unblock_requests(shost); } +static int sbp2_lun2int(u16 lun) +{ + struct scsi_lun eight_bytes_lun; + + memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); + eight_bytes_lun.scsi_lun[0] = (lun >> 8) & 0xff; + eight_bytes_lun.scsi_lun[1] = lun & 0xff; + + return scsilun_to_int(&eight_bytes_lun); +} + static void sbp2_release_target(struct kref *kref) { struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref); struct sbp2_logical_unit *lu, *next; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + struct scsi_device *sdev; + struct fw_device *device = fw_device(tgt->unit->device.parent); /* prevent deadlocks */ sbp2_unblock(tgt); list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { - if (lu->sdev) { - scsi_remove_device(lu->sdev); - scsi_device_put(lu->sdev); + sdev = scsi_device_lookup(shost, 0, 0, sbp2_lun2int(lu->lun)); + if (sdev) { + scsi_remove_device(sdev); + scsi_device_put(sdev); } sbp2_send_management_orb(lu, tgt->node_id, lu->generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); @@ -778,6 +792,7 @@ static void sbp2_release_target(struct kref *kref) put_device(&tgt->unit->device); scsi_host_put(shost); + fw_device_put(device); } static struct workqueue_struct *sbp2_wq; @@ -807,7 +822,6 @@ static void sbp2_login(struct work_struct *work) struct fw_device *device = fw_device(tgt->unit->device.parent); struct Scsi_Host *shost; struct scsi_device *sdev; - struct scsi_lun eight_bytes_lun; struct sbp2_login_response response; int generation, node_id, local_node_id; @@ -820,7 +834,7 @@ static void sbp2_login(struct work_struct *work) local_node_id = device->card->node_id; /* If this is a re-login attempt, log out, or we might be rejected. */ - if (lu->sdev) + if (lu->has_sdev) sbp2_send_management_orb(lu, device->node_id, generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); @@ -859,7 +873,7 @@ static void sbp2_login(struct work_struct *work) sbp2_agent_reset(lu); /* This was a re-login. */ - if (lu->sdev) { + if (lu->has_sdev) { sbp2_cancel_orbs(lu); sbp2_conditionally_unblock(lu); goto out; @@ -868,13 +882,8 @@ static void sbp2_login(struct work_struct *work) if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) ssleep(SBP2_INQUIRY_DELAY); - memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); - eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff; - eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff; shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); - - sdev = __scsi_add_device(shost, 0, 0, - scsilun_to_int(&eight_bytes_lun), lu); + sdev = __scsi_add_device(shost, 0, 0, sbp2_lun2int(lu->lun), lu); /* * FIXME: We are unable to perform reconnects while in sbp2_login(). * Therefore __scsi_add_device() will get into trouble if a bus reset @@ -896,7 +905,8 @@ static void sbp2_login(struct work_struct *work) } /* No error during __scsi_add_device() */ - lu->sdev = sdev; + lu->has_sdev = true; + scsi_device_put(sdev); sbp2_allow_block(lu); goto out; @@ -934,11 +944,11 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) return -ENOMEM; } - lu->tgt = tgt; - lu->sdev = NULL; - lu->lun = lun_entry & 0xffff; - lu->retries = 0; - lu->blocked = false; + lu->tgt = tgt; + lu->lun = lun_entry & 0xffff; + lu->retries = 0; + lu->has_sdev = false; + lu->blocked = false; ++tgt->dont_block; INIT_LIST_HEAD(&lu->orb_list); INIT_DELAYED_WORK(&lu->work, sbp2_login); @@ -1080,6 +1090,8 @@ static int sbp2_probe(struct device *dev) if (scsi_add_host(shost, &unit->device) < 0) goto fail_shost_put; + fw_device_get(device); + /* Initialize to values that won't match anything in our table. */ firmware_revision = 0xff000000; model = 0xff000000; diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 172c1867e9a..e47bb040197 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -383,6 +383,7 @@ void fw_destroy_nodes(struct fw_card *card) card->color++; if (card->local_node != NULL) for_each_fw_node(card, card->local_node, report_lost_node); + card->local_node = NULL; spin_unlock_irqrestore(&card->lock, flags); } diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index fa7967b5740..09cb7287045 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -26,6 +26,7 @@ #include <linux/fs.h> #include <linux/dma-mapping.h> #include <linux/firewire-constants.h> +#include <asm/atomic.h> #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) @@ -219,6 +220,7 @@ extern struct bus_type fw_bus_type; struct fw_card { const struct fw_card_driver *driver; struct device *device; + atomic_t device_count; struct kref kref; int node_id; diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 310e497b583..c8d0e871599 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -670,8 +670,8 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector, * and attempt to recover if there are problems. Returns 0 if everything's * ok; nonzero if the request has been terminated. */ -static -int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) +static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, + int len, int ireason, int rw) { /* * ireason == 0: the drive wants to receive data from us @@ -701,6 +701,9 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) drive->name, __FUNCTION__, ireason); } + if (rq->cmd_type == REQ_TYPE_ATA_PC) + rq->cmd_flags |= REQ_FAILED; + cdrom_end_request(drive, 0); return -1; } @@ -1071,11 +1074,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) /* * check which way to transfer data */ - if (blk_fs_request(rq) || blk_pc_request(rq)) { - if (ide_cd_check_ireason(drive, len, ireason, write)) - return ide_stopped; + if (ide_cd_check_ireason(drive, rq, len, ireason, write)) + return ide_stopped; - if (blk_fs_request(rq) && write == 0) { + if (blk_fs_request(rq)) { + if (write == 0) { int nskip; if (ide_cd_check_transfer_size(drive, len)) { @@ -1101,16 +1104,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (ireason == 0) { write = 1; xferfunc = HWIF(drive)->atapi_output_bytes; - } else if (ireason == 2 || (ireason == 1 && - (blk_fs_request(rq) || blk_pc_request(rq)))) { + } else { write = 0; xferfunc = HWIF(drive)->atapi_input_bytes; - } else { - printk(KERN_ERR "%s: %s: The drive " - "appears confused (ireason = 0x%02x). " - "Trying to recover by ending request.\n", - drive->name, __FUNCTION__, ireason); - goto end_request; } /* @@ -1182,11 +1178,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) else rq->data += blen; } + if (!write && blk_sense_request(rq)) + rq->sense_len += blen; } - if (write && blk_sense_request(rq)) - rq->sense_len += thislen; - /* * pad, if necessary */ @@ -1931,6 +1926,7 @@ static const struct cd_list_entry ide_cd_quirks_list[] = { { "MATSHITADVD-ROM SR-8186", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { "MATSHITADVD-ROM SR-8176", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { "MATSHITADVD-ROM SR-8174", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, + { "Optiarc DVD RW AD-5200A", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { NULL, NULL, 0 } }; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 8f5bed47105..39501d13025 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -867,7 +867,7 @@ static void idedisk_setup (ide_drive_t *drive) /* Only print cache size when it was specified */ if (id->buf_size) - printk (" w/%dKiB Cache", id->buf_size/2); + printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2); printk(KERN_CONT ", CHS=%d/%d/%d\n", drive->bios_cyl, drive->bios_head, drive->bios_sect); @@ -949,7 +949,8 @@ static void ide_device_shutdown(ide_drive_t *drive) return; } - printk("Shutdown: %s\n", drive->name); + printk(KERN_INFO "Shutdown: %s\n", drive->name); + drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); } diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index d0e7b537353..2de99e4be5c 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -1,9 +1,13 @@ /* + * IDE DMA support (including IDE PCI BM-DMA). + * * Copyright (C) 1995-1998 Mark Lord * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2004, 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public License + * + * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). */ /* @@ -11,49 +15,6 @@ */ /* - * This module provides support for the bus-master IDE DMA functions - * of various PCI chipsets, including the Intel PIIX (i82371FB for - * the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and - * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset) - * ("PIIX" stands for "PCI ISA IDE Xcellerator"). - * - * Pretty much the same code works for other IDE PCI bus-mastering chipsets. - * - * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). - * - * By default, DMA support is prepared for use, but is currently enabled only - * for drives which already have DMA enabled (UltraDMA or mode 2 multi/single), - * or which are recognized as "good" (see table below). Drives with only mode0 - * or mode1 (multi/single) DMA should also work with this chipset/driver - * (eg. MC2112A) but are not enabled by default. - * - * Use "hdparm -i" to view modes supported by a given drive. - * - * The hdparm-3.5 (or later) utility can be used for manually enabling/disabling - * DMA support, but must be (re-)compiled against this kernel version or later. - * - * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting. - * If problems arise, ide.c will disable DMA operation after a few retries. - * This error recovery mechanism works and has been extremely well exercised. - * - * IDE drives, depending on their vintage, may support several different modes - * of DMA operation. The boot-time modes are indicated with a "*" in - * the "hdparm -i" listing, and can be changed with *knowledgeable* use of - * the "hdparm -X" feature. There is seldom a need to do this, as drives - * normally power-up with their "best" PIO/DMA modes enabled. - * - * Testing has been done with a rather extensive number of drives, - * with Quantum & Western Digital models generally outperforming the pack, - * and Fujitsu & Conner (and some Seagate which are really Conner) drives - * showing more lackluster throughput. - * - * Keep an eye on /var/adm/messages for "DMA disabled" messages. - * - * Some people have reported trouble with Intel Zappa motherboards. - * This can be fixed by upgrading the AMI BIOS to version 1.00.04.BS0, - * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe - * (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this). - * * Thanks to "Christopher J. Reimer" <reimer@doe.carleton.ca> for * fixing the problem with the BIOS on some Acer motherboards. * @@ -65,11 +26,6 @@ * * Most importantly, thanks to Robert Bringman <rob@mars.trion.com> * for supplying a Promise UDMA board & WD UDMA drive for this work! - * - * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports. - * - * ATA-66/100 and recovery functions, I forgot the rest...... - * */ #include <linux/module.h> diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 4a2cb286822..194ecb0049e 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -756,7 +756,8 @@ static int ide_probe_port(ide_hwif_t *hwif) BUG_ON(hwif->present); - if (hwif->noprobe) + if (hwif->noprobe || + (hwif->drives[0].noprobe && hwif->drives[1].noprobe)) return -EACCES; /* diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0598ecfd5f3..43e0e055777 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -3765,6 +3765,11 @@ static int ide_tape_probe(ide_drive_t *drive) g->fops = &idetape_block_ops; ide_register_region(g); + printk(KERN_WARNING "It is possible that this driver does not have any" + " users anymore and, as a result, it will be REMOVED soon." + " Please notify Bart <bzolnier@gmail.com> or Boris" + " <petkovbb@gmail.com> in case you still need it.\n"); + return 0; out_free_tape: diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 477833f0daf..fa16bc30bbc 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -590,11 +590,6 @@ void ide_unregister(unsigned int index, int init_default, int restore) hwif->extra_ports = 0; } - /* - * Note that we only release the standard ports, - * and do not even try to handle any extra ports - * allocated for weird IDE interface chipsets. - */ ide_hwif_release_regions(hwif); /* copy original settings */ @@ -1036,10 +1031,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device drive->nice1 = (arg >> IDE_NICE_1) & 1; return 0; case HDIO_DRIVE_RESET: - { - unsigned long flags; - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + /* * Abort the current command on the * group if there is one, taking @@ -1058,17 +1052,15 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device ide_abort(drive, "drive reset"); BUG_ON(HWGROUP(drive)->handler); - + /* Ensure nothing gets queued after we drop the lock. Reset will clear the busy */ - + HWGROUP(drive)->busy = 1; spin_unlock_irqrestore(&ide_lock, flags); (void) ide_do_reset(drive); return 0; - } - case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -1449,7 +1441,7 @@ static int __init ide_setup(char *s) case -1: /* "noprobe" */ hwif->noprobe = 1; - goto done; + goto obsolete_option; case 1: /* base */ vals[1] = vals[0] + 0x206; /* default ctl */ diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index bba29df5f21..2f4f47ad602 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -334,43 +334,6 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif) hwif->drives[1].drive_data = t2; } -/* - * qd_unsetup: - * - * called to unsetup an ata channel : back to default values, unlinks tuning - */ -/* -static void __exit qd_unsetup(ide_hwif_t *hwif) -{ - u8 config = hwif->config_data; - int base = hwif->select_data; - void *set_pio_mode = (void *)hwif->set_pio_mode; - - if (hwif->chipset != ide_qd65xx) - return; - - printk(KERN_NOTICE "%s: back to defaults\n", hwif->name); - - hwif->selectproc = NULL; - hwif->set_pio_mode = NULL; - - if (set_pio_mode == (void *)qd6500_set_pio_mode) { - // will do it for both - outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - } else if (set_pio_mode == (void *)qd6580_set_pio_mode) { - if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) { - outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1])); - } else { - outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - } - } else { - printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n"); - printk(KERN_WARNING "keeping settings !\n"); - } -} -*/ - static const struct ide_port_info qd65xx_port_info __initdata = { .chipset = ide_qd65xx, .host_flags = IDE_HFLAG_IO_32BIT | @@ -444,6 +407,8 @@ static int __init qd_probe(int base) printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n", config, control, QD_ID3); + outb(QD_DEF_CONTR, QD_CONTROL_PORT); + if (control & QD_CONTR_SEC_DISABLED) { /* secondary disabled */ @@ -460,8 +425,6 @@ static int __init qd_probe(int base) ide_device_add(idx, &qd65xx_port_info); - outb(QD_DEF_CONTR, QD_CONTROL_PORT); - return 1; } else { ide_hwif_t *mate; @@ -487,8 +450,6 @@ static int __init qd_probe(int base) ide_device_add(idx, &qd65xx_port_info); - outb(QD_DEF_CONTR, QD_CONTROL_PORT); - return 0; /* no other qd65xx possible */ } } diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index bd24dad3cfc..ec667982809 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -787,7 +787,8 @@ static int __init cmd640x_init(void) /* * Try to enable the secondary interface, if not already enabled */ - if (cmd_hwif1->noprobe) { + if (cmd_hwif1->noprobe || + (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe)) { port2 = "not probed"; } else { b = get_cmd640_reg(CNTRL); diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index d0f7bb8b8ad..6357bb6269a 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1570,10 +1570,12 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic if (rev < 3) info = &hpt36x; else { - static const struct hpt_info *hpt37x_info[] = - { &hpt370, &hpt370a, &hpt372, &hpt372n }; - - info = hpt37x_info[min_t(u8, rev, 6) - 3]; + switch (min_t(u8, rev, 6)) { + case 3: info = &hpt370; break; + case 4: info = &hpt370a; break; + case 5: info = &hpt372; break; + case 6: info = &hpt372n; break; + } idx++; } break; @@ -1626,7 +1628,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic return ide_setup_pci_device(dev, &d); } -static const struct pci_device_id hpt366_pci_tbl[] = { +static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), 0 }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), 1 }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), 2 }, diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c index 73bfd1656f8..b8797c66676 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_mem.c +++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c @@ -136,14 +136,8 @@ int build_phys_page_list(struct ib_phys_buf *buffer_list, /* Find largest page shift we can use to cover buffers */ for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift)) - if (num_phys_buf > 1) { - if ((1ULL << *shift) & mask) - break; - } else - if (1ULL << *shift >= - buffer_list[0].size + - (buffer_list[0].addr & ((1ULL << *shift) - 1))) - break; + if ((1ULL << *shift) & mask) + break; buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1); buffer_list[0].addr &= ~0ull << *shift; diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 7f8853b44ee..b2112f5a422 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -567,12 +567,12 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i /* Init the adapter */ nesdev->nesadapter = nes_init_adapter(nesdev, hw_rev); - nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; if (!nesdev->nesadapter) { printk(KERN_ERR PFX "Unable to initialize adapter.\n"); ret = -ENOMEM; goto bail5; } + nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; /* nesdev->base_doorbell_index = nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */ diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index fd57e8a1582..a48b288618e 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -285,6 +285,21 @@ struct nes_device { }; +static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad) +{ + u32 crc_value; + crc_value = crc32c(~0, (void *)nes_quad, sizeof (struct nes_v4_quad)); + + /* + * With commit ef19454b ("[LIB] crc32c: Keep intermediate crc + * state in cpu order"), behavior of crc32c changes on + * big-endian platforms. Our algorithm expects the previous + * behavior; otherwise we have RDMA connection establishment + * issue on big-endian. + */ + return cpu_to_le32(crc_value); +} + static inline void set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value) { diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index bd5cfeaac20..39adb267fb1 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -370,11 +370,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, int ret = 0; u32 was_timer_set; + if (!cm_node) + return -EINVAL; new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); if (!new_send) return -1; - if (!cm_node) - return -EINVAL; /* new_send->timetosend = currenttime */ new_send->retrycount = NES_DEFAULT_RETRYS; @@ -947,6 +947,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener); kfree(listener); + listener = NULL; ret = 0; cm_listens_destroyed++; } else { @@ -2319,6 +2320,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct iw_cm_event cm_event; struct nes_hw_qp_wqe *wqe; struct nes_v4_quad nes_quad; + u32 crc_value; int ret; ibqp = nes_get_qp(cm_id->device, conn_param->qpn); @@ -2435,8 +2437,8 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; /* Produce hash key */ - nesqp->hte_index = cpu_to_be32( - crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); + crc_value = get_crc_value(&nes_quad); + nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n", nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask); @@ -2750,6 +2752,7 @@ void cm_event_connected(struct nes_cm_event *event) struct iw_cm_event cm_event; struct nes_hw_qp_wqe *wqe; struct nes_v4_quad nes_quad; + u32 crc_value; int ret; /* get all our handles */ @@ -2827,8 +2830,8 @@ void cm_event_connected(struct nes_cm_event *event) nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; /* Produce hash key */ - nesqp->hte_index = cpu_to_be32( - crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); + crc_value = get_crc_value(&nes_quad); + nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n", nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask); diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 7c4c0fbf0ab..49e53e4c1eb 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -156,15 +156,14 @@ static void nes_nic_tune_timer(struct nes_device *nesdev) spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); - if (shared_timer->cq_count_old < cq_count) { - if (cq_count > shared_timer->threshold_low) - shared_timer->cq_direction_downward=0; - } - if (shared_timer->cq_count_old >= cq_count) + if (shared_timer->cq_count_old <= cq_count) + shared_timer->cq_direction_downward = 0; + else shared_timer->cq_direction_downward++; shared_timer->cq_count_old = cq_count; if (shared_timer->cq_direction_downward > NES_NIC_CQ_DOWNWARD_TREND) { - if (cq_count <= shared_timer->threshold_low) { + if (cq_count <= shared_timer->threshold_low && + shared_timer->threshold_low > 4) { shared_timer->threshold_low = shared_timer->threshold_low/2; shared_timer->cq_direction_downward=0; nesdev->currcq_count = 0; @@ -1728,7 +1727,6 @@ int nes_napi_isr(struct nes_device *nesdev) nesdev->int_req &= ~NES_INT_TIMER; nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); - nesadapter->tune_timer.timer_in_use_old = 0; } nesdev->deepcq_count = 0; return 1; @@ -1867,7 +1865,6 @@ void nes_dpc(unsigned long param) nesdev->int_req &= ~NES_INT_TIMER; nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); - nesdev->nesadapter->tune_timer.timer_in_use_old = 0; } else { nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); } diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 1e10df550c9..b7e2844f096 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -962,7 +962,7 @@ struct nes_arp_entry { #define DEFAULT_JUMBO_NES_QL_LOW 12 #define DEFAULT_JUMBO_NES_QL_TARGET 40 #define DEFAULT_JUMBO_NES_QL_HIGH 128 -#define NES_NIC_CQ_DOWNWARD_TREND 8 +#define NES_NIC_CQ_DOWNWARD_TREND 16 struct nes_hw_tune_timer { //u16 cq_count; diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 4dafbe16e82..a651e9d9f0e 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -929,7 +929,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, NES_MAX_USER_DB_REGIONS, nesucontext->first_free_db); nes_debug(NES_DBG_PD, "find_first_zero_biton doorbells returned %u, mapping pd_id %u.\n", nespd->mmap_db_index, nespd->pd_id); - if (nespd->mmap_db_index > NES_MAX_USER_DB_REGIONS) { + if (nespd->mmap_db_index >= NES_MAX_USER_DB_REGIONS) { nes_debug(NES_DBG_PD, "mmap_db_index > MAX\n"); nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num); kfree(nespd); @@ -1327,7 +1327,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, (long long unsigned int)req.user_wqe_buffers); nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); kfree(nesqp->allocated_buffer); - return ERR_PTR(-ENOMEM); + return ERR_PTR(-EFAULT); } } @@ -1674,6 +1674,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, } nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n", (unsigned long)req.user_cq_buffer, entries); + err = 1; list_for_each_entry(nespbl, &nes_ucontext->cq_reg_mem_list, list) { if (nespbl->user_base == (unsigned long )req.user_cq_buffer) { list_del(&nespbl->list); @@ -1686,7 +1687,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, if (err) { nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); kfree(nescq); - return ERR_PTR(err); + return ERR_PTR(-EFAULT); } pbl_entries = nespbl->pbl_size >> 3; @@ -1831,9 +1832,6 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, spin_unlock_irqrestore(&nesdev->cqp.lock, flags); } } - nes_debug(NES_DBG_CQ, "iWARP CQ%u create timeout expired, major code = 0x%04X," - " minor code = 0x%04X\n", - nescq->hw_cq.cq_number, cqp_request->major_code, cqp_request->minor_code); if (!context) pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, nescq->hw_cq.cq_pbase); diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 0c303c84b37..6b6df867958 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -632,8 +632,7 @@ mpt_deregister(u8 cb_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_event_register - Register protocol-specific event callback - * handler. + * mpt_event_register - Register protocol-specific event callback handler. * @cb_idx: previously registered (via mpt_register) callback handle * @ev_cbfunc: callback function * @@ -654,8 +653,7 @@ mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_event_deregister - Deregister protocol-specific event callback - * handler. + * mpt_event_deregister - Deregister protocol-specific event callback handler * @cb_idx: previously registered callback handle * * Each protocol-specific driver should call this routine @@ -765,11 +763,13 @@ mpt_device_driver_deregister(u8 cb_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024) - * allocated per MPT adapter. + * mpt_get_msg_frame - Obtain an MPT request frame from the pool * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * + * Obtain an MPT request frame from the pool (of 1024) that are + * allocated per MPT adapter. + * * Returns pointer to a MPT request frame or %NULL if none are available * or IOC is not active. */ @@ -834,13 +834,12 @@ mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_put_msg_frame - Send a protocol specific MPT request frame - * to a IOC. + * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @mf: Pointer to MPT request frame * - * This routine posts a MPT request frame to the request post FIFO of a + * This routine posts an MPT request frame to the request post FIFO of a * specific MPT adapter. */ void @@ -868,13 +867,15 @@ mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) } /** - * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame - * to a IOC using hi priority request queue. + * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @mf: Pointer to MPT request frame * - * This routine posts a MPT request frame to the request post FIFO of a + * Send a protocol-specific MPT request frame to an IOC using + * hi-priority request queue. + * + * This routine posts an MPT request frame to the request post FIFO of a * specific MPT adapter. **/ void diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index af1de0ccee2..0c252f60c4c 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1533,7 +1533,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) * * Remark: Currently invoked from a non-interrupt thread (_bh). * - * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC + * Note: With old EH code, at most 1 SCSI TaskMgmt function per IOC * will be active. * * Returns 0 for SUCCESS, or %FAILED. @@ -2537,14 +2537,12 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR /** * mptscsih_get_scsi_lookup - * - * retrieves scmd entry from ScsiLookup[] array list - * * @ioc: Pointer to MPT_ADAPTER structure * @i: index into the array * - * Returns the scsi_cmd pointer + * retrieves scmd entry from ScsiLookup[] array list * + * Returns the scsi_cmd pointer **/ static struct scsi_cmnd * mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i) @@ -2561,14 +2559,12 @@ mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i) /** * mptscsih_getclear_scsi_lookup - * - * retrieves and clears scmd entry from ScsiLookup[] array list - * * @ioc: Pointer to MPT_ADAPTER structure * @i: index into the array * - * Returns the scsi_cmd pointer + * retrieves and clears scmd entry from ScsiLookup[] array list * + * Returns the scsi_cmd pointer **/ static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f337800076c..a0f0e605d63 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -90,6 +90,11 @@ config MACVLAN This allows one to create virtual interfaces that map packets to or from specific MAC addresses to a particular interface. + Macvlan devices can be added using the "ip" command from the + iproute2 package starting with the iproute2-2.6.23 release: + + "ip link add link <real dev> [ address MAC ] [ NAME ] type macvlan" + To compile this driver as a module, choose M here: the module will be called macvlan. @@ -2363,6 +2368,7 @@ config GELIC_NET config GELIC_WIRELESS bool "PS3 Wireless support" depends on GELIC_NET + select WIRELESS_EXT help This option adds the support for the wireless feature of PS3. If you have the wireless-less model of PS3 or have no plan to diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index afc7f34b1dc..8af142ccf37 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -1,6 +1,6 @@ /* bnx2x.c: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -10,13 +10,13 @@ * Based on code from Michael Chan's bnx2 driver * UDP CSUM errata workaround by Arik Gendelman * Slowpath rework by Vladislav Zolotarov - * Statistics and Link managment by Yitchak Gertner + * Statistics and Link management by Yitchak Gertner * */ /* define this to make the driver freeze on error * to allow getting debug info - * (you will need to reboot afterwords) + * (you will need to reboot afterwards) */ /*#define BNX2X_STOP_ON_ERROR*/ @@ -63,22 +63,21 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "0.40.15" -#define DRV_MODULE_RELDATE "$DateTime: 2007/11/15 07:28:37 $" -#define BNX2X_BC_VER 0x040009 +#define DRV_MODULE_VERSION "1.40.22" +#define DRV_MODULE_RELDATE "2007/11/27" +#define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (5*HZ) static char version[] __devinitdata = - "Broadcom NetXtreme II 577xx 10Gigabit Ethernet Driver " + "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>"); MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); -MODULE_INFO(cvs_version, "$Revision: #356 $"); static int use_inta; static int poll; @@ -94,8 +93,8 @@ module_param(debug, int, 0); MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X"); MODULE_PARM_DESC(poll, "use polling (for debug)"); MODULE_PARM_DESC(onefunc, "enable only first function"); -MODULE_PARM_DESC(nomcp, "ignore managment CPU (Implies onefunc)"); -MODULE_PARM_DESC(debug, "defualt debug msglevel"); +MODULE_PARM_DESC(nomcp, "ignore management CPU (Implies onefunc)"); +MODULE_PARM_DESC(debug, "default debug msglevel"); #ifdef BNX2X_MULTI module_param(use_multi, int, 0); @@ -298,8 +297,7 @@ static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) static int bnx2x_mc_assert(struct bnx2x *bp) { - int i, j; - int rc = 0; + int i, j, rc = 0; char last_idx; const char storm[] = {"XTCU"}; const u32 intmem_base[] = { @@ -313,8 +311,9 @@ static int bnx2x_mc_assert(struct bnx2x *bp) for (i = 0; i < 4; i++) { last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET + intmem_base[i]); - BNX2X_ERR("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n", - storm[i], last_idx); + if (last_idx) + BNX2X_LOG("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n", + storm[i], last_idx); /* print the asserts */ for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) { @@ -330,7 +329,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp) intmem_base[i]); if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) { - BNX2X_ERR("DATA %cSTORM_ASSERT_INDEX 0x%x =" + BNX2X_LOG("DATA %cSTORM_ASSERT_INDEX 0x%x =" " 0x%08x 0x%08x 0x%08x 0x%08x\n", storm[i], j, row3, row2, row1, row0); rc++; @@ -341,6 +340,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp) } return rc; } + static void bnx2x_fw_dump(struct bnx2x *bp) { u32 mark, offset; @@ -348,21 +348,22 @@ static void bnx2x_fw_dump(struct bnx2x *bp) int word; mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104); - printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark); + mark = ((mark + 0x3) & ~0x3); + printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark); for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + offset + 4*word)); data[8] = 0x0; - printk(KERN_ERR PFX "%s", (char *)data); + printk(KERN_CONT "%s", (char *)data); } for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + offset + 4*word)); data[8] = 0x0; - printk(KERN_ERR PFX "%s", (char *)data); + printk(KERN_CONT "%s", (char *)data); } printk("\n" KERN_ERR PFX "end of fw dump\n"); } @@ -427,10 +428,10 @@ static void bnx2x_panic_dump(struct bnx2x *bp) } } - BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_t_idx(%u)" - " def_x_idx(%u) def_att_idx(%u) attn_state(%u)" + BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)" + " def_t_idx(%u) def_att_idx(%u) attn_state(%u)" " spq_prod_idx(%u)\n", - bp->def_c_idx, bp->def_u_idx, bp->def_t_idx, bp->def_x_idx, + bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx, bp->def_att_idx, bp->attn_state, bp->spq_prod_idx); @@ -441,7 +442,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); } -static void bnx2x_enable_int(struct bnx2x *bp) +static void bnx2x_int_enable(struct bnx2x *bp) { int port = bp->port; u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -454,18 +455,26 @@ static void bnx2x_enable_int(struct bnx2x *bp) HC_CONFIG_0_REG_ATTN_BIT_EN_0); } else { val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | + HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | HC_CONFIG_0_REG_INT_LINE_EN_0 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); + + /* Errata A0.158 workaround */ + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n", + val, port, addr, msix); + + REG_WR(bp, addr, val); + val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; } - DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) msi %d\n", + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n", val, port, addr, msix); REG_WR(bp, addr, val); } -static void bnx2x_disable_int(struct bnx2x *bp) +static void bnx2x_int_disable(struct bnx2x *bp) { int port = bp->port; u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -484,15 +493,15 @@ static void bnx2x_disable_int(struct bnx2x *bp) BNX2X_ERR("BUG! proper val not read from IGU!\n"); } -static void bnx2x_disable_int_sync(struct bnx2x *bp) +static void bnx2x_int_disable_sync(struct bnx2x *bp) { int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; int i; atomic_inc(&bp->intr_sem); - /* prevent the HW from sending interrupts*/ - bnx2x_disable_int(bp); + /* prevent the HW from sending interrupts */ + bnx2x_int_disable(bp); /* make sure all ISRs are done */ if (msix) { @@ -775,6 +784,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp, mb(); /* force bnx2x_wait_ramrod to see the change */ return; } + switch (command | bp->state) { case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT): DP(NETIF_MSG_IFUP, "got setup ramrod\n"); @@ -787,20 +797,20 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp, fp->state = BNX2X_FP_STATE_HALTED; break; - case (RAMROD_CMD_ID_ETH_PORT_DEL | BNX2X_STATE_CLOSING_WAIT4_DELETE): - DP(NETIF_MSG_IFDOWN, "got delete ramrod\n"); - bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; - break; - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid); - bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_DELETED; + DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", + cid); + bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; break; case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); break; + case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n"); + break; + default: BNX2X_ERR("unexpected ramrod (%d) state is %x\n", command, bp->state); @@ -1179,12 +1189,175 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) return val; } +static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource) +{ + u32 cnt; + u32 lock_status; + u32 resource_bit = (1 << resource); + u8 func = bp->port; + + /* Validating that the resource is within range */ + if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { + DP(NETIF_MSG_HW, + "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", + resource, HW_LOCK_MAX_RESOURCE_VALUE); + return -EINVAL; + } + + /* Validating that the resource is not already taken */ + lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8); + if (lock_status & resource_bit) { + DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", + lock_status, resource_bit); + return -EEXIST; + } + + /* Try for 1 second every 5ms */ + for (cnt = 0; cnt < 200; cnt++) { + /* Try to acquire the lock */ + REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8 + 4, + resource_bit); + lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8); + if (lock_status & resource_bit) + return 0; + + msleep(5); + } + DP(NETIF_MSG_HW, "Timeout\n"); + return -EAGAIN; +} + +static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource) +{ + u32 lock_status; + u32 resource_bit = (1 << resource); + u8 func = bp->port; + + /* Validating that the resource is within range */ + if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { + DP(NETIF_MSG_HW, + "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", + resource, HW_LOCK_MAX_RESOURCE_VALUE); + return -EINVAL; + } + + /* Validating that the resource is currently taken */ + lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8); + if (!(lock_status & resource_bit)) { + DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", + lock_status, resource_bit); + return -EFAULT; + } + + REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8, resource_bit); + return 0; +} + +static int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode) +{ + /* The GPIO should be swapped if swap register is set and active */ + int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && + REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port; + int gpio_shift = gpio_num + + (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); + u32 gpio_mask = (1 << gpio_shift); + u32 gpio_reg; + + if (gpio_num > MISC_REGISTERS_GPIO_3) { + BNX2X_ERR("Invalid GPIO %d\n", gpio_num); + return -EINVAL; + } + + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); + /* read GPIO and mask except the float bits */ + gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT); + + switch (mode) { + case MISC_REGISTERS_GPIO_OUTPUT_LOW: + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n", + gpio_num, gpio_shift); + /* clear FLOAT and set CLR */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS); + break; + + case MISC_REGISTERS_GPIO_OUTPUT_HIGH: + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n", + gpio_num, gpio_shift); + /* clear FLOAT and set SET */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS); + break; + + case MISC_REGISTERS_GPIO_INPUT_HI_Z : + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n", + gpio_num, gpio_shift); + /* set FLOAT */ + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + break; + + default: + break; + } + + REG_WR(bp, MISC_REG_GPIO, gpio_reg); + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO); + + return 0; +} + +static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) +{ + u32 spio_mask = (1 << spio_num); + u32 spio_reg; + + if ((spio_num < MISC_REGISTERS_SPIO_4) || + (spio_num > MISC_REGISTERS_SPIO_7)) { + BNX2X_ERR("Invalid SPIO %d\n", spio_num); + return -EINVAL; + } + + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); + /* read SPIO and mask except the float bits */ + spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT); + + switch (mode) { + case MISC_REGISTERS_SPIO_OUTPUT_LOW : + DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num); + /* clear FLOAT and set CLR */ + spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS); + break; + + case MISC_REGISTERS_SPIO_OUTPUT_HIGH : + DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num); + /* clear FLOAT and set SET */ + spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS); + break; + + case MISC_REGISTERS_SPIO_INPUT_HI_Z: + DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num); + /* set FLOAT */ + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + break; + + default: + break; + } + + REG_WR(bp, MISC_REG_SPIO, spio_reg); + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO); + + return 0; +} + static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val) { - int rc; - u32 tmp, i; int port = bp->port; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 tmp; + int i, rc; /* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x val 0x%08x\n", bp->phy_addr, reg, val); */ @@ -1236,8 +1409,8 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val) { int port = bp->port; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 val, i; - int rc; + u32 val; + int i, rc; if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { @@ -1286,58 +1459,54 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val) return rc; } -static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val) +static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl, + u32 phy_addr, u32 reg, u32 addr, u32 val) { - int rc = 0; - u32 tmp, i; - int port = bp->port; - u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { - - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - tmp &= ~EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); - REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - udelay(40); - } + u32 tmp; + int i, rc = 0; - /* set clause 45 mode */ - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - tmp |= EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + /* set clause 45 mode, slow down the MDIO clock to 2.5MHz + * (a value of 49==0x31) and make sure that the AUTO poll is off + */ + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + tmp &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT); + tmp |= (EMAC_MDIO_MODE_CLAUSE_45 | + (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); + REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); /* address */ - tmp = ((bp->phy_addr << 21) | (reg << 16) | addr | + tmp = ((phy_addr << 21) | (reg << 16) | addr | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; } } - if (tmp & EMAC_MDIO_COMM_START_BUSY) { BNX2X_ERR("write phy register failed\n"); rc = -EBUSY; + } else { /* data */ - tmp = ((bp->phy_addr << 21) | (reg << 16) | val | + tmp = ((phy_addr << 21) | (reg << 16) | val | EMAC_MDIO_COMM_COMMAND_WRITE_45 | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -1351,75 +1520,78 @@ static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val) } } - /* unset clause 45 mode */ - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - tmp &= ~EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); - - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { - - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + /* unset clause 45 mode, set the MDIO clock to a faster value + * (0x13 => 6.25Mhz) and restore the AUTO poll if needed + */ + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + tmp &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT); + tmp |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) tmp |= EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); - } + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); return rc; } -static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr, - u32 *ret_val) +static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg, + u32 addr, u32 val) { - int port = bp->port; - u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 val, i; - int rc = 0; + u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr, + reg, addr, val); +} - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - val &= ~EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); - REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - udelay(40); - } +static int bnx2x_mdio45_ctrl_read(struct bnx2x *bp, u32 mdio_ctrl, + u32 phy_addr, u32 reg, u32 addr, + u32 *ret_val) +{ + u32 val; + int i, rc = 0; - /* set clause 45 mode */ - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - val |= EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + /* set clause 45 mode, slow down the MDIO clock to 2.5MHz + * (a value of 49==0x31) and make sure that the AUTO poll is off + */ + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + val &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT); + val |= (EMAC_MDIO_MODE_CLAUSE_45 | + (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); + REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); /* address */ - val = ((bp->phy_addr << 21) | (reg << 16) | addr | + val = ((phy_addr << 21) | (reg << 16) | addr | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; } } - if (val & EMAC_MDIO_COMM_START_BUSY) { BNX2X_ERR("read phy register failed\n"); *ret_val = 0; rc = -EBUSY; + } else { /* data */ - val = ((bp->phy_addr << 21) | (reg << 16) | + val = ((phy_addr << 21) | (reg << 16) | EMAC_MDIO_COMM_COMMAND_READ_45 | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { val &= EMAC_MDIO_COMM_DATA; break; @@ -1436,31 +1608,39 @@ static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr, *ret_val = val; } - /* unset clause 45 mode */ - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - val &= ~EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); - - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { - - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + /* unset clause 45 mode, set the MDIO clock to a faster value + * (0x13 => 6.25Mhz) and restore the AUTO poll if needed + */ + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + val &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT); + val |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) val |= EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); - } + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); return rc; } -static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val) +static int bnx2x_mdio45_read(struct bnx2x *bp, u32 phy_addr, u32 reg, + u32 addr, u32 *ret_val) +{ + u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + + return bnx2x_mdio45_ctrl_read(bp, emac_base, phy_addr, + reg, addr, ret_val); +} + +static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 phy_addr, u32 reg, + u32 addr, u32 val) { int i; u32 rd_val; might_sleep(); for (i = 0; i < 10; i++) { - bnx2x_mdio45_write(bp, reg, addr, val); + bnx2x_mdio45_write(bp, phy_addr, reg, addr, val); msleep(5); - bnx2x_mdio45_read(bp, reg, addr, &rd_val); + bnx2x_mdio45_read(bp, phy_addr, reg, addr, &rd_val); /* if the read value is not the same as the value we wrote, we should write it again */ if (rd_val == val) @@ -1471,18 +1651,81 @@ static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val) } /* - * link managment + * link management */ +static void bnx2x_pause_resolve(struct bnx2x *bp, u32 pause_result) +{ + switch (pause_result) { /* ASYM P ASYM P */ + case 0xb: /* 1 0 1 1 */ + bp->flow_ctrl = FLOW_CTRL_TX; + break; + + case 0xe: /* 1 1 1 0 */ + bp->flow_ctrl = FLOW_CTRL_RX; + break; + + case 0x5: /* 0 1 0 1 */ + case 0x7: /* 0 1 1 1 */ + case 0xd: /* 1 1 0 1 */ + case 0xf: /* 1 1 1 1 */ + bp->flow_ctrl = FLOW_CTRL_BOTH; + break; + + default: + break; + } +} + +static u8 bnx2x_ext_phy_resove_fc(struct bnx2x *bp) +{ + u32 ext_phy_addr; + u32 ld_pause; /* local */ + u32 lp_pause; /* link partner */ + u32 an_complete; /* AN complete */ + u32 pause_result; + u8 ret = 0; + + ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + + /* read twice */ + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_STATUS, &an_complete); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_STATUS, &an_complete); + + if (an_complete & EXT_PHY_KR_AUTO_NEG_COMPLETE) { + ret = 1; + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_AUTO_NEG_ADVERT, &ld_pause); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_LP_AUTO_NEG, &lp_pause); + pause_result = (ld_pause & + EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 8; + pause_result |= (lp_pause & + EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 10; + DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n", + pause_result); + bnx2x_pause_resolve(bp, pause_result); + } + return ret; +} + static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status) { - u32 ld_pause; /* local driver */ - u32 lp_pause; /* link partner */ + u32 ld_pause; /* local driver */ + u32 lp_pause; /* link partner */ u32 pause_result; bp->flow_ctrl = 0; - /* reolve from gp_status in case of AN complete and not sgmii */ + /* resolve from gp_status in case of AN complete and not sgmii */ if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) && (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && (!(bp->phy_flags & PHY_SGMII_FLAG)) && @@ -1499,45 +1742,57 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status) pause_result |= (lp_pause & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result); + bnx2x_pause_resolve(bp, pause_result); + } else if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) || + !(bnx2x_ext_phy_resove_fc(bp))) { + /* forced speed */ + if (bp->req_autoneg & AUTONEG_FLOW_CTRL) { + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + if (bp->dev->mtu <= 4500) + bp->flow_ctrl = FLOW_CTRL_BOTH; + else + bp->flow_ctrl = FLOW_CTRL_TX; + break; - switch (pause_result) { /* ASYM P ASYM P */ - case 0xb: /* 1 0 1 1 */ - bp->flow_ctrl = FLOW_CTRL_TX; - break; - - case 0xe: /* 1 1 1 0 */ - bp->flow_ctrl = FLOW_CTRL_RX; - break; + case FLOW_CTRL_TX: + bp->flow_ctrl = FLOW_CTRL_TX; + break; - case 0x5: /* 0 1 0 1 */ - case 0x7: /* 0 1 1 1 */ - case 0xd: /* 1 1 0 1 */ - case 0xf: /* 1 1 1 1 */ - bp->flow_ctrl = FLOW_CTRL_BOTH; - break; + case FLOW_CTRL_RX: + if (bp->dev->mtu <= 4500) + bp->flow_ctrl = FLOW_CTRL_RX; + break; - default: - break; - } + case FLOW_CTRL_BOTH: + if (bp->dev->mtu <= 4500) + bp->flow_ctrl = FLOW_CTRL_BOTH; + else + bp->flow_ctrl = FLOW_CTRL_TX; + break; - } else { /* forced mode */ - switch (bp->req_flow_ctrl) { - case FLOW_CTRL_AUTO: - if (bp->dev->mtu <= 4500) - bp->flow_ctrl = FLOW_CTRL_BOTH; - else - bp->flow_ctrl = FLOW_CTRL_TX; - break; + case FLOW_CTRL_NONE: + default: + break; + } + } else { /* forced mode */ + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while" + " req_autoneg 0x%x\n", + bp->req_flow_ctrl, bp->req_autoneg); + break; - case FLOW_CTRL_TX: - case FLOW_CTRL_RX: - case FLOW_CTRL_BOTH: - bp->flow_ctrl = bp->req_flow_ctrl; - break; + case FLOW_CTRL_TX: + case FLOW_CTRL_RX: + case FLOW_CTRL_BOTH: + bp->flow_ctrl = bp->req_flow_ctrl; + break; - case FLOW_CTRL_NONE: - default: - break; + case FLOW_CTRL_NONE: + default: + break; + } } } DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl); @@ -1548,9 +1803,9 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status) bp->link_status = 0; if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { - DP(NETIF_MSG_LINK, "link up\n"); + DP(NETIF_MSG_LINK, "phy link up\n"); - bp->link_up = 1; + bp->phy_link_up = 1; bp->link_status |= LINK_STATUS_LINK_UP; if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) @@ -1659,20 +1914,20 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status) bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED; } else { /* link_down */ - DP(NETIF_MSG_LINK, "link down\n"); + DP(NETIF_MSG_LINK, "phy link down\n"); - bp->link_up = 0; + bp->phy_link_up = 0; bp->line_speed = 0; bp->duplex = DUPLEX_FULL; bp->flow_ctrl = 0; } - DP(NETIF_MSG_LINK, "gp_status 0x%x link_up %d\n" + DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %d\n" DP_LEVEL " line_speed %d duplex %d flow_ctrl 0x%x" " link_status 0x%x\n", - gp_status, bp->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl, - bp->link_status); + gp_status, bp->phy_link_up, bp->line_speed, bp->duplex, + bp->flow_ctrl, bp->link_status); } static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g) @@ -1680,40 +1935,40 @@ static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g) int port = bp->port; /* first reset all status - * we asume only one line will be change at a time */ + * we assume only one line will be change at a time */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_XGXS0_LINK_STATUS | - NIG_SERDES0_LINK_STATUS | - NIG_STATUS_INTERRUPT_XGXS0_LINK10G)); - if (bp->link_up) { + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS)); + if (bp->phy_link_up) { if (is_10g) { /* Disable the 10G link interrupt * by writing 1 to the status register */ - DP(NETIF_MSG_LINK, "10G XGXS link up\n"); + DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); bnx2x_bits_en(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_INTERRUPT_XGXS0_LINK10G); + NIG_STATUS_XGXS0_LINK10G); } else if (bp->phy_flags & PHY_XGXS_FLAG) { /* Disable the link interrupt * by writing 1 to the relevant lane * in the status register */ - DP(NETIF_MSG_LINK, "1G XGXS link up\n"); + DP(NETIF_MSG_LINK, "1G XGXS phy link up\n"); bnx2x_bits_en(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, ((1 << bp->ser_lane) << - NIG_XGXS0_LINK_STATUS_SIZE)); + NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); } else { /* SerDes */ - DP(NETIF_MSG_LINK, "SerDes link up\n"); + DP(NETIF_MSG_LINK, "SerDes phy link up\n"); /* Disable the link interrupt * by writing 1 to the status register */ bnx2x_bits_en(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_SERDES0_LINK_STATUS); + NIG_STATUS_SERDES0_LINK_STATUS); } } else { /* link_down */ @@ -1724,91 +1979,182 @@ static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp) { u32 ext_phy_type; u32 ext_phy_addr; - u32 local_phy; - u32 val = 0; + u32 val1 = 0, val2; u32 rx_sd, pcs_status; if (bp->phy_flags & PHY_XGXS_FLAG) { - local_phy = bp->phy_addr; ext_phy_addr = ((bp->ext_phy_config & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); - bp->phy_addr = (u8)ext_phy_addr; ext_phy_type = XGXS_EXT_PHY_TYPE(bp); switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "XGXS Direct\n"); - val = 1; + val1 = 1; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_WIS_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_WIS_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PMD_RX_SD, &rx_sd); - val = (rx_sd & 0x1); + DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd); + val1 = (rx_sd & 0x1); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: DP(NETIF_MSG_LINK, "XGXS 8706\n"); - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PMD_RX_SD, &rx_sd); - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD, - EXT_PHY_OPT_PCS_STATUS, &pcs_status); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PCS_DEVAD, + EXT_PHY_OPT_PCS_STATUS, &pcs_status); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_LINK_STATUS, &val2); + DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x" - " pcs_status 0x%x\n", rx_sd, pcs_status); - /* link is up if both bit 0 of pmd_rx and - * bit 0 of pcs_status are set + " pcs_status 0x%x 1Gbps link_status 0x%x 0x%x\n", + rx_sd, pcs_status, val2, (val2 & (1<<1))); + /* link is up if both bit 0 of pmd_rx_sd and + * bit 0 of pcs_status are set, or if the autoneg bit + 1 is set */ - val = (rx_sd & pcs_status); + val1 = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO); + + /* clear the interrupt LASI status register */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PCS_DEVAD, + EXT_PHY_KR_LASI_STATUS, &val2); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PCS_DEVAD, + EXT_PHY_KR_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "KR LASI status 0x%x->0x%x\n", + val2, val1); + /* Check the LASI */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0x9003, &val2); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0x9003, &val1); + DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n", + val2, val1); + /* Check the link status */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PCS_DEVAD, + EXT_PHY_KR_PCS_STATUS, &val2); + DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); + /* Check the link status on 1.1.2 */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val2); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val1); + DP(NETIF_MSG_LINK, + "KR PMA status 0x%x->0x%x\n", val2, val1); + val1 = ((val1 & 4) == 4); + /* If 1G was requested assume the link is up */ + if (!(bp->req_autoneg & AUTONEG_SPEED) && + (bp->req_line_speed == SPEED_1000)) + val1 = 1; + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val2); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, + "10G-base-T LASI status 0x%x->0x%x\n", val2, val1); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val2); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val1); + DP(NETIF_MSG_LINK, + "10G-base-T PMA status 0x%x->0x%x\n", val2, val1); + val1 = ((val1 & 4) == 4); + /* if link is up + * print the AN outcome of the SFX7101 PHY + */ + if (val1) { + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0x21, &val2); + DP(NETIF_MSG_LINK, + "SFX7101 AN status 0x%x->%s\n", val2, + (val2 & (1<<14)) ? "Master" : "Slave"); + } break; default: DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", bp->ext_phy_config); - val = 0; + val1 = 0; break; } - bp->phy_addr = local_phy; } else { /* SerDes */ ext_phy_type = SERDES_EXT_PHY_TYPE(bp); switch (ext_phy_type) { case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "SerDes Direct\n"); - val = 1; + val1 = 1; break; case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: DP(NETIF_MSG_LINK, "SerDes 5482\n"); - val = 1; + val1 = 1; break; default: DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", bp->ext_phy_config); - val = 0; + val1 = 0; break; } } - return val; + return val1; } static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb) @@ -1819,7 +2165,7 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb) u32 wb_write[2]; u32 val; - DP(NETIF_MSG_LINK, "enableing BigMAC\n"); + DP(NETIF_MSG_LINK, "enabling BigMAC\n"); /* reset and unreset the BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); @@ -1933,6 +2279,35 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb) bp->stats_state = STATS_STATE_ENABLE; } +static void bnx2x_bmac_rx_disable(struct bnx2x *bp) +{ + int port = bp->port; + u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 wb_write[2]; + + /* Only if the bmac is out of reset */ + if (REG_RD(bp, MISC_REG_RESET_REG_2) & + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)) { + /* Clear Rx Enable bit in BMAC_CONTROL register */ +#ifdef BNX2X_DMAE_RD + bnx2x_read_dmae(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, 2); + wb_write[0] = *bnx2x_sp(bp, wb_data[0]); + wb_write[1] = *bnx2x_sp(bp, wb_data[1]); +#else + wb_write[0] = REG_RD(bp, + bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL); + wb_write[1] = REG_RD(bp, + bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL + 4); +#endif + wb_write[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, + wb_write, 2); + msleep(1); + } +} + static void bnx2x_emac_enable(struct bnx2x *bp) { int port = bp->port; @@ -1940,7 +2315,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp) u32 val; int timeout; - DP(NETIF_MSG_LINK, "enableing EMAC\n"); + DP(NETIF_MSG_LINK, "enabling EMAC\n"); /* reset and unreset the emac core */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); @@ -2033,7 +2408,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp) EMAC_TX_MODE_EXT_PAUSE_EN); } - /* KEEP_VLAN_TAG, promiscous */ + /* KEEP_VLAN_TAG, promiscuous */ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; EMAC_WR(EMAC_REG_EMAC_RX_MODE, val); @@ -2161,7 +2536,6 @@ static void bnx2x_pbf_update(struct bnx2x *bp) u32 count = 1000; u32 pause = 0; - /* disable port */ REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); @@ -2232,7 +2606,7 @@ static void bnx2x_pbf_update(struct bnx2x *bp) static void bnx2x_update_mng(struct bnx2x *bp) { if (!nomcp) - SHMEM_WR(bp, drv_fw_mb[bp->port].link_status, + SHMEM_WR(bp, port_mb[bp->port].link_status, bp->link_status); } @@ -2294,19 +2668,19 @@ static void bnx2x_link_down(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - STOP\n"); } - /* indicate link down */ + /* indicate no mac active */ bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG); - /* reset BigMac */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + /* update shared memory */ + bnx2x_update_mng(bp); - /* ignore drain flag interrupt */ /* activate nig drain */ NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - /* update shared memory */ - bnx2x_update_mng(bp); + /* reset BigMac */ + bnx2x_bmac_rx_disable(bp); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); /* indicate link down */ bnx2x_link_report(bp); @@ -2317,14 +2691,15 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp); /* This function is called upon link interrupt */ static void bnx2x_link_update(struct bnx2x *bp) { - u32 gp_status; int port = bp->port; int i; + u32 gp_status; int link_10g; - DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x," + DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x," " int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x," - " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG), + " 10G %x, XGXS_LINK %x\n", port, + (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes", REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4), REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask, REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), @@ -2336,7 +2711,7 @@ static void bnx2x_link_update(struct bnx2x *bp) might_sleep(); MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS); /* avoid fast toggling */ - for (i = 0 ; i < 10 ; i++) { + for (i = 0; i < 10; i++) { msleep(10); bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); @@ -2351,7 +2726,8 @@ static void bnx2x_link_update(struct bnx2x *bp) bnx2x_link_int_ack(bp, link_10g); /* link is up only if both local phy and external phy are up */ - if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) { + bp->link_up = (bp->phy_link_up && bnx2x_ext_phy_is_link_up(bp)); + if (bp->link_up) { if (link_10g) { bnx2x_bmac_enable(bp, 0); bnx2x_leds_set(bp, SPEED_10000); @@ -2427,7 +2803,9 @@ static void bnx2x_reset_unicore(struct bnx2x *bp) } } - BNX2X_ERR("BUG! unicore is still in reset!\n"); + BNX2X_ERR("BUG! %s (0x%x) is still in reset!\n", + (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes", + bp->phy_addr); } static void bnx2x_set_swap_lanes(struct bnx2x *bp) @@ -2475,12 +2853,12 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp) MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT); bnx2x_mdio22_write(bp, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); bnx2x_mdio22_read(bp, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, - &control2); + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + &control2); if (bp->autoneg & AUTONEG_PARALLEL) { control2 |= @@ -2490,8 +2868,14 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp) ~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; } bnx2x_mdio22_write(bp, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, - control2); + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + control2); + + /* Disable parallel detection of HiG */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2); + bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, + MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | + MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS); } } @@ -2625,7 +3009,7 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp) MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G); /* set extended capabilities */ - if (bp->advertising & ADVERTISED_2500baseT_Full) + if (bp->advertising & ADVERTISED_2500baseX_Full) val |= MDIO_OVER_1G_UP1_2_5G; if (bp->advertising & ADVERTISED_10000baseT_Full) val |= MDIO_OVER_1G_UP1_10G; @@ -2641,20 +3025,91 @@ static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp) /* for AN, we are always publishing full duplex */ an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; - /* set pause */ - switch (bp->pause_mode) { - case PAUSE_SYMMETRIC: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; - break; - case PAUSE_ASYMMETRIC: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; - break; - case PAUSE_BOTH: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; - break; - case PAUSE_NONE: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; - break; + /* resolve pause mode and advertisement + * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ + if (bp->req_autoneg & AUTONEG_FLOW_CTRL) { + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + if (bp->dev->mtu <= 4500) { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + } + break; + + case FLOW_CTRL_TX: + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + break; + + case FLOW_CTRL_RX: + if (bp->dev->mtu <= 4500) { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } + break; + + case FLOW_CTRL_BOTH: + if (bp->dev->mtu <= 4500) { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + } + break; + + case FLOW_CTRL_NONE: + default: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + } + } else { /* forced mode */ + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while" + " req_autoneg 0x%x\n", + bp->req_flow_ctrl, bp->req_autoneg); + break; + + case FLOW_CTRL_TX: + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + break; + + case FLOW_CTRL_RX: + case FLOW_CTRL_BOTH: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + + case FLOW_CTRL_NONE: + default: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + } } MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); @@ -2752,47 +3207,162 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x *bp) static void bnx2x_link_int_enable(struct bnx2x *bp) { int port = bp->port; + u32 ext_phy_type; + u32 mask; /* setting the status to report on link up for either XGXS or SerDes */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_XGXS0_LINK_STATUS | - NIG_STATUS_INTERRUPT_XGXS0_LINK10G | - NIG_SERDES0_LINK_STATUS)); + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS)); if (bp->phy_flags & PHY_XGXS_FLAG) { - /* TBD - - * in force mode (not AN) we can enable just the relevant - * interrupt - * Even in AN we might enable only one according to the AN - * speed mask - */ - bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G)); - DP(NETIF_MSG_LINK, "enable XGXS interrupt\n"); + mask = (NIG_MASK_XGXS0_LINK10G | + NIG_MASK_XGXS0_LINK_STATUS); + DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); + ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && + (ext_phy_type != + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); + } } else { /* SerDes */ - bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_SERDES0_LINK_STATUS); - DP(NETIF_MSG_LINK, "enable SerDes interrupt\n"); + mask = NIG_MASK_SERDES0_LINK_STATUS; + DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); + ext_phy_type = SERDES_EXT_PHY_TYPE(bp); + if ((ext_phy_type != + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && + (ext_phy_type != + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); + } } + bnx2x_bits_en(bp, + NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + mask); + DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x," + " int_mask 0x%x, MI_INT %x, SERDES_LINK %x," + " 10G %x, XGXS_LINK %x\n", port, + (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes", + REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4), + REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), + REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), + REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68) + ); +} + +static void bnx2x_bcm8072_external_rom_boot(struct bnx2x *bp) +{ + u32 ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + u32 fw_ver1, fw_ver2; + + /* Need to wait 200ms after reset */ + msleep(200); + /* Boot port from external ROM + * Set ser_boot_ctl bit in the MISC_CTRL1 register + */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + EXT_PHY_KR_MISC_CTRL1, 0x0001); + + /* Reset internal microprocessor */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL, + EXT_PHY_KR_ROM_RESET_INTERNAL_MP); + /* set micro reset = 0 */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL, + EXT_PHY_KR_ROM_MICRO_RESET); + /* Reset internal microprocessor */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL, + EXT_PHY_KR_ROM_RESET_INTERNAL_MP); + /* wait for 100ms for code download via SPI port */ + msleep(100); + + /* Clear ser_boot_ctl bit */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + EXT_PHY_KR_MISC_CTRL1, 0x0000); + /* Wait 100ms */ + msleep(100); + + /* Print the PHY FW version */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0xca19, &fw_ver1); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0xca1a, &fw_ver2); + DP(NETIF_MSG_LINK, + "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2); +} + +static void bnx2x_bcm8072_force_10G(struct bnx2x *bp) +{ + u32 ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + + /* Force KR or KX */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL, + 0x2040); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL2, + 0x000b); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_PMD_CTRL, + 0x0000); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, EXT_PHY_KR_CTRL, + 0x0000); } static void bnx2x_ext_phy_init(struct bnx2x *bp) { - int port = bp->port; u32 ext_phy_type; u32 ext_phy_addr; - u32 local_phy; + u32 cnt; + u32 ctrl; + u32 val = 0; if (bp->phy_flags & PHY_XGXS_FLAG) { - local_phy = bp->phy_addr; ext_phy_addr = ((bp->ext_phy_config & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + /* Make sure that the soft reset is off (expect for the 8072: + * due to the lock, it will be done inside the specific + * handling) + */ + if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)) { + /* Wait for soft reset to get cleared upto 1 sec */ + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL, &ctrl); + if (!(ctrl & (1<<15))) + break; + msleep(1); + } + DP(NETIF_MSG_LINK, + "control reg 0x%x (after %d ms)\n", ctrl, cnt); + } + switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "XGXS Direct\n"); @@ -2800,49 +3370,235 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); - bp->phy_addr = ext_phy_type; - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PMD_MISC_CNTL, 0x8288); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PHY_IDENTIFIER, 0x7fbf); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_CMU_PLL_BYPASS, 0x0100); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_WIS_DEVAD, EXT_PHY_OPT_LASI_CNTL, 0x1); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: DP(NETIF_MSG_LINK, "XGXS 8706\n"); - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); - - bp->phy_addr = ext_phy_type; - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, - EXT_PHY_OPT_PMD_DIGITAL_CNT, - 0x400); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + + if (!(bp->req_autoneg & AUTONEG_SPEED)) { + /* Force speed */ + if (bp->req_line_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, + "XGXS 8706 force 10Gbps\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_PMD_DIGITAL_CNT, + 0x400); + } else { + /* Force 1Gbps */ + DP(NETIF_MSG_LINK, + "XGXS 8706 force 1Gbps\n"); + + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL, + 0x0040); + + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL2, + 0x000D); + } + + /* Enable LASI */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_CNTL, + 0x1); + } else { + /* AUTONEG */ + /* Allow CL37 through CL73 */ + DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_CL37_CL73, + 0x040c); + + /* Enable Full-Duplex advertisment on CL37 */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_CL37_FD, + 0x0020); + /* Enable CL37 AN */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_CL37_AN, + 0x1000); + /* Advertise 10G/1G support */ + if (bp->advertising & + ADVERTISED_1000baseT_Full) + val = (1<<5); + if (bp->advertising & + ADVERTISED_10000baseT_Full) + val |= (1<<7); + + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_ADV, val); + /* Enable LASI */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_CNTL, + 0x1); + + /* Enable clause 73 AN */ + bnx2x_mdio45_write(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_CNTL, + 0x1200); + } + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO); + /* Wait for soft reset to get cleared upto 1 sec */ + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL, &ctrl); + if (!(ctrl & (1<<15))) + break; + msleep(1); + } + DP(NETIF_MSG_LINK, + "8072 control reg 0x%x (after %d ms)\n", + ctrl, cnt); + + bnx2x_bcm8072_external_rom_boot(bp); + DP(NETIF_MSG_LINK, "Finshed loading 8072 KR ROM\n"); + + /* enable LASI */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0x9000, 0x0400); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + EXT_PHY_KR_LASI_CNTL, 0x0004); + + /* If this is forced speed, set to KR or KX + * (all other are not supported) + */ + if (!(bp->req_autoneg & AUTONEG_SPEED)) { + if (bp->req_line_speed == SPEED_10000) { + bnx2x_bcm8072_force_10G(bp); + DP(NETIF_MSG_LINK, + "Forced speed 10G on 8072\n"); + /* unlock */ + bnx2x_hw_unlock(bp, + HW_LOCK_RESOURCE_8072_MDIO); + break; + } else + val = (1<<5); + } else { + + /* Advertise 10G/1G support */ + if (bp->advertising & + ADVERTISED_1000baseT_Full) + val = (1<<5); + if (bp->advertising & + ADVERTISED_10000baseT_Full) + val |= (1<<7); + } + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0x11, val); + /* Add support for CL37 ( passive mode ) I */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0x8370, 0x040c); + /* Add support for CL37 ( passive mode ) II */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0xffe4, 0x20); + /* Add support for CL37 ( passive mode ) III */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0xffe0, 0x1000); + /* Restart autoneg */ + msleep(500); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_CTRL, 0x1200); + DP(NETIF_MSG_LINK, "8072 Autoneg Restart: " + "1G %ssupported 10G %ssupported\n", + (val & (1<<5)) ? "" : "not ", + (val & (1<<7)) ? "" : "not "); + + /* unlock */ + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + DP(NETIF_MSG_LINK, + "Setting the SFX7101 LASI indication\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_LASI_CNTL, 0x1); + DP(NETIF_MSG_LINK, + "Setting the SFX7101 LED to blink on traffic\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + 0xC007, (1<<3)); + + /* read modify write pause advertizing */ + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_AUTO_NEG_ADVERT, &val); + val &= ~EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH; + /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ + if (bp->advertising & ADVERTISED_Pause) + val |= EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE; + + if (bp->advertising & ADVERTISED_Asym_Pause) { + val |= + EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC; + } + DP(NETIF_MSG_LINK, "SFX7101 AN advertize 0x%x\n", val); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_AUTO_NEG_ADVERT, val); + /* Restart autoneg */ + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_CTRL, &val); + val |= 0x200; + bnx2x_mdio45_write(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_CTRL, val); break; default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - bp->ext_phy_config); + BNX2X_ERR("BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); break; } - bp->phy_addr = local_phy; } else { /* SerDes */ -/* ext_phy_addr = ((bp->ext_phy_config & +/* ext_phy_addr = ((bp->ext_phy_config & PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT); */ @@ -2854,10 +3610,6 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: DP(NETIF_MSG_LINK, "SerDes 5482\n"); - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); break; default: @@ -2871,8 +3623,22 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) static void bnx2x_ext_phy_reset(struct bnx2x *bp) { u32 ext_phy_type; - u32 ext_phy_addr; - u32 local_phy; + u32 ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK); + + /* The PHY reset is controled by GPIO 1 + * Give it 1ms of reset pulse + */ + if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) && + (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) { + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH); + } if (bp->phy_flags & PHY_XGXS_FLAG) { ext_phy_type = XGXS_EXT_PHY_TYPE(bp); @@ -2883,15 +3649,24 @@ static void bnx2x_ext_phy_reset(struct bnx2x *bp) case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - DP(NETIF_MSG_LINK, "XGXS 8705/6\n"); - local_phy = bp->phy_addr; - ext_phy_addr = ((bp->ext_phy_config & - PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> - PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); - bp->phy_addr = (u8)ext_phy_addr; - bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + DP(NETIF_MSG_LINK, "XGXS 8705/8706\n"); + bnx2x_mdio45_write(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_CNTL, 0xa040); - bp->phy_addr = local_phy; + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + DP(NETIF_MSG_LINK, "XGXS 8072\n"); + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0, 1<<15); + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + DP(NETIF_MSG_LINK, "XGXS SFX7101\n"); break; default: @@ -2930,6 +3705,7 @@ static void bnx2x_link_initialize(struct bnx2x *bp) NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); + /* Activate the external PHY */ bnx2x_ext_phy_reset(bp); bnx2x_set_aer_mmd(bp); @@ -2994,13 +3770,13 @@ static void bnx2x_link_initialize(struct bnx2x *bp) /* AN enabled */ bnx2x_set_brcm_cl37_advertisment(bp); - /* program duplex & pause advertisment (for aneg) */ + /* program duplex & pause advertisement (for aneg) */ bnx2x_set_ieee_aneg_advertisment(bp); /* enable autoneg */ bnx2x_set_autoneg(bp); - /* enalbe and restart AN */ + /* enable and restart AN */ bnx2x_restart_autoneg(bp); } @@ -3010,11 +3786,11 @@ static void bnx2x_link_initialize(struct bnx2x *bp) bnx2x_initialize_sgmii_process(bp); } - /* enable the interrupt */ - bnx2x_link_int_enable(bp); - /* init ext phy and enable link state int */ bnx2x_ext_phy_init(bp); + + /* enable the interrupt */ + bnx2x_link_int_enable(bp); } static void bnx2x_phy_deassert(struct bnx2x *bp) @@ -3073,6 +3849,11 @@ static int bnx2x_phy_init(struct bnx2x *bp) static void bnx2x_link_reset(struct bnx2x *bp) { int port = bp->port; + u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK); + + /* update shared memory */ + bp->link_status = 0; + bnx2x_update_mng(bp); /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, @@ -3081,21 +3862,45 @@ static void bnx2x_link_reset(struct bnx2x *bp) NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); - bnx2x_ext_phy_reset(bp); + /* activate nig drain */ + NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + + /* disable nig egress interface */ + NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0); + NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + + /* Stop BigMac rx */ + bnx2x_bmac_rx_disable(bp); + + /* disable emac */ + NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0); + + msleep(10); + + /* The PHY reset is controled by GPIO 1 + * Hold it as output low + */ + if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) && + (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) { + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + DP(NETIF_MSG_LINK, "reset external PHY\n"); + } /* reset the SerDes/XGXS */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, (0x1ff << (port*16))); - /* reset EMAC / BMAC and disable NIG interfaces */ - NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0); - NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0); + /* reset BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0); + /* disable nig ingress interface */ + NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0); NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0); - NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); - NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + /* set link down */ + bp->link_up = 0; } #ifdef BNX2X_XGXS_LB @@ -3158,7 +3963,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, int port = bp->port; DP(NETIF_MSG_TIMER, - "spe (%x:%x) command %x hw_cid %x data (%x:%x) left %x\n", + "spe (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) + (void *)bp->spq_prod_bd - (void *)bp->spq), command, HW_CID(bp, cid), data_hi, data_lo, bp->spq_left); @@ -3176,6 +3981,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, bnx2x_panic(); return -EBUSY; } + /* CID needs port number to be encoded int it */ bp->spq_prod_bd->hdr.conn_and_cmd_data = cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) | @@ -3282,8 +4088,8 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8; u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : MISC_REG_AEU_MASK_ATTN_FUNC_0; - u32 nig_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : - NIG_REG_MASK_INTERRUPT_PORT0; + u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : + NIG_REG_MASK_INTERRUPT_PORT0; if (~bp->aeu_mask & (asserted & 0xff)) BNX2X_ERR("IGU ERROR\n"); @@ -3301,15 +4107,11 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) if (asserted & ATTN_HARD_WIRED_MASK) { if (asserted & ATTN_NIG_FOR_FUNC) { - u32 nig_status_port; - u32 nig_int_addr = port ? - NIG_REG_STATUS_INTERRUPT_PORT1 : - NIG_REG_STATUS_INTERRUPT_PORT0; - bp->nig_mask = REG_RD(bp, nig_mask_addr); - REG_WR(bp, nig_mask_addr, 0); + /* save nig interrupt mask */ + bp->nig_mask = REG_RD(bp, nig_int_mask_addr); + REG_WR(bp, nig_int_mask_addr, 0); - nig_status_port = REG_RD(bp, nig_int_addr); bnx2x_link_update(bp); /* handle unicore attn? */ @@ -3362,15 +4164,132 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) /* now set back the mask */ if (asserted & ATTN_NIG_FOR_FUNC) - REG_WR(bp, nig_mask_addr, bp->nig_mask); + REG_WR(bp, nig_int_mask_addr, bp->nig_mask); } -static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) +static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) { int port = bp->port; - int index; + int reg_offset; + u32 val; + + if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) { + + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : + MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + + val = REG_RD(bp, reg_offset); + val &= ~AEU_INPUTS_ATTN_BITS_SPIO5; + REG_WR(bp, reg_offset, val); + + BNX2X_ERR("SPIO5 hw attention\n"); + + switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) { + case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G: + /* Fan failure attention */ + + /* The PHY reset is controled by GPIO 1 */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + /* Low power mode is controled by GPIO 2 */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + /* mark the failure */ + bp->ext_phy_config &= + ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; + bp->ext_phy_config |= + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; + SHMEM_WR(bp, + dev_info.port_hw_config[port]. + external_phy_config, + bp->ext_phy_config); + /* log the failure */ + printk(KERN_ERR PFX "Fan Failure on Network" + " Controller %s has caused the driver to" + " shutdown the card to prevent permanent" + " damage. Please contact Dell Support for" + " assistance\n", bp->dev->name); + break; + + default: + break; + } + } +} + +static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn) +{ + u32 val; + + if (attn & BNX2X_DOORQ_ASSERT) { + + val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR); + BNX2X_ERR("DB hw attention 0x%x\n", val); + /* DORQ discard attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from DORQ\n"); + } +} + +static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) +{ + u32 val; + + if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { + + val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR); + BNX2X_ERR("CFC hw attention 0x%x\n", val); + /* CFC error attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from CFC\n"); + } + + if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { + + val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); + BNX2X_ERR("PXP hw attention 0x%x\n", val); + /* RQ_USDMDP_FIFO_OVERFLOW */ + if (val & 0x18000) + BNX2X_ERR("FATAL error from PXP\n"); + } +} + +static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) +{ + if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) { + + if (attn & BNX2X_MC_ASSERT_BITS) { + + BNX2X_ERR("MC assert!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0); + bnx2x_panic(); + + } else if (attn & BNX2X_MCP_ASSERT) { + + BNX2X_ERR("MCP assert!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0); + bnx2x_mc_assert(bp); + + } else + BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn); + } + + if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) { + + REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff); + BNX2X_ERR("LATCHED attention 0x%x (masked)\n", attn); + } +} + +static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) +{ struct attn_route attn; struct attn_route group_mask; + int port = bp->port; + int index; u32 reg_addr; u32 val; @@ -3391,64 +4310,14 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) DP(NETIF_MSG_HW, "group[%d]: %llx\n", index, (unsigned long long)group_mask.sig[0]); - if (attn.sig[3] & group_mask.sig[3] & - EVEREST_GEN_ATTN_IN_USE_MASK) { - - if (attn.sig[3] & BNX2X_MC_ASSERT_BITS) { - - BNX2X_ERR("MC assert!\n"); - bnx2x_panic(); - - } else if (attn.sig[3] & BNX2X_MCP_ASSERT) { - - BNX2X_ERR("MCP assert!\n"); - REG_WR(bp, - MISC_REG_AEU_GENERAL_ATTN_11, 0); - bnx2x_mc_assert(bp); - - } else { - BNX2X_ERR("UNKOWEN HW ASSERT!\n"); - } - } - - if (attn.sig[1] & group_mask.sig[1] & - BNX2X_DOORQ_ASSERT) { - - val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR); - BNX2X_ERR("DB hw attention 0x%x\n", val); - /* DORQ discard attention */ - if (val & 0x2) - BNX2X_ERR("FATAL error from DORQ\n"); - } - - if (attn.sig[2] & group_mask.sig[2] & - AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { - - val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR); - BNX2X_ERR("CFC hw attention 0x%x\n", val); - /* CFC error attention */ - if (val & 0x2) - BNX2X_ERR("FATAL error from CFC\n"); - } - - if (attn.sig[2] & group_mask.sig[2] & - AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { - - val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); - BNX2X_ERR("PXP hw attention 0x%x\n", val); - /* RQ_USDMDP_FIFO_OVERFLOW */ - if (val & 0x18000) - BNX2X_ERR("FATAL error from PXP\n"); - } - - if (attn.sig[3] & group_mask.sig[3] & - EVEREST_LATCHED_ATTN_IN_USE_MASK) { - - REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, - 0x7ff); - DP(NETIF_MSG_HW, "got latched bits 0x%x\n", - attn.sig[3]); - } + bnx2x_attn_int_deasserted3(bp, + attn.sig[3] & group_mask.sig[3]); + bnx2x_attn_int_deasserted1(bp, + attn.sig[1] & group_mask.sig[1]); + bnx2x_attn_int_deasserted2(bp, + attn.sig[2] & group_mask.sig[2]); + bnx2x_attn_int_deasserted0(bp, + attn.sig[0] & group_mask.sig[0]); if ((attn.sig[0] & group_mask.sig[0] & HW_INTERRUT_ASSERT_SET_0) || @@ -3456,7 +4325,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) HW_INTERRUT_ASSERT_SET_1) || (attn.sig[2] & group_mask.sig[2] & HW_INTERRUT_ASSERT_SET_2)) - BNX2X_ERR("FATAL HW block attention\n"); + BNX2X_ERR("FATAL HW block attention" + " set0 0x%x set1 0x%x" + " set2 0x%x\n", + (attn.sig[0] & group_mask.sig[0] & + HW_INTERRUT_ASSERT_SET_0), + (attn.sig[1] & group_mask.sig[1] & + HW_INTERRUT_ASSERT_SET_1), + (attn.sig[2] & group_mask.sig[2] & + HW_INTERRUT_ASSERT_SET_2)); if ((attn.sig[0] & group_mask.sig[0] & HW_PRTY_ASSERT_SET_0) || @@ -3464,7 +4341,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) HW_PRTY_ASSERT_SET_1) || (attn.sig[2] & group_mask.sig[2] & HW_PRTY_ASSERT_SET_2)) - BNX2X_ERR("FATAL HW block parity atention\n"); + BNX2X_ERR("FATAL HW block parity attention\n"); } } @@ -3529,7 +4406,7 @@ static void bnx2x_sp_task(struct work_struct *work) /* Return here if interrupt is disabled */ if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n"); return; } @@ -3539,12 +4416,11 @@ static void bnx2x_sp_task(struct work_struct *work) DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status); - if (status & 0x1) { - /* HW attentions */ + /* HW attentions */ + if (status & 0x1) bnx2x_attn_int(bp); - } - /* CStorm events: query_stats, cfc delete ramrods */ + /* CStorm events: query_stats, port delete ramrod */ if (status & 0x2) bp->stat_pending = 0; @@ -3558,6 +4434,7 @@ static void bnx2x_sp_task(struct work_struct *work) IGU_INT_NOP, 1); bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx), IGU_INT_ENABLE, 1); + } static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) @@ -3567,11 +4444,11 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) /* Return here if interrupt is disabled */ if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n"); return IRQ_HANDLED; } - bnx2x_ack_sb(bp, 16, XSTORM_ID, 0, IGU_INT_DISABLE, 0); + bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -3906,7 +4783,7 @@ static void bnx2x_stop_stats(struct bnx2x *bp) while (bp->stats_state != STATS_STATE_DISABLE) { if (!timeout) { - BNX2X_ERR("timeout wating for stats stop\n"); + BNX2X_ERR("timeout waiting for stats stop\n"); break; } timeout--; @@ -4173,39 +5050,37 @@ static void bnx2x_update_net_stats(struct bnx2x *bp) nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); - nstats->tx_bytes = - bnx2x_hilo(&estats->total_bytes_transmitted_hi); + nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); - nstats->rx_dropped = estats->checksum_discard + - estats->mac_discard; + nstats->rx_dropped = estats->checksum_discard + estats->mac_discard; nstats->tx_dropped = 0; nstats->multicast = bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi); - nstats->collisions = - estats->single_collision_transmit_frames + - estats->multiple_collision_transmit_frames + - estats->late_collision_frames + - estats->excessive_collision_frames; + nstats->collisions = estats->single_collision_transmit_frames + + estats->multiple_collision_transmit_frames + + estats->late_collision_frames + + estats->excessive_collision_frames; nstats->rx_length_errors = estats->runt_packets_received + estats->jabber_packets_received; - nstats->rx_over_errors = estats->no_buff_discard; + nstats->rx_over_errors = estats->brb_discard + + estats->brb_truncate_discard; nstats->rx_crc_errors = estats->crc_receive_errors; nstats->rx_frame_errors = estats->alignment_errors; - nstats->rx_fifo_errors = estats->brb_discard + - estats->brb_truncate_discard; + nstats->rx_fifo_errors = estats->no_buff_discard; nstats->rx_missed_errors = estats->xxoverflow_discard; nstats->rx_errors = nstats->rx_length_errors + nstats->rx_over_errors + nstats->rx_crc_errors + nstats->rx_frame_errors + - nstats->rx_fifo_errors; + nstats->rx_fifo_errors + + nstats->rx_missed_errors; nstats->tx_aborted_errors = estats->late_collision_frames + - estats->excessive_collision_frames; + estats->excessive_collision_frames; nstats->tx_carrier_errors = estats->false_carrier_detections; nstats->tx_fifo_errors = 0; nstats->tx_heartbeat_errors = 0; @@ -4334,7 +5209,7 @@ static void bnx2x_timer(unsigned long data) return; if (atomic_read(&bp->intr_sem) != 0) - goto bnx2x_restart_timer; + goto timer_restart; if (poll) { struct bnx2x_fastpath *fp = &bp->fp[0]; @@ -4344,7 +5219,7 @@ static void bnx2x_timer(unsigned long data) rc = bnx2x_rx_int(fp, 1000); } - if (!nomcp && (bp->bc_ver >= 0x040003)) { + if (!nomcp) { int port = bp->port; u32 drv_pulse; u32 mcp_pulse; @@ -4353,9 +5228,9 @@ static void bnx2x_timer(unsigned long data) bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; /* TBD - add SYSTEM_TIME */ drv_pulse = bp->fw_drv_pulse_wr_seq; - SHMEM_WR(bp, drv_fw_mb[port].drv_pulse_mb, drv_pulse); + SHMEM_WR(bp, func_mb[port].drv_pulse_mb, drv_pulse); - mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].mcp_pulse_mb) & + mcp_pulse = (SHMEM_RD(bp, func_mb[port].mcp_pulse_mb) & MCP_PULSE_SEQ_MASK); /* The delta between driver pulse and mcp response * should be 1 (before mcp response) or 0 (after mcp response) @@ -4369,11 +5244,11 @@ static void bnx2x_timer(unsigned long data) } if (bp->stats_state == STATS_STATE_DISABLE) - goto bnx2x_restart_timer; + goto timer_restart; bnx2x_update_stats(bp); -bnx2x_restart_timer: +timer_restart: mod_timer(&bp->timer, jiffies + bp->current_interval); } @@ -4438,6 +5313,9 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, atten_status_block); def_sb->atten_status_block.status_block_id = id; + bp->def_att_idx = 0; + bp->attn_state = 0; + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); @@ -4472,6 +5350,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, u_def_status_block); def_sb->u_def_status_block.status_block_id = id; + bp->def_u_idx = 0; + REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_USTRORM_INTMEM + @@ -4489,6 +5369,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, c_def_status_block); def_sb->c_def_status_block.status_block_id = id; + bp->def_c_idx = 0; + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_CSTRORM_INTMEM + @@ -4506,6 +5388,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, t_def_status_block); def_sb->t_def_status_block.status_block_id = id; + bp->def_t_idx = 0; + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_TSTRORM_INTMEM + @@ -4523,6 +5407,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, x_def_status_block); def_sb->x_def_status_block.status_block_id = id; + bp->def_x_idx = 0; + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_XSTRORM_INTMEM + @@ -4535,6 +5421,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1); + bp->stat_pending = 0; + bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); } @@ -4626,7 +5514,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp) fp->rx_bd_prod = fp->rx_comp_prod = ring_prod; fp->rx_pkt = fp->rx_calls = 0; - /* Warning! this will genrate an interrupt (to the TSTORM) */ + /* Warning! this will generate an interrupt (to the TSTORM) */ /* must only be done when chip is initialized */ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod); @@ -4678,7 +5566,6 @@ static void bnx2x_init_sp_ring(struct bnx2x *bp) bp->spq_left = MAX_SPQ_PENDING; bp->spq_prod_idx = 0; - bp->dsb_sp_prod_idx = 0; bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; bp->spq_prod_bd = bp->spq; bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT; @@ -4755,6 +5642,42 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); } +static void bnx2x_set_client_config(struct bnx2x *bp) +{ +#ifdef BCM_VLAN + int mode = bp->rx_mode; +#endif + int i, port = bp->port; + struct tstorm_eth_client_config tstorm_client = {0}; + + tstorm_client.mtu = bp->dev->mtu; + tstorm_client.statistics_counter_id = 0; + tstorm_client.config_flags = + TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; +#ifdef BCM_VLAN + if (mode && bp->vlgrp) { + tstorm_client.config_flags |= + TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; + DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); + } +#endif + if (mode != BNX2X_RX_MODE_PROMISC) + tstorm_client.drop_flags = + TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR; + + for_each_queue(bp, i) { + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, i), + ((u32 *)&tstorm_client)[0]); + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, i) + 4, + ((u32 *)&tstorm_client)[1]); + } + +/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n", + ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */ +} + static void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { int mode = bp->rx_mode; @@ -4794,41 +5717,9 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp) /* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, ((u32 *)&tstorm_mac_filter)[i]); */ } -} -static void bnx2x_set_client_config(struct bnx2x *bp, int client_id) -{ -#ifdef BCM_VLAN - int mode = bp->rx_mode; -#endif - int port = bp->port; - struct tstorm_eth_client_config tstorm_client = {0}; - - tstorm_client.mtu = bp->dev->mtu; - tstorm_client.statistics_counter_id = 0; - tstorm_client.config_flags = - TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; -#ifdef BCM_VLAN - if (mode && bp->vlgrp) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; - DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); - } -#endif - tstorm_client.drop_flags = (TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR | - TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR | - TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR | - TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, client_id), - ((u32 *)&tstorm_client)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) + 4, - ((u32 *)&tstorm_client)[1]); - -/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n", - ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */ + if (mode != BNX2X_RX_MODE_NONE) + bnx2x_set_client_config(bp); } static void bnx2x_init_internal(struct bnx2x *bp) @@ -4836,7 +5727,6 @@ static void bnx2x_init_internal(struct bnx2x *bp) int port = bp->port; struct tstorm_eth_function_common_config tstorm_config = {0}; struct stats_indication_flags stats_flags = {0}; - int i; if (is_multi(bp)) { tstorm_config.config_flags = MULTI_FLAGS; @@ -4850,13 +5740,9 @@ static void bnx2x_init_internal(struct bnx2x *bp) /* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n", (*(u32 *)&tstorm_config)); */ - bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx untill link is up */ + bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ bnx2x_set_storm_rx_mode(bp); - for_each_queue(bp, i) - bnx2x_set_client_config(bp, i); - - stats_flags.collect_eth = cpu_to_le32(1); REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), @@ -4902,7 +5788,7 @@ static void bnx2x_nic_init(struct bnx2x *bp) bnx2x_init_internal(bp); bnx2x_init_stats(bp); bnx2x_init_ind_table(bp); - bnx2x_enable_int(bp); + bnx2x_int_enable(bp); } @@ -5265,8 +6151,10 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) if (mode & 0x1) { /* init common */ DP(BNX2X_MSG_MCP, "starting common init func %d mode %x\n", func, mode); - REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff); - REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + 0xffffffff); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + 0xfffc); bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END); REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); @@ -5359,7 +6247,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8); #endif bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END); - /* softrest pulse */ + /* soft reset pulse */ REG_WR(bp, QM_REG_SOFT_RESET, 1); REG_WR(bp, QM_REG_SOFT_RESET, 0); @@ -5413,7 +6301,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) { REG_WR(bp, i, 0xc0cac01a); - /* TODO: repleace with something meaningfull */ + /* TODO: replace with something meaningful */ } /* SRCH COMMON comes here */ REG_WR(bp, SRC_REG_SOFT_RST, 0); @@ -5486,6 +6374,28 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) enable_blocks_attention(bp); /* enable_blocks_parity(bp); */ + switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) { + case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G: + /* Fan failure is indicated by SPIO 5 */ + bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5, + MISC_REGISTERS_SPIO_INPUT_HI_Z); + + /* set to active low mode */ + val = REG_RD(bp, MISC_REG_SPIO_INT); + val |= ((1 << MISC_REGISTERS_SPIO_5) << + MISC_REGISTERS_SPIO_INT_OLD_SET_POS); + REG_WR(bp, MISC_REG_SPIO_INT, val); + + /* enable interrupt to signal the IGU */ + val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN); + val |= (1 << MISC_REGISTERS_SPIO_5); + REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); + break; + + default: + break; + } + } /* end of common init */ /* per port init */ @@ -5645,9 +6555,21 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) /* Port MCP comes here */ /* Port DMAE comes here */ + switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) { + case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G: + /* add SPIO 5 to group 0 */ + val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + val |= AEU_INPUTS_ATTN_BITS_SPIO5; + REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val); + break; + + default: + break; + } + bnx2x_link_reset(bp); - /* Reset pciex errors for debug */ + /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); REG_WR(bp, 0x2120, 0xffffffff); REG_WR(bp, 0x2814, 0xffffffff); @@ -5669,9 +6591,9 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) port = bp->port; bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) & + (SHMEM_RD(bp, func_mb[port].drv_pulse_mb) & DRV_PULSE_SEQ_MASK); - bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param); + bp->fw_mb = SHMEM_RD(bp, func_mb[port].fw_mb_param); DP(BNX2X_MSG_MCP, "drv_pulse 0x%x fw_mb 0x%x\n", bp->fw_drv_pulse_wr_seq, bp->fw_mb); } else { @@ -5681,16 +6603,15 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) return 0; } - -/* send the MCP a request, block untill there is a reply */ +/* send the MCP a request, block until there is a reply */ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) { - u32 rc = 0; - u32 seq = ++bp->fw_seq; int port = bp->port; + u32 seq = ++bp->fw_seq; + u32 rc = 0; - SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq); - DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq); + SHMEM_WR(bp, func_mb[port].drv_mb_header, (command | seq)); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); /* let the FW do it's magic ... */ msleep(100); /* TBD */ @@ -5698,19 +6619,20 @@ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) if (CHIP_REV_IS_SLOW(bp)) msleep(900); - rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header); - + rc = SHMEM_RD(bp, func_mb[port].fw_mb_header); DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq); /* is this a reply to our command? */ if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) { rc &= FW_MSG_CODE_MASK; + } else { /* FW BUG! */ BNX2X_ERR("FW failed to respond!\n"); bnx2x_fw_dump(bp); rc = 0; } + return rc; } @@ -5869,7 +6791,7 @@ static int bnx2x_alloc_mem(struct bnx2x *bp) for (i = 0; i < 16*1024; i += 64) * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; - /* now sixup the last line in the block to point to the next block */ + /* now fixup the last line in the block to point to the next block */ *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping; /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */ @@ -5950,22 +6872,19 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) int i; free_irq(bp->msix_table[0].vector, bp->dev); - DP(NETIF_MSG_IFDOWN, "rleased sp irq (%d)\n", + DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", bp->msix_table[0].vector); for_each_queue(bp, i) { - DP(NETIF_MSG_IFDOWN, "about to rlease fp #%d->%d irq " + DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " "state(%x)\n", i, bp->msix_table[i + 1].vector, bnx2x_fp(bp, i, state)); - if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) { - - free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]); - bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_CLOSED; - - } else - DP(NETIF_MSG_IFDOWN, "irq not freed\n"); + if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) + BNX2X_ERR("IRQ of fp #%d being freed while " + "state != closed\n", i); + free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]); } } @@ -5995,7 +6914,7 @@ static int bnx2x_enable_msix(struct bnx2x *bp) if (pci_enable_msix(bp->pdev, &bp->msix_table[0], bp->num_queues + 1)){ - BNX2X_ERR("failed to enable msix\n"); + BNX2X_LOG("failed to enable MSI-X\n"); return -1; } @@ -6010,11 +6929,8 @@ static int bnx2x_enable_msix(struct bnx2x *bp) static int bnx2x_req_msix_irqs(struct bnx2x *bp) { - int i, rc; - DP(NETIF_MSG_IFUP, "about to request sp irq\n"); - rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0, bp->dev->name, bp->dev); @@ -6029,7 +6945,8 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) bp->dev->name, &bp->fp[i]); if (rc) { - BNX2X_ERR("request fp #%d irq failed\n", i); + BNX2X_ERR("request fp #%d irq failed " + "rc %d\n", i, rc); bnx2x_free_msix_irqs(bp); return -EBUSY; } @@ -6109,8 +7026,8 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, /* can take a while if any port is running */ int timeout = 500; - /* DP("waiting for state to become %d on IDX [%d]\n", - state, sb_idx); */ + DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", + poll ? "polling" : "waiting", state, idx); might_sleep(); @@ -6128,7 +7045,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, mb(); /* state is changed by bnx2x_sp_event()*/ - if (*state_p != state) + if (*state_p == state) return 0; timeout--; @@ -6136,17 +7053,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, } - /* timeout! */ - BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx); - return -EBUSY; + BNX2X_ERR("timeout %s for state %x on IDX [%d]\n", + poll ? "polling" : "waiting", state, idx); + return -EBUSY; } static int bnx2x_setup_leading(struct bnx2x *bp) { - /* reset IGU staae */ + /* reset IGU state */ bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, 0, IGU_INT_ENABLE, 0); /* SETUP ramrod */ @@ -6162,12 +7079,13 @@ static int bnx2x_setup_multi(struct bnx2x *bp, int index) /* reset IGU state */ bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + /* SETUP ramrod */ bp->fp[index].state = BNX2X_FP_STATE_OPENING; bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0); /* Wait for completion */ return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, - &(bp->fp[index].state), 1); + &(bp->fp[index].state), 0); } @@ -6177,8 +7095,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev); static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) { - int rc; - int i = 0; + u32 load_code; + int i; bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; @@ -6188,26 +7106,28 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) initialized, otherwise - not. */ if (!nomcp) { - rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); - if (rc == FW_MSG_CODE_DRV_LOAD_REFUSED) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); + if (!load_code) { + BNX2X_ERR("MCP response failure, unloading\n"); + return -EBUSY; + } + if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { + BNX2X_ERR("MCP refused load request, unloading\n"); return -EBUSY; /* other port in diagnostic mode */ } } else { - rc = FW_MSG_CODE_DRV_LOAD_COMMON; + load_code = FW_MSG_CODE_DRV_LOAD_COMMON; } - DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues); - /* if we can't use msix we only need one fp, * so try to enable msix with the requested number of fp's * and fallback to inta with one fp */ if (req_irq) { - if (use_inta) { bp->num_queues = 1; } else { - if (use_multi > 1 && use_multi <= 16) + if ((use_multi > 1) && (use_multi <= 16)) /* user requested number */ bp->num_queues = use_multi; else if (use_multi == 1) @@ -6216,15 +7136,17 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) bp->num_queues = 1; if (bnx2x_enable_msix(bp)) { - /* faild to enable msix */ + /* failed to enable msix */ bp->num_queues = 1; if (use_multi) - BNX2X_ERR("Muti requested but failed" + BNX2X_ERR("Multi requested but failed" " to enable MSI-X\n"); } } } + DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues); + if (bnx2x_alloc_mem(bp)) return -ENOMEM; @@ -6232,13 +7154,13 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) if (bp->flags & USING_MSIX_FLAG) { if (bnx2x_req_msix_irqs(bp)) { pci_disable_msix(bp->pdev); - goto out_error; + goto load_error; } } else { if (bnx2x_req_irq(bp)) { BNX2X_ERR("IRQ request failed, aborting\n"); - goto out_error; + goto load_error; } } } @@ -6249,31 +7171,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) /* Initialize HW */ - if (bnx2x_function_init(bp, (rc == FW_MSG_CODE_DRV_LOAD_COMMON))) { + if (bnx2x_function_init(bp, + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON))) { BNX2X_ERR("HW init failed, aborting\n"); - goto out_error; + goto load_error; } atomic_set(&bp->intr_sem, 0); - /* Reenable SP tasklet */ - /*if (bp->sp_task_en) { */ - /* tasklet_enable(&bp->sp_task);*/ - /*} else { */ - /* bp->sp_task_en = 1; */ - /*} */ /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp); /* Send LOAD_DONE command to MCP */ if (!nomcp) { - rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); - DP(NETIF_MSG_IFUP, "rc = 0x%x\n", rc); - if (!rc) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + if (!load_code) { BNX2X_ERR("MCP response failure, unloading\n"); - goto int_disable; + goto load_int_disable; } } @@ -6285,11 +7201,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) napi_enable(&bnx2x_fp(bp, i, napi)); if (bnx2x_setup_leading(bp)) - goto stop_netif; + goto load_stop_netif; for_each_nondefault_queue(bp, i) if (bnx2x_setup_multi(bp, i)) - goto stop_netif; + goto load_stop_netif; bnx2x_set_mac_addr(bp); @@ -6313,42 +7229,24 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) return 0; -stop_netif: +load_stop_netif: for_each_queue(bp, i) napi_disable(&bnx2x_fp(bp, i, napi)); -int_disable: - bnx2x_disable_int_sync(bp); +load_int_disable: + bnx2x_int_disable_sync(bp); bnx2x_free_skbs(bp); bnx2x_free_irq(bp); -out_error: +load_error: bnx2x_free_mem(bp); /* TBD we really need to reset the chip if we want to recover from this */ - return rc; + return -EBUSY; } -static void bnx2x_netif_stop(struct bnx2x *bp) -{ - int i; - - bp->rx_mode = BNX2X_RX_MODE_NONE; - bnx2x_set_storm_rx_mode(bp); - - bnx2x_disable_int_sync(bp); - bnx2x_link_reset(bp); - - for_each_queue(bp, i) - napi_disable(&bnx2x_fp(bp, i, napi)); - - if (netif_running(bp->dev)) { - netif_tx_disable(bp->dev); - bp->dev->trans_start = jiffies; /* prevent tx timeout */ - } -} static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) { @@ -6401,20 +7299,20 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index) int rc; - /* halt the connnection */ + /* halt the connection */ bp->fp[index].state = BNX2X_FP_STATE_HALTING; bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0); rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, &(bp->fp[index].state), 1); - if (rc) /* timout */ + if (rc) /* timeout */ return rc; /* delete cfc entry */ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); - return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_DELETED, index, + return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index, &(bp->fp[index].state), 1); } @@ -6422,8 +7320,8 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index) static void bnx2x_stop_leading(struct bnx2x *bp) { - - /* if the other port is hadling traffic, + u16 dsb_sp_prod_idx; + /* if the other port is handling traffic, this can take a lot of time */ int timeout = 500; @@ -6437,52 +7335,71 @@ static void bnx2x_stop_leading(struct bnx2x *bp) &(bp->fp[0].state), 1)) return; - bp->dsb_sp_prod_idx = *bp->dsb_sp_prod; + dsb_sp_prod_idx = *bp->dsb_sp_prod; - /* Send CFC_DELETE ramrod */ + /* Send PORT_DELETE ramrod */ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); - /* - Wait for completion. + /* Wait for completion to arrive on default status block we are going to reset the chip anyway so there is not much to do if this times out */ - while (bp->dsb_sp_prod_idx == *bp->dsb_sp_prod && timeout) { - timeout--; - msleep(1); + while ((dsb_sp_prod_idx == *bp->dsb_sp_prod) && timeout) { + timeout--; + msleep(1); } - + if (!timeout) { + DP(NETIF_MSG_IFDOWN, "timeout polling for completion " + "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", + *bp->dsb_sp_prod, dsb_sp_prod_idx); + } + bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + bp->fp[0].state = BNX2X_FP_STATE_CLOSED; } -static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) + +static int bnx2x_nic_unload(struct bnx2x *bp, int free_irq) { u32 reset_code = 0; - int rc; - int i; + int i, timeout; bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; - /* Calling flush_scheduled_work() may deadlock because - * linkwatch_event() may be on the workqueue and it will try to get - * the rtnl_lock which we are holding. - */ + del_timer_sync(&bp->timer); - while (bp->in_reset_task) - msleep(1); + bp->rx_mode = BNX2X_RX_MODE_NONE; + bnx2x_set_storm_rx_mode(bp); - /* Delete the timer: do it before disabling interrupts, as it - may be stil STAT_QUERY ramrod pending after stopping the timer */ - del_timer_sync(&bp->timer); + if (netif_running(bp->dev)) { + netif_tx_disable(bp->dev); + bp->dev->trans_start = jiffies; /* prevent tx timeout */ + } + + /* Wait until all fast path tasks complete */ + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + timeout = 1000; + while (bnx2x_has_work(fp) && (timeout--)) + msleep(1); + if (!timeout) + BNX2X_ERR("timeout waiting for queue[%d]\n", i); + } /* Wait until stat ramrod returns and all SP tasks complete */ - while (bp->stat_pending && (bp->spq_left != MAX_SPQ_PENDING)) + timeout = 1000; + while ((bp->stat_pending || (bp->spq_left != MAX_SPQ_PENDING)) && + (timeout--)) msleep(1); - /* Stop fast path, disable MAC, disable interrupts, disable napi */ - bnx2x_netif_stop(bp); + for_each_queue(bp, i) + napi_disable(&bnx2x_fp(bp, i, napi)); + /* Disable interrupts after Tx and Rx are disabled on stack level */ + bnx2x_int_disable_sync(bp); if (bp->flags & NO_WOL_FLAG) reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP; + else if (bp->wol) { u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1; u8 *mac_addr = bp->dev->dev_addr; @@ -6499,28 +7416,37 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val); reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN; + } else reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + /* Close multi and leading connections */ for_each_nondefault_queue(bp, i) if (bnx2x_stop_multi(bp, i)) - goto error; - + goto unload_error; bnx2x_stop_leading(bp); + if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) || + (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) { + DP(NETIF_MSG_IFDOWN, "failed to close leading properly!" + "state 0x%x fp[0].state 0x%x", + bp->state, bp->fp[0].state); + } + +unload_error: + bnx2x_link_reset(bp); -error: if (!nomcp) - rc = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code); else - rc = FW_MSG_CODE_DRV_UNLOAD_COMMON; + reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; /* Release IRQs */ - if (fre_irq) + if (free_irq) bnx2x_free_irq(bp); /* Reset the chip */ - bnx2x_reset_chip(bp, rc); + bnx2x_reset_chip(bp, reset_code); /* Report UNLOAD_DONE to MCP */ if (!nomcp) @@ -6531,8 +7457,7 @@ error: bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; - /* Set link down */ - bp->link_up = 0; + netif_carrier_off(bp->dev); return 0; @@ -6568,7 +7493,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseT_Full | + SUPPORTED_2500baseX_Full | SUPPORTED_TP | SUPPORTED_FIBRE | SUPPORTED_Autoneg | SUPPORTED_Pause | @@ -6581,10 +7506,10 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) bp->phy_flags |= PHY_SGMII_FLAG; - bp->supported |= (/* SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full |*/ + bp->supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_TP | SUPPORTED_FIBRE | SUPPORTED_Autoneg | @@ -6620,7 +7545,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseT_Full | + SUPPORTED_2500baseX_Full | SUPPORTED_10000baseT_Full | SUPPORTED_TP | SUPPORTED_FIBRE | SUPPORTED_Autoneg | @@ -6629,12 +7554,46 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", + ext_phy_type); + + bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n", + BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", + ext_phy_type); + + bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", ext_phy_type); bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n", + ext_phy_type); + + bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | SUPPORTED_Pause | SUPPORTED_Asym_Pause); break; @@ -6691,7 +7650,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) SUPPORTED_1000baseT_Full); if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - bp->supported &= ~SUPPORTED_2500baseT_Full; + bp->supported &= ~SUPPORTED_2500baseX_Full; if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) bp->supported &= ~SUPPORTED_10000baseT_Full; @@ -6711,13 +7670,8 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) bp->req_line_speed = 0; bp->advertising = bp->supported; } else { - u32 ext_phy_type; - - ext_phy_type = XGXS_EXT_PHY_TYPE(bp); - if ((ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) { + if (XGXS_EXT_PHY_TYPE(bp) == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) { /* force 10G, no AN */ bp->req_line_speed = SPEED_10000; bp->advertising = @@ -6734,8 +7688,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_10M_FULL: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) { + if (bp->supported & SUPPORTED_10baseT_Full) { bp->req_line_speed = SPEED_10; bp->advertising = (ADVERTISED_10baseT_Full | ADVERTISED_TP); @@ -6749,8 +7702,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_10M_HALF: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) { + if (bp->supported & SUPPORTED_10baseT_Half) { bp->req_line_speed = SPEED_10; bp->req_duplex = DUPLEX_HALF; bp->advertising = (ADVERTISED_10baseT_Half | @@ -6765,8 +7717,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) { + if (bp->supported & SUPPORTED_100baseT_Full) { bp->req_line_speed = SPEED_100; bp->advertising = (ADVERTISED_100baseT_Full | ADVERTISED_TP); @@ -6780,8 +7731,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) { + if (bp->supported & SUPPORTED_100baseT_Half) { bp->req_line_speed = SPEED_100; bp->req_duplex = DUPLEX_HALF; bp->advertising = (ADVERTISED_100baseT_Half | @@ -6796,8 +7746,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_1G: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) { + if (bp->supported & SUPPORTED_1000baseT_Full) { bp->req_line_speed = SPEED_1000; bp->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_TP); @@ -6811,10 +7760,9 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_2_5G: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) { + if (bp->supported & SUPPORTED_2500baseX_Full) { bp->req_line_speed = SPEED_2500; - bp->advertising = (ADVERTISED_2500baseT_Full | + bp->advertising = (ADVERTISED_2500baseX_Full | ADVERTISED_TP); } else { BNX2X_ERR("NVRAM config error. " @@ -6828,15 +7776,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) case PORT_FEATURE_LINK_SPEED_10G_CX4: case PORT_FEATURE_LINK_SPEED_10G_KX4: case PORT_FEATURE_LINK_SPEED_10G_KR: - if (!(bp->phy_flags & PHY_XGXS_FLAG)) { - BNX2X_ERR("NVRAM config error. " - "Invalid link_config 0x%x" - " phy_flags 0x%x\n", - bp->link_config, bp->phy_flags); - return; - } - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { + if (bp->supported & SUPPORTED_10000baseT_Full) { bp->req_line_speed = SPEED_10000; bp->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); @@ -6863,43 +7803,13 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) bp->req_flow_ctrl = (bp->link_config & PORT_FEATURE_FLOW_CONTROL_MASK); - /* Please refer to Table 28B-3 of the 802.3ab-1999 spec */ - switch (bp->req_flow_ctrl) { - case FLOW_CTRL_AUTO: + if ((bp->req_flow_ctrl == FLOW_CTRL_AUTO) && + (bp->supported & SUPPORTED_Autoneg)) bp->req_autoneg |= AUTONEG_FLOW_CTRL; - if (bp->dev->mtu <= 4500) { - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - } else { - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; - } - break; - - case FLOW_CTRL_TX: - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; - break; - - case FLOW_CTRL_RX: - case FLOW_CTRL_BOTH: - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; - case FLOW_CTRL_NONE: - default: - bp->pause_mode = PAUSE_NONE; - bp->advertising &= ~(ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; - } - BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x\n" - KERN_INFO " pause_mode %d advertising 0x%x\n", - bp->req_autoneg, bp->req_flow_ctrl, - bp->pause_mode, bp->advertising); + BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x" + " advertising 0x%x\n", + bp->req_autoneg, bp->req_flow_ctrl, bp->advertising); } static void bnx2x_get_hwinfo(struct bnx2x *bp) @@ -6933,15 +7843,15 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, validity_map[port]); if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - BNX2X_ERR("MCP validity signature bad\n"); + BNX2X_ERR("BAD MCP validity signature\n"); - bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) & + bp->fw_seq = (SHMEM_RD(bp, func_mb[port].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); - + bp->board = SHMEM_RD(bp, dev_info.shared_hw_config.board); bp->serdes_config = - SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config); + SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config); bp->lane_config = SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); bp->ext_phy_config = @@ -6954,13 +7864,13 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp) bp->link_config = SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); - BNX2X_DEV_INFO("hw_config (%08x) serdes_config (%08x)\n" + BNX2X_DEV_INFO("hw_config (%08x) board (%08x) serdes_config (%08x)\n" KERN_INFO " lane_config (%08x) ext_phy_config (%08x)\n" KERN_INFO " speed_cap_mask (%08x) link_config (%08x)" " fw_seq (%08x)\n", - bp->hw_config, bp->serdes_config, bp->lane_config, - bp->ext_phy_config, bp->speed_cap_mask, - bp->link_config, bp->fw_seq); + bp->hw_config, bp->board, bp->serdes_config, + bp->lane_config, bp->ext_phy_config, + bp->speed_cap_mask, bp->link_config, bp->fw_seq); switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK); bnx2x_link_settings_supported(bp, switch_cfg); @@ -7014,14 +7924,8 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp) return; set_mac: /* only supposed to happen on emulation/FPGA */ - BNX2X_ERR("warning constant MAC workaround active\n"); - bp->dev->dev_addr[0] = 0; - bp->dev->dev_addr[1] = 0x50; - bp->dev->dev_addr[2] = 0xc2; - bp->dev->dev_addr[3] = 0x2c; - bp->dev->dev_addr[4] = 0x71; - bp->dev->dev_addr[5] = port ? 0x0d : 0x0e; - + BNX2X_ERR("warning rendom MAC workaround active\n"); + random_ether_addr(bp->dev->dev_addr); memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6); } @@ -7048,19 +7952,34 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) } if (bp->phy_flags & PHY_XGXS_FLAG) { - cmd->port = PORT_FIBRE; - } else { + u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + + switch (ext_phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + cmd->port = PORT_FIBRE; + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + cmd->port = PORT_TP; + break; + + default: + DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); + } + } else cmd->port = PORT_TP; - } cmd->phy_address = bp->phy_addr; cmd->transceiver = XCVR_INTERNAL; - if (bp->req_autoneg & AUTONEG_SPEED) { + if (bp->req_autoneg & AUTONEG_SPEED) cmd->autoneg = AUTONEG_ENABLE; - } else { + else cmd->autoneg = AUTONEG_DISABLE; - } cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; @@ -7091,8 +8010,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) switch (cmd->port) { case PORT_TP: - if (!(bp->supported & SUPPORTED_TP)) + if (!(bp->supported & SUPPORTED_TP)) { + DP(NETIF_MSG_LINK, "TP not supported\n"); return -EINVAL; + } if (bp->phy_flags & PHY_XGXS_FLAG) { bnx2x_link_reset(bp); @@ -7102,8 +8023,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; case PORT_FIBRE: - if (!(bp->supported & SUPPORTED_FIBRE)) + if (!(bp->supported & SUPPORTED_FIBRE)) { + DP(NETIF_MSG_LINK, "FIBRE not supported\n"); return -EINVAL; + } if (!(bp->phy_flags & PHY_XGXS_FLAG)) { bnx2x_link_reset(bp); @@ -7113,12 +8036,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; default: + DP(NETIF_MSG_LINK, "Unknown port type\n"); return -EINVAL; } if (cmd->autoneg == AUTONEG_ENABLE) { - if (!(bp->supported & SUPPORTED_Autoneg)) + if (!(bp->supported & SUPPORTED_Autoneg)) { + DP(NETIF_MSG_LINK, "Aotoneg not supported\n"); return -EINVAL; + } /* advertise the requested speed and duplex if supported */ cmd->advertising &= bp->supported; @@ -7133,14 +8059,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) switch (cmd->speed) { case SPEED_10: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->supported & SUPPORTED_10baseT_Full)) + if (!(bp->supported & + SUPPORTED_10baseT_Full)) { + DP(NETIF_MSG_LINK, + "10M full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { - if (!(bp->supported & SUPPORTED_10baseT_Half)) + if (!(bp->supported & + SUPPORTED_10baseT_Half)) { + DP(NETIF_MSG_LINK, + "10M half not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_10baseT_Half | ADVERTISED_TP); @@ -7150,15 +8084,21 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) case SPEED_100: if (cmd->duplex == DUPLEX_FULL) { if (!(bp->supported & - SUPPORTED_100baseT_Full)) + SUPPORTED_100baseT_Full)) { + DP(NETIF_MSG_LINK, + "100M full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { if (!(bp->supported & - SUPPORTED_100baseT_Half)) + SUPPORTED_100baseT_Half)) { + DP(NETIF_MSG_LINK, + "100M half not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_100baseT_Half | ADVERTISED_TP); @@ -7166,39 +8106,54 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; case SPEED_1000: - if (cmd->duplex != DUPLEX_FULL) + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, "1G half not supported\n"); return -EINVAL; + } - if (!(bp->supported & SUPPORTED_1000baseT_Full)) + if (!(bp->supported & SUPPORTED_1000baseT_Full)) { + DP(NETIF_MSG_LINK, "1G full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_TP); break; case SPEED_2500: - if (cmd->duplex != DUPLEX_FULL) + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, + "2.5G half not supported\n"); return -EINVAL; + } - if (!(bp->supported & SUPPORTED_2500baseT_Full)) + if (!(bp->supported & SUPPORTED_2500baseX_Full)) { + DP(NETIF_MSG_LINK, + "2.5G full not supported\n"); return -EINVAL; + } - advertising = (ADVERTISED_2500baseT_Full | + advertising = (ADVERTISED_2500baseX_Full | ADVERTISED_TP); break; case SPEED_10000: - if (cmd->duplex != DUPLEX_FULL) + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, "10G half not supported\n"); return -EINVAL; + } - if (!(bp->supported & SUPPORTED_10000baseT_Full)) + if (!(bp->supported & SUPPORTED_10000baseT_Full)) { + DP(NETIF_MSG_LINK, "10G full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); break; default: + DP(NETIF_MSG_LINK, "Unsupported speed\n"); return -EINVAL; } @@ -7398,8 +8353,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp) static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val, u32 cmd_flags) { - int rc; - int count, i; + int count, i, rc; u32 val; /* build the command word */ @@ -7452,13 +8406,13 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf, if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { DP(NETIF_MSG_NVM, - "Invalid paramter: offset 0x%x buf_size 0x%x\n", + "Invalid parameter: offset 0x%x buf_size 0x%x\n", offset, buf_size); return -EINVAL; } if (offset + buf_size > bp->flash_size) { - DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +" " buf_size (0x%x) > flash_size (0x%x)\n", offset, buf_size, bp->flash_size); return -EINVAL; @@ -7519,8 +8473,7 @@ static int bnx2x_get_eeprom(struct net_device *dev, static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, u32 cmd_flags) { - int rc; - int count, i; + int count, i, rc; /* build the command word */ cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR; @@ -7557,7 +8510,7 @@ static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, return rc; } -#define BYTE_OFFSET(offset) (8 * (offset & 0x03)) +#define BYTE_OFFSET(offset) (8 * (offset & 0x03)) static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf, int buf_size) @@ -7568,7 +8521,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf, u32 val; if (offset + buf_size > bp->flash_size) { - DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +" " buf_size (0x%x) > flash_size (0x%x)\n", offset, buf_size, bp->flash_size); return -EINVAL; @@ -7621,13 +8574,13 @@ static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf, if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { DP(NETIF_MSG_NVM, - "Invalid paramter: offset 0x%x buf_size 0x%x\n", + "Invalid parameter: offset 0x%x buf_size 0x%x\n", offset, buf_size); return -EINVAL; } if (offset + buf_size > bp->flash_size) { - DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +" " buf_size (0x%x) > flash_size (0x%x)\n", offset, buf_size, bp->flash_size); return -EINVAL; @@ -7788,52 +8741,29 @@ static int bnx2x_set_pauseparam(struct net_device *dev, DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); - bp->req_flow_ctrl = FLOW_CTRL_AUTO; if (epause->autoneg) { - bp->req_autoneg |= AUTONEG_FLOW_CTRL; - if (bp->dev->mtu <= 4500) { - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - } else { - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; + if (!(bp->supported & SUPPORTED_Autoneg)) { + DP(NETIF_MSG_LINK, "Aotoneg not supported\n"); + return -EINVAL; } - } else { + bp->req_autoneg |= AUTONEG_FLOW_CTRL; + } else bp->req_autoneg &= ~AUTONEG_FLOW_CTRL; - if (epause->rx_pause) - bp->req_flow_ctrl |= FLOW_CTRL_RX; - if (epause->tx_pause) - bp->req_flow_ctrl |= FLOW_CTRL_TX; - - switch (bp->req_flow_ctrl) { - case FLOW_CTRL_AUTO: - bp->req_flow_ctrl = FLOW_CTRL_NONE; - bp->pause_mode = PAUSE_NONE; - bp->advertising &= ~(ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; + bp->req_flow_ctrl = FLOW_CTRL_AUTO; - case FLOW_CTRL_TX: - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; - break; + if (epause->rx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_RX; + if (epause->tx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_TX; - case FLOW_CTRL_RX: - case FLOW_CTRL_BOTH: - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; - } - } + if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) && + (bp->req_flow_ctrl == FLOW_CTRL_AUTO)) + bp->req_flow_ctrl = FLOW_CTRL_NONE; - DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n" - DP_LEVEL " pause_mode %d advertising 0x%x\n", - bp->req_autoneg, bp->req_flow_ctrl, bp->pause_mode, - bp->advertising); + DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n", + bp->req_autoneg, bp->req_flow_ctrl); bnx2x_stop_stats(bp); bnx2x_link_initialize(bp); @@ -7906,81 +8836,87 @@ static void bnx2x_self_test(struct net_device *dev, static struct { char string[ETH_GSTRING_LEN]; } bnx2x_stats_str_arr[BNX2X_NUM_STATS] = { - { "rx_bytes"}, /* 0 */ - { "rx_error_bytes"}, /* 1 */ - { "tx_bytes"}, /* 2 */ - { "tx_error_bytes"}, /* 3 */ - { "rx_ucast_packets"}, /* 4 */ - { "rx_mcast_packets"}, /* 5 */ - { "rx_bcast_packets"}, /* 6 */ - { "tx_ucast_packets"}, /* 7 */ - { "tx_mcast_packets"}, /* 8 */ - { "tx_bcast_packets"}, /* 9 */ - { "tx_mac_errors"}, /* 10 */ - { "tx_carrier_errors"}, /* 11 */ - { "rx_crc_errors"}, /* 12 */ - { "rx_align_errors"}, /* 13 */ - { "tx_single_collisions"}, /* 14 */ - { "tx_multi_collisions"}, /* 15 */ - { "tx_deferred"}, /* 16 */ - { "tx_excess_collisions"}, /* 17 */ - { "tx_late_collisions"}, /* 18 */ - { "tx_total_collisions"}, /* 19 */ - { "rx_fragments"}, /* 20 */ - { "rx_jabbers"}, /* 21 */ - { "rx_undersize_packets"}, /* 22 */ - { "rx_oversize_packets"}, /* 23 */ - { "rx_xon_frames"}, /* 24 */ - { "rx_xoff_frames"}, /* 25 */ - { "tx_xon_frames"}, /* 26 */ - { "tx_xoff_frames"}, /* 27 */ - { "rx_mac_ctrl_frames"}, /* 28 */ - { "rx_filtered_packets"}, /* 29 */ - { "rx_discards"}, /* 30 */ + { "rx_bytes"}, + { "rx_error_bytes"}, + { "tx_bytes"}, + { "tx_error_bytes"}, + { "rx_ucast_packets"}, + { "rx_mcast_packets"}, + { "rx_bcast_packets"}, + { "tx_ucast_packets"}, + { "tx_mcast_packets"}, + { "tx_bcast_packets"}, + { "tx_mac_errors"}, /* 10 */ + { "tx_carrier_errors"}, + { "rx_crc_errors"}, + { "rx_align_errors"}, + { "tx_single_collisions"}, + { "tx_multi_collisions"}, + { "tx_deferred"}, + { "tx_excess_collisions"}, + { "tx_late_collisions"}, + { "tx_total_collisions"}, + { "rx_fragments"}, /* 20 */ + { "rx_jabbers"}, + { "rx_undersize_packets"}, + { "rx_oversize_packets"}, + { "rx_xon_frames"}, + { "rx_xoff_frames"}, + { "tx_xon_frames"}, + { "tx_xoff_frames"}, + { "rx_mac_ctrl_frames"}, + { "rx_filtered_packets"}, + { "rx_discards"}, /* 30 */ + { "brb_discard"}, + { "brb_truncate"}, + { "xxoverflow"} }; #define STATS_OFFSET32(offset_name) \ (offsetof(struct bnx2x_eth_stats, offset_name) / 4) static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = { - STATS_OFFSET32(total_bytes_received_hi), /* 0 */ - STATS_OFFSET32(stat_IfHCInBadOctets_hi), /* 1 */ - STATS_OFFSET32(total_bytes_transmitted_hi), /* 2 */ - STATS_OFFSET32(stat_IfHCOutBadOctets_hi), /* 3 */ - STATS_OFFSET32(total_unicast_packets_received_hi), /* 4 */ - STATS_OFFSET32(total_multicast_packets_received_hi), /* 5 */ - STATS_OFFSET32(total_broadcast_packets_received_hi), /* 6 */ - STATS_OFFSET32(total_unicast_packets_transmitted_hi), /* 7 */ - STATS_OFFSET32(total_multicast_packets_transmitted_hi), /* 8 */ - STATS_OFFSET32(total_broadcast_packets_transmitted_hi), /* 9 */ - STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */ - STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), /* 11 */ - STATS_OFFSET32(crc_receive_errors), /* 12 */ - STATS_OFFSET32(alignment_errors), /* 13 */ - STATS_OFFSET32(single_collision_transmit_frames), /* 14 */ - STATS_OFFSET32(multiple_collision_transmit_frames), /* 15 */ - STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), /* 16 */ - STATS_OFFSET32(excessive_collision_frames), /* 17 */ - STATS_OFFSET32(late_collision_frames), /* 18 */ - STATS_OFFSET32(number_of_bugs_found_in_stats_spec), /* 19 */ - STATS_OFFSET32(runt_packets_received), /* 20 */ - STATS_OFFSET32(jabber_packets_received), /* 21 */ - STATS_OFFSET32(error_runt_packets_received), /* 22 */ - STATS_OFFSET32(error_jabber_packets_received), /* 23 */ - STATS_OFFSET32(pause_xon_frames_received), /* 24 */ - STATS_OFFSET32(pause_xoff_frames_received), /* 25 */ - STATS_OFFSET32(pause_xon_frames_transmitted), /* 26 */ - STATS_OFFSET32(pause_xoff_frames_transmitted), /* 27 */ - STATS_OFFSET32(control_frames_received), /* 28 */ - STATS_OFFSET32(mac_filter_discard), /* 29 */ - STATS_OFFSET32(no_buff_discard), /* 30 */ + STATS_OFFSET32(total_bytes_received_hi), + STATS_OFFSET32(stat_IfHCInBadOctets_hi), + STATS_OFFSET32(total_bytes_transmitted_hi), + STATS_OFFSET32(stat_IfHCOutBadOctets_hi), + STATS_OFFSET32(total_unicast_packets_received_hi), + STATS_OFFSET32(total_multicast_packets_received_hi), + STATS_OFFSET32(total_broadcast_packets_received_hi), + STATS_OFFSET32(total_unicast_packets_transmitted_hi), + STATS_OFFSET32(total_multicast_packets_transmitted_hi), + STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */ + STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), + STATS_OFFSET32(crc_receive_errors), + STATS_OFFSET32(alignment_errors), + STATS_OFFSET32(single_collision_transmit_frames), + STATS_OFFSET32(multiple_collision_transmit_frames), + STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), + STATS_OFFSET32(excessive_collision_frames), + STATS_OFFSET32(late_collision_frames), + STATS_OFFSET32(number_of_bugs_found_in_stats_spec), + STATS_OFFSET32(runt_packets_received), /* 20 */ + STATS_OFFSET32(jabber_packets_received), + STATS_OFFSET32(error_runt_packets_received), + STATS_OFFSET32(error_jabber_packets_received), + STATS_OFFSET32(pause_xon_frames_received), + STATS_OFFSET32(pause_xoff_frames_received), + STATS_OFFSET32(pause_xon_frames_transmitted), + STATS_OFFSET32(pause_xoff_frames_transmitted), + STATS_OFFSET32(control_frames_received), + STATS_OFFSET32(mac_filter_discard), + STATS_OFFSET32(no_buff_discard), /* 30 */ + STATS_OFFSET32(brb_discard), + STATS_OFFSET32(brb_truncate_discard), + STATS_OFFSET32(xxoverflow_discard) }; static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = { 8, 0, 8, 0, 8, 8, 8, 8, 8, 8, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, + 4, 4, 4, 4 }; static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) @@ -8138,9 +9074,7 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) * net_device service functions */ -/* Called with rtnl_lock from vlan functions and also netif_tx_lock - * from set_multicast. - */ +/* called with netif_tx_lock from set_multicast */ static void bnx2x_set_rx_mode(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); @@ -8314,7 +9248,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) ETH_TX_BD_ETH_ADDR_TYPE_SHIFT); tx_bd->general_data |= 1; /* header nbd */ - /* remeber the first bd of the packet */ + /* remember the first bd of the packet */ tx_buf->first_bd = bd_prod; DP(NETIF_MSG_TX_QUEUED, @@ -8334,7 +9268,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) /* for now NS flag is not used in Linux */ pbd->global_data = (len | - ((skb->protocol == ETH_P_8021Q) << + ((skb->protocol == ntohs(ETH_P_8021Q)) << ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); pbd->ip_hlen = ip_hdrlen(skb) / 2; pbd->total_hlen = cpu_to_le16(len + pbd->ip_hlen); @@ -8343,7 +9277,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_TCP_CSUM; - pbd->tcp_flags = htonl(tcp_flag_word(skb)) & 0xFFFF; + pbd->tcp_flags = pbd_tcp_flags(skb); pbd->total_hlen += cpu_to_le16(tcp_hdrlen(skb) / 2); pbd->tcp_pseudo_csum = swab16(th->check); @@ -8387,7 +9321,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb_shinfo(skb)->gso_size && (skb->len > (bp->dev->mtu + ETH_HLEN))) { - int hlen = 2 * le32_to_cpu(pbd->total_hlen); + int hlen = 2 * le16_to_cpu(pbd->total_hlen); DP(NETIF_MSG_TX_QUEUED, "TSO packet len %d hlen %d total len %d tso size %d\n", @@ -8427,7 +9361,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_bd->vlan = cpu_to_le16(pkt_prod); /* this marks the bd * as one that has no individual mapping - * the FW ignors this flag in a bd not maked start + * the FW ignores this flag in a bd not marked start */ tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO; DP(NETIF_MSG_TX_QUEUED, @@ -8504,9 +9438,11 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %u bd %d\n", nbd, bd_prod); - fp->hw_tx_prods->bds_prod += cpu_to_le16(nbd); + fp->hw_tx_prods->bds_prod = + cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd); mb(); /* FW restriction: must not reorder writing nbd and packets */ - fp->hw_tx_prods->packets_prod += cpu_to_le32(1); + fp->hw_tx_prods->packets_prod = + cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1); DOORBELL(bp, fp_index, 0); mmiowb(); @@ -8525,11 +9461,6 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static struct net_device_stats *bnx2x_get_stats(struct net_device *dev) -{ - return &dev->stats; -} - /* Called with rtnl_lock */ static int bnx2x_open(struct net_device *dev) { @@ -8543,16 +9474,13 @@ static int bnx2x_open(struct net_device *dev) /* Called with rtnl_lock */ static int bnx2x_close(struct net_device *dev) { - int rc; struct bnx2x *bp = netdev_priv(dev); /* Unload the driver, release IRQs */ - rc = bnx2x_nic_unload(bp, 1); - if (rc) { - BNX2X_ERR("bnx2x_nic_unload failed: %d\n", rc); - return rc; - } - bnx2x_set_power_state(bp, PCI_D3hot); + bnx2x_nic_unload(bp, 1); + + if (!CHIP_REV_IS_SLOW(bp)) + bnx2x_set_power_state(bp, PCI_D3hot); return 0; } @@ -8584,7 +9512,7 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIPHY: data->phy_id = bp->phy_addr; - /* fallthru */ + /* fallthrough */ case SIOCGMIIREG: { u32 mii_regval; @@ -8633,7 +9561,7 @@ static int bnx2x_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; /* This does not race with packet allocation - * because the actuall alloc size is + * because the actual alloc size is * only updated as part of load */ dev->mtu = new_mtu; @@ -8666,7 +9594,7 @@ static void bnx2x_vlan_rx_register(struct net_device *dev, bp->vlgrp = vlgrp; if (netif_running(dev)) - bnx2x_set_rx_mode(dev); + bnx2x_set_client_config(bp); } #endif @@ -8695,14 +9623,18 @@ static void bnx2x_reset_task(struct work_struct *work) if (!netif_running(bp->dev)) return; - bp->in_reset_task = 1; + rtnl_lock(); - bnx2x_netif_stop(bp); + if (bp->state != BNX2X_STATE_OPEN) { + DP(NETIF_MSG_TX_ERR, "state is %x, returning\n", bp->state); + goto reset_task_exit; + } bnx2x_nic_unload(bp, 0); bnx2x_nic_load(bp, 0); - bp->in_reset_task = 0; +reset_task_exit: + rtnl_unlock(); } static int __devinit bnx2x_init_board(struct pci_dev *pdev, @@ -8783,8 +9715,6 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev, spin_lock_init(&bp->phy_lock); - bp->in_reset_task = 0; - INIT_WORK(&bp->reset_task, bnx2x_reset_task); INIT_WORK(&bp->sp_task, bnx2x_sp_task); @@ -8813,7 +9743,7 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev, bnx2x_get_hwinfo(bp); if (CHIP_REV(bp) == CHIP_REV_FPGA) { - printk(KERN_ERR PFX "FPGA detacted. MCP disabled," + printk(KERN_ERR PFX "FPGA detected. MCP disabled," " will only init first device\n"); onefunc = 1; nomcp = 1; @@ -8882,14 +9812,32 @@ err_out: return rc; } +static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL); + + val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT; + return val; +} + +/* return value of 1=2.5GHz 2=5GHz */ +static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL); + + val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; + return val; +} + static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int version_printed; struct net_device *dev = NULL; struct bnx2x *bp; - int rc, i; + int rc; int port = PCI_FUNC(pdev->devfn); + DECLARE_MAC_BUF(mac); if (version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -8906,6 +9854,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, if (port && onefunc) { printk(KERN_ERR PFX "second function disabled. exiting\n"); + free_netdev(dev); return 0; } @@ -8918,7 +9867,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, dev->hard_start_xmit = bnx2x_start_xmit; dev->watchdog_timeo = TX_TIMEOUT; - dev->get_stats = bnx2x_get_stats; dev->ethtool_ops = &bnx2x_ethtool_ops; dev->open = bnx2x_open; dev->stop = bnx2x_close; @@ -8944,7 +9892,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, rc = register_netdev(dev); if (rc) { - printk(KERN_ERR PFX "Cannot register net device\n"); + dev_err(&pdev->dev, "Cannot register net device\n"); if (bp->regview) iounmap(bp->regview); if (bp->doorbells) @@ -8959,32 +9907,30 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); bp->name = board_info[ent->driver_data].name; - printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz " - "found at mem %lx, IRQ %d, ", - dev->name, bp->name, + printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx," + " IRQ %d, ", dev->name, bp->name, ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', ((CHIP_ID(bp) & 0x0ff0) >> 4), - ((bp->flags & PCIX_FLAG) ? "-X" : ""), - ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), - bp->bus_speed_mhz, - dev->base_addr, - bp->pdev->irq); - - printk("node addr "); - for (i = 0; i < 6; i++) - printk("%2.2x", dev->dev_addr[i]); - printk("\n"); - + bnx2x_get_pcie_width(bp), + (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz", + dev->base_addr, bp->pdev->irq); + printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr)); return 0; } static void __devexit bnx2x_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp = netdev_priv(dev); + struct bnx2x *bp; + + if (!dev) { + /* we get here if init_one() fails */ + printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n"); + return; + } + + bp = netdev_priv(dev); - flush_scheduled_work(); - /*tasklet_kill(&bp->sp_task);*/ unregister_netdev(dev); if (bp->regview) @@ -9002,34 +9948,43 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp = netdev_priv(dev); - int rc; + struct bnx2x *bp; + + if (!dev) + return 0; if (!netif_running(dev)) return 0; - rc = bnx2x_nic_unload(bp, 0); - if (!rc) - return rc; + bp = netdev_priv(dev); + + bnx2x_nic_unload(bp, 0); netif_device_detach(dev); - pci_save_state(pdev); + pci_save_state(pdev); bnx2x_set_power_state(bp, pci_choose_state(pdev, state)); + return 0; } static int bnx2x_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp = netdev_priv(dev); + struct bnx2x *bp; int rc; + if (!dev) { + printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n"); + return -ENODEV; + } + if (!netif_running(dev)) return 0; - pci_restore_state(pdev); + bp = netdev_priv(dev); + pci_restore_state(pdev); bnx2x_set_power_state(bp, PCI_D0); netif_device_attach(dev); diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 4f7ae6f7745..4f0c0d31e7c 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -1,6 +1,6 @@ /* bnx2x.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,8 @@ #define BNX2X_MSG_STATS 0x20000 /* was: NETIF_MSG_TIMER */ #define NETIF_MSG_NVM 0x40000 /* was: NETIF_MSG_HW */ #define NETIF_MSG_DMAE 0x80000 /* was: NETIF_MSG_HW */ +#define BNX2X_MSG_SP 0x100000 /* was: NETIF_MSG_INTR */ +#define BNX2X_MSG_FP 0x200000 /* was: NETIF_MSG_INTR */ #define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */ @@ -40,6 +42,12 @@ __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \ } while (0) +/* for logging (never masked) */ +#define BNX2X_LOG(__fmt, __args...) do { \ + printk(KERN_NOTICE "[%s:%d(%s)]" __fmt, __FUNCTION__, \ + __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \ + } while (0) + /* before we have a dev->name use dev_info() */ #define BNX2X_DEV_INFO(__fmt, __args...) do { \ if (bp->msglevel & NETIF_MSG_PROBE) \ @@ -423,8 +431,6 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_OPEN 0xa0000 #define BNX2X_FP_STATE_HALTING 0xb0000 #define BNX2X_FP_STATE_HALTED 0xc0000 -#define BNX2X_FP_STATE_DELETED 0xd0000 -#define BNX2X_FP_STATE_CLOSE_IRQ 0xe0000 int index; @@ -505,7 +511,6 @@ struct bnx2x { struct eth_spe *spq; dma_addr_t spq_mapping; u16 spq_prod_idx; - u16 dsb_sp_prod_idx; struct eth_spe *spq_prod_bd; struct eth_spe *spq_last_bd; u16 *dsb_sp_prod; @@ -517,7 +522,7 @@ struct bnx2x { */ u8 stat_pending; - /* End of fileds used in the performance code paths */ + /* End of fields used in the performance code paths */ int panic; int msglevel; @@ -540,8 +545,6 @@ struct bnx2x { spinlock_t phy_lock; struct work_struct reset_task; - u16 in_reset_task; - struct work_struct sp_task; struct timer_list timer; @@ -555,7 +558,6 @@ struct bnx2x { #define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0) #define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000) -#define CHIP_NUM_5710 0x57100000 #define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000) #define CHIP_REV_Ax 0x00000000 @@ -574,7 +576,8 @@ struct bnx2x { u32 fw_mb; u32 hw_config; - u32 serdes_config; + u32 board; + u32 serdes_config; u32 lane_config; u32 ext_phy_config; #define XGXS_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \ @@ -595,11 +598,11 @@ struct bnx2x { u8 tx_lane_swap; u8 link_up; + u8 phy_link_up; u32 supported; /* link settings - missing defines */ #define SUPPORTED_2500baseT_Full (1 << 15) -#define SUPPORTED_CX4 (1 << 16) u32 phy_flags; /*#define PHY_SERDES_FLAG 0x1*/ @@ -644,16 +647,9 @@ struct bnx2x { #define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH #define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE - u32 pause_mode; -#define PAUSE_NONE 0 -#define PAUSE_SYMMETRIC 1 -#define PAUSE_ASYMMETRIC 2 -#define PAUSE_BOTH 3 - u32 advertising; /* link settings - missing defines */ #define ADVERTISED_2500baseT_Full (1 << 15) -#define ADVERTISED_CX4 (1 << 16) u32 link_status; u32 line_speed; @@ -667,6 +663,8 @@ struct bnx2x { #define NVRAM_TIMEOUT_COUNT 30000 #define NVRAM_PAGE_SIZE 256 + u8 wol; + int rx_ring_size; u16 tx_quick_cons_trip_int; @@ -718,9 +716,6 @@ struct bnx2x { #endif char *name; - u16 bus_speed_mhz; - u8 wol; - u8 pad; /* used to synchronize stats collecting */ int stats_state; @@ -856,8 +851,8 @@ struct bnx2x { #define MAX_SPQ_PENDING 8 -#define BNX2X_NUM_STATS 31 -#define BNX2X_NUM_TESTS 2 +#define BNX2X_NUM_STATS 34 +#define BNX2X_NUM_TESTS 1 #define DPM_TRIGER_TYPE 0x40 @@ -867,6 +862,15 @@ struct bnx2x { DPM_TRIGER_TYPE); \ } while (0) +/* PCIE link and speed */ +#define PCICFG_LINK_WIDTH 0x1f00000 +#define PCICFG_LINK_WIDTH_SHIFT 20 +#define PCICFG_LINK_SPEED 0xf0000 +#define PCICFG_LINK_SPEED_SHIFT 16 + +#define BMAC_CONTROL_RX_ENABLE 2 + +#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff) /* stuff added to make the code fit 80Col */ @@ -939,13 +943,13 @@ struct bnx2x { #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD -#define NIG_STATUS_INTERRUPT_XGXS0_LINK10G \ +#define NIG_STATUS_XGXS0_LINK10G \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G -#define NIG_XGXS0_LINK_STATUS \ +#define NIG_STATUS_XGXS0_LINK_STATUS \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS -#define NIG_XGXS0_LINK_STATUS_SIZE \ +#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE -#define NIG_SERDES0_LINK_STATUS \ +#define NIG_STATUS_SERDES0_LINK_STATUS \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS #define NIG_MASK_MI_INT \ NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h index 62a6eb81025..3b968904ca6 100644 --- a/drivers/net/bnx2x_fw_defs.h +++ b/drivers/net/bnx2x_fw_defs.h @@ -1,6 +1,6 @@ /* bnx2x_fw_defs.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h index 6fd959c34d1..b21075ccb52 100644 --- a/drivers/net/bnx2x_hsi.h +++ b/drivers/net/bnx2x_hsi.h @@ -1,6 +1,6 @@ /* bnx2x_hsi.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -8,169 +8,9 @@ */ -#define FUNC_0 0 -#define FUNC_1 1 -#define FUNC_MAX 2 - - -/* This value (in milliseconds) determines the frequency of the driver - * issuing the PULSE message code. The firmware monitors this periodic - * pulse to determine when to switch to an OS-absent mode. */ -#define DRV_PULSE_PERIOD_MS 250 - -/* This value (in milliseconds) determines how long the driver should - * wait for an acknowledgement from the firmware before timing out. Once - * the firmware has timed out, the driver will assume there is no firmware - * running and there won't be any firmware-driver synchronization during a - * driver reset. */ -#define FW_ACK_TIME_OUT_MS 5000 - -#define FW_ACK_POLL_TIME_MS 1 - -#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS) - -/* LED Blink rate that will achieve ~15.9Hz */ -#define LED_BLINK_RATE_VAL 480 - -/**************************************************************************** - * Driver <-> FW Mailbox * - ****************************************************************************/ -struct drv_fw_mb { - u32 drv_mb_header; -#define DRV_MSG_CODE_MASK 0xffff0000 -#define DRV_MSG_CODE_LOAD_REQ 0x10000000 -#define DRV_MSG_CODE_LOAD_DONE 0x11000000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000 -#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000 -#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000 -#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000 -#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000 -#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000 -#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000 -#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 -#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 - -#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff - - u32 drv_mb_param; - - u32 fw_mb_header; -#define FW_MSG_CODE_MASK 0xffff0000 -#define FW_MSG_CODE_DRV_LOAD_COMMON 0x11000000 -#define FW_MSG_CODE_DRV_LOAD_PORT 0x12000000 -#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x13000000 -#define FW_MSG_CODE_DRV_LOAD_DONE 0x14000000 -#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x21000000 -#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x22000000 -#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x23000000 -#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50000000 -#define FW_MSG_CODE_DIAG_REFUSE 0x51000000 -#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70000000 -#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x71000000 -#define FW_MSG_CODE_GET_KEY_DONE 0x80000000 -#define FW_MSG_CODE_NO_KEY 0x8f000000 -#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x8f800000 -#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90000000 -#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x91000000 -#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x92000000 -#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x93000000 -#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x94000000 - -#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff - - u32 fw_mb_param; - - u32 link_status; - /* Driver should update this field on any link change event */ - -#define LINK_STATUS_LINK_FLAG_MASK 0x00000001 -#define LINK_STATUS_LINK_UP 0x00000001 -#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E -#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1) - -#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020 -#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 - -#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 -#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080 -#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 - -#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 -#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 -#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800 -#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000 -#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000 -#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000 -#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000 - -#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000 -#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000 - -#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000 -#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000 - -#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 -#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18) -#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18) -#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18) -#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18) - -#define LINK_STATUS_SERDES_LINK 0x00100000 - -#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000 -#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000 -#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 -#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000 -#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000 -#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000 -#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000 -#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000 - - u32 drv_pulse_mb; -#define DRV_PULSE_SEQ_MASK 0x00007fff -#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 - /* The system time is in the format of - * (year-2001)*12*32 + month*32 + day. */ -#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 - /* Indicate to the firmware not to go into the - * OS-absent when it is not getting driver pulse. - * This is used for debugging as well for PXE(MBA). */ - - u32 mcp_pulse_mb; -#define MCP_PULSE_SEQ_MASK 0x00007fff -#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 - /* Indicates to the driver not to assert due to lack - * of MCP response */ -#define MCP_EVENT_MASK 0xffff0000 -#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 - -}; - +#define PORT_0 0 +#define PORT_1 1 +#define PORT_MAX 2 /**************************************************************************** * Shared HW configuration * @@ -249,7 +89,7 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_SMBUS_TIMING_100KHZ 0x00000000 #define SHARED_HW_CFG_SMBUS_TIMING_400KHZ 0x00001000 -#define SHARED_HW_CFG_HIDE_FUNC1 0x00002000 +#define SHARED_HW_CFG_HIDE_PORT1 0x00002000 u32 power_dissipated; /* 0x11c */ #define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000 @@ -290,6 +130,8 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006 #define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007 #define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a #define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000 #define SHARED_HW_CFG_BOARD_VER_SHIFT 16 @@ -304,13 +146,12 @@ struct shared_hw_cfg { /* NVRAM Offset */ }; + /**************************************************************************** * Port HW configuration * ****************************************************************************/ -struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */ +struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ - /* Fields below are port specific (in anticipation of dual port - devices */ u32 pci_id; #define PORT_HW_CFG_PCI_VENDOR_ID_MASK 0xffff0000 #define PORT_HW_CFG_PCI_DEVICE_ID_MASK 0x0000ffff @@ -420,6 +261,8 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */ #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00 #define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK 0x000000ff @@ -462,11 +305,13 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */ }; + /**************************************************************************** * Shared Feature configuration * ****************************************************************************/ struct shared_feat_cfg { /* NVRAM Offset */ - u32 bmc_common; /* 0x450 */ + + u32 config; /* 0x450 */ #define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001 }; @@ -475,7 +320,8 @@ struct shared_feat_cfg { /* NVRAM Offset */ /**************************************************************************** * Port Feature configuration * ****************************************************************************/ -struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */ +struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ + u32 config; #define PORT_FEATURE_BAR1_SIZE_MASK 0x0000000f #define PORT_FEATURE_BAR1_SIZE_SHIFT 0 @@ -609,8 +455,7 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */ #define PORT_FEATURE_SMBUS_ADDR_MASK 0x000000fe #define PORT_FEATURE_SMBUS_ADDR_SHIFT 1 - u32 iscsib_boot_cfg; -#define PORT_FEATURE_ISCSIB_SKIP_TARGET_BOOT 0x00000001 + u32 reserved1; u32 link_config; /* Used as HW defaults for the driver */ #define PORT_FEATURE_CONNECTED_SWITCH_MASK 0x03000000 @@ -657,20 +502,201 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */ }; +/***************************************************************************** + * Device Information * + *****************************************************************************/ +struct dev_info { /* size */ + + u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */ + + struct shared_hw_cfg shared_hw_config; /* 40 */ + + struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */ + + struct shared_feat_cfg shared_feature_config; /* 4 */ + + struct port_feat_cfg port_feature_config[PORT_MAX]; /* 116*2=232 */ + +}; + + +#define FUNC_0 0 +#define FUNC_1 1 +#define E1_FUNC_MAX 2 +#define FUNC_MAX E1_FUNC_MAX + + +/* This value (in milliseconds) determines the frequency of the driver + * issuing the PULSE message code. The firmware monitors this periodic + * pulse to determine when to switch to an OS-absent mode. */ +#define DRV_PULSE_PERIOD_MS 250 + +/* This value (in milliseconds) determines how long the driver should + * wait for an acknowledgement from the firmware before timing out. Once + * the firmware has timed out, the driver will assume there is no firmware + * running and there won't be any firmware-driver synchronization during a + * driver reset. */ +#define FW_ACK_TIME_OUT_MS 5000 + +#define FW_ACK_POLL_TIME_MS 1 + +#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS) + +/* LED Blink rate that will achieve ~15.9Hz */ +#define LED_BLINK_RATE_VAL 480 + /**************************************************************************** - * Device Information * + * Driver <-> FW Mailbox * ****************************************************************************/ -struct dev_info { /* size */ +struct drv_port_mb { + + u32 link_status; + /* Driver should update this field on any link change event */ + +#define LINK_STATUS_LINK_FLAG_MASK 0x00000001 +#define LINK_STATUS_LINK_UP 0x00000001 +#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E +#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1) + +#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020 +#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 + +#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 +#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080 +#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 + +#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 +#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 +#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800 +#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000 +#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000 +#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000 +#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000 + +#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000 +#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000 + +#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000 +#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000 + +#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 +#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18) +#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18) +#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18) +#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18) + +#define LINK_STATUS_SERDES_LINK 0x00100000 + +#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000 +#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000 +#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 +#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000 +#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000 +#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000 +#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000 +#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000 - u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */ + u32 reserved[3]; - struct shared_hw_cfg shared_hw_config; /* 40 */ +}; + + +struct drv_func_mb { + + u32 drv_mb_header; +#define DRV_MSG_CODE_MASK 0xffff0000 +#define DRV_MSG_CODE_LOAD_REQ 0x10000000 +#define DRV_MSG_CODE_LOAD_DONE 0x11000000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000 +#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000 +#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000 +#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000 +#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000 +#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000 +#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000 +#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 +#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 + +#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff + + u32 drv_mb_param; + + u32 fw_mb_header; +#define FW_MSG_CODE_MASK 0xffff0000 +#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000 +#define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000 +#define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000 +#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000 +#define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000 +#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000 +#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x20110000 +#define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 0x20120000 +#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x21100000 +#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50100000 +#define FW_MSG_CODE_DIAG_REFUSE 0x50200000 +#define FW_MSG_CODE_DIAG_EXIT_DONE 0x60100000 +#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70100000 +#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x70200000 +#define FW_MSG_CODE_GET_KEY_DONE 0x80100000 +#define FW_MSG_CODE_NO_KEY 0x80f00000 +#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x80f80000 +#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90100000 +#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x90210000 +#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000 +#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000 +#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000 + +#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff + + u32 fw_mb_param; + + u32 drv_pulse_mb; +#define DRV_PULSE_SEQ_MASK 0x00007fff +#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 + /* The system time is in the format of + * (year-2001)*12*32 + month*32 + day. */ +#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 + /* Indicate to the firmware not to go into the + * OS-absent when it is not getting driver pulse. + * This is used for debugging as well for PXE(MBA). */ - struct port_hw_cfg port_hw_config[FUNC_MAX]; /* 400*2=800 */ + u32 mcp_pulse_mb; +#define MCP_PULSE_SEQ_MASK 0x00007fff +#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 + /* Indicates to the driver not to assert due to lack + * of MCP response */ +#define MCP_EVENT_MASK 0xffff0000 +#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 - struct shared_feat_cfg shared_feature_config; /* 4 */ + u32 iscsi_boot_signature; + u32 iscsi_boot_block_offset; - struct port_feat_cfg port_feature_config[FUNC_MAX];/* 116*2=232 */ + u32 reserved[3]; }; @@ -678,9 +704,8 @@ struct dev_info { /* size */ /**************************************************************************** * Management firmware state * ****************************************************************************/ -/* Allocate 320 bytes for management firmware: still not known exactly - * how much IMD needs. */ -#define MGMTFW_STATE_WORD_SIZE 80 +/* Allocate 440 bytes for management firmware */ +#define MGMTFW_STATE_WORD_SIZE 110 struct mgmtfw_state { u32 opaque[MGMTFW_STATE_WORD_SIZE]; @@ -691,31 +716,40 @@ struct mgmtfw_state { * Shared Memory Region * ****************************************************************************/ struct shmem_region { /* SharedMem Offset (size) */ - u32 validity_map[FUNC_MAX]; /* 0x0 (4 * 2 = 0x8) */ -#define SHR_MEM_VALIDITY_PCI_CFG 0x00000001 -#define SHR_MEM_VALIDITY_MB 0x00000002 -#define SHR_MEM_VALIDITY_DEV_INFO 0x00000004 + + u32 validity_map[PORT_MAX]; /* 0x0 (4*2 = 0x8) */ +#define SHR_MEM_FORMAT_REV_ID ('A'<<24) +#define SHR_MEM_FORMAT_REV_MASK 0xff000000 + /* validity bits */ +#define SHR_MEM_VALIDITY_PCI_CFG 0x00100000 +#define SHR_MEM_VALIDITY_MB 0x00200000 +#define SHR_MEM_VALIDITY_DEV_INFO 0x00400000 +#define SHR_MEM_VALIDITY_RESERVED 0x00000007 /* One licensing bit should be set */ #define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038 #define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008 #define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010 #define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020 + /* Active MFW */ +#define SHR_MEM_VALIDITY_ACTIVE_MFW_UNKNOWN 0x00000000 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_IPMI 0x00000040 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_UMP 0x00000080 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_NCSI 0x000000c0 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0 - struct drv_fw_mb drv_fw_mb[FUNC_MAX]; /* 0x8 (28 * 2 = 0x38) */ - - struct dev_info dev_info; /* 0x40 (0x438) */ + struct dev_info dev_info; /* 0x8 (0x438) */ -#ifdef _LICENSE_H - license_key_t drv_lic_key[FUNC_MAX]; /* 0x478 (52 * 2 = 0x68) */ -#else /* Linux! */ - u8 reserved[52*FUNC_MAX]; -#endif + u8 reserved[52*PORT_MAX]; /* FW information (for internal FW use) */ - u32 fw_info_fio_offset; /* 0x4e0 (0x4) */ - struct mgmtfw_state mgmtfw_state; /* 0x4e4 (0x140) */ + u32 fw_info_fio_offset; /* 0x4a8 (0x4) */ + struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */ + + struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */ + struct drv_func_mb func_mb[FUNC_MAX]; /* 0x684 (44*2=0x58) */ -}; /* 0x624 */ +}; /* 0x6dc */ #define BCM_5710_FW_MAJOR_VERSION 4 diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index 04f93bff2ef..dcaecc53bdb 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h @@ -1,6 +1,6 @@ /* bnx2x_init.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -409,7 +409,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp) pci_read_config_word(bp->pdev, bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val); - DP(NETIF_MSG_HW, "read 0x%x from devctl\n", val); + DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val); w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5); r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12); @@ -472,10 +472,14 @@ static void bnx2x_init_pxp(struct bnx2x *bp) REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val); REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order); - REG_WR(bp, PXP2_REG_RQ_WR_MBS0 + 8, w_order); + REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order); REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); - REG_WR(bp, PXP2_REG_RQ_RD_MBS0 + 8, r_order); + REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); + if (r_order == MAX_RD_ORD) + REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); + + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16); } diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h index 86055297ab0..5a1aa0b5504 100644 --- a/drivers/net/bnx2x_reg.h +++ b/drivers/net/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,8 @@ #define BRB1_REG_BRB1_INT_STS 0x6011c /* [RW 4] Parity mask register #0 read/write */ #define BRB1_REG_BRB1_PRTY_MASK 0x60138 +/* [R 4] Parity register #0 read */ +#define BRB1_REG_BRB1_PRTY_STS 0x6012c /* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */ @@ -281,6 +283,8 @@ #define CDU_REG_CDU_INT_STS 0x101030 /* [RW 5] Parity mask register #0 read/write */ #define CDU_REG_CDU_PRTY_MASK 0x10104c +/* [R 5] Parity register #0 read */ +#define CDU_REG_CDU_PRTY_STS 0x101040 /* [RC 32] logging of error data in case of a CDU load error: {expected_cid[15:0]; xpected_type[2:0]; xpected_region[2:0]; ctive_error; ype_error; ctual_active; ctual_compressed_context}; */ @@ -308,6 +312,8 @@ #define CFC_REG_CFC_INT_STS_CLR 0x104100 /* [RW 4] Parity mask register #0 read/write */ #define CFC_REG_CFC_PRTY_MASK 0x104118 +/* [R 4] Parity register #0 read */ +#define CFC_REG_CFC_PRTY_STS 0x10410c /* [RW 21] CID cam access (21:1 - Data; alid - 0) */ #define CFC_REG_CID_CAM 0x104800 #define CFC_REG_CONTROL0 0x104028 @@ -354,6 +360,8 @@ #define CSDM_REG_CSDM_INT_MASK_1 0xc22ac /* [RW 11] Parity mask register #0 read/write */ #define CSDM_REG_CSDM_PRTY_MASK 0xc22bc +/* [R 11] Parity register #0 read */ +#define CSDM_REG_CSDM_PRTY_STS 0xc22b0 #define CSDM_REG_ENABLE_IN1 0xc2238 #define CSDM_REG_ENABLE_IN2 0xc223c #define CSDM_REG_ENABLE_OUT1 0xc2240 @@ -438,6 +446,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define CSEM_REG_CSEM_PRTY_MASK_0 0x200130 #define CSEM_REG_CSEM_PRTY_MASK_1 0x200140 +/* [R 32] Parity register #0 read */ +#define CSEM_REG_CSEM_PRTY_STS_0 0x200124 +#define CSEM_REG_CSEM_PRTY_STS_1 0x200134 #define CSEM_REG_ENABLE_IN 0x2000a4 #define CSEM_REG_ENABLE_OUT 0x2000a8 /* [RW 32] This address space contains all registers and memories that are @@ -526,6 +537,8 @@ #define CSEM_REG_TS_9_AS 0x20005c /* [RW 1] Parity mask register #0 read/write */ #define DBG_REG_DBG_PRTY_MASK 0xc0a8 +/* [R 1] Parity register #0 read */ +#define DBG_REG_DBG_PRTY_STS 0xc09c /* [RW 2] debug only: These bits indicate the credit for PCI request type 4 interface; MUST be configured AFTER pci_ext_buffer_strt_addr_lsb/msb are configured */ @@ -543,6 +556,8 @@ #define DMAE_REG_DMAE_INT_MASK 0x102054 /* [RW 4] Parity mask register #0 read/write */ #define DMAE_REG_DMAE_PRTY_MASK 0x102064 +/* [R 4] Parity register #0 read */ +#define DMAE_REG_DMAE_PRTY_STS 0x102058 /* [RW 1] Command 0 go. */ #define DMAE_REG_GO_C0 0x102080 /* [RW 1] Command 1 go. */ @@ -623,6 +638,8 @@ #define DORQ_REG_DORQ_INT_STS_CLR 0x170178 /* [RW 2] Parity mask register #0 read/write */ #define DORQ_REG_DORQ_PRTY_MASK 0x170190 +/* [R 2] Parity register #0 read */ +#define DORQ_REG_DORQ_PRTY_STS 0x170184 /* [RW 8] The address to write the DPM CID to STORM. */ #define DORQ_REG_DPM_CID_ADDR 0x170044 /* [RW 5] The DPM mode CID extraction offset. */ @@ -692,6 +709,8 @@ #define HC_REG_CONFIG_1 0x108004 /* [RW 3] Parity mask register #0 read/write */ #define HC_REG_HC_PRTY_MASK 0x1080a0 +/* [R 3] Parity register #0 read */ +#define HC_REG_HC_PRTY_STS 0x108094 /* [RW 17] status block interrupt mask; one in each bit means unmask; zerow in each bit means mask; bit 0 - default SB; bit 1 - SB_0; bit 2 - SB_1... bit 16- SB_15; addr 0 - port 0; addr 1 - port 1 */ @@ -1127,6 +1146,7 @@ #define MISC_REG_AEU_GENERAL_ATTN_17 0xa044 #define MISC_REG_AEU_GENERAL_ATTN_18 0xa048 #define MISC_REG_AEU_GENERAL_ATTN_19 0xa04c +#define MISC_REG_AEU_GENERAL_ATTN_10 0xa028 #define MISC_REG_AEU_GENERAL_ATTN_11 0xa02c #define MISC_REG_AEU_GENERAL_ATTN_2 0xa008 #define MISC_REG_AEU_GENERAL_ATTN_20 0xa050 @@ -1135,6 +1155,9 @@ #define MISC_REG_AEU_GENERAL_ATTN_4 0xa010 #define MISC_REG_AEU_GENERAL_ATTN_5 0xa014 #define MISC_REG_AEU_GENERAL_ATTN_6 0xa018 +#define MISC_REG_AEU_GENERAL_ATTN_7 0xa01c +#define MISC_REG_AEU_GENERAL_ATTN_8 0xa020 +#define MISC_REG_AEU_GENERAL_ATTN_9 0xa024 /* [RW 32] first 32b for inverting the input for function 0; for each bit: 0= do not invert; 1= invert; mapped as follows: [0] NIG attention for function0; [1] NIG attention for function1; [2] GPIO1 mcp; [3] GPIO2 mcp; @@ -1183,6 +1206,40 @@ starts at 0x0 for the A0 tape-out and increments by one for each all-layer tape-out. */ #define MISC_REG_CHIP_REV 0xa40c +/* [RW 32] The following driver registers(1..6) represent 6 drivers and 32 + clients. Each client can be controlled by one driver only. One in each + bit represent that this driver control the appropriate client (Ex: bit 5 + is set means this driver control client number 5). addr1 = set; addr0 = + clear; read from both addresses will give the same result = status. write + to address 1 will set a request to control all the clients that their + appropriate bit (in the write command) is set. if the client is free (the + appropriate bit in all the other drivers is clear) one will be written to + that driver register; if the client isn't free the bit will remain zero. + if the appropriate bit is set (the driver request to gain control on a + client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW + interrupt will be asserted). write to address 0 will set a request to + free all the clients that their appropriate bit (in the write command) is + set. if the appropriate bit is clear (the driver request to free a client + it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will + be asserted). */ +#define MISC_REG_DRIVER_CONTROL_1 0xa510 +/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of + these bits is written as a '1'; the corresponding SPIO bit will turn off + it's drivers and become an input. This is the reset state of all GPIO + pins. The read value of these bits will be a '1' if that last command + (#SET; #CLR; or #FLOAT) for this bit was a #FLOAT. (reset value 0xff). + [23-20] CLR port 1; 19-16] CLR port 0; When any of these bits is written + as a '1'; the corresponding GPIO bit will drive low. The read value of + these bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for + this bit was a #CLR. (reset value 0). [15-12] SET port 1; 11-8] port 0; + SET When any of these bits is written as a '1'; the corresponding GPIO + bit will drive high (if it has that capability). The read value of these + bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for this + bit was a #SET. (reset value 0). [7-4] VALUE port 1; [3-0] VALUE port 0; + RO; These bits indicate the read value of each of the eight GPIO pins. + This is the result value of the pin; not the drive value. Writing these + bits will have not effect. */ +#define MISC_REG_GPIO 0xa490 /* [RW 1] Setting this bit enables a timer in the GRC block to timeout any access that does not finish within ~misc_registers_grc_timout_val.grc_timeout_val cycles. When this bit is @@ -1223,6 +1280,8 @@ #define MISC_REG_MISC_INT_MASK 0xa388 /* [RW 1] Parity mask register #0 read/write */ #define MISC_REG_MISC_PRTY_MASK 0xa398 +/* [R 1] Parity register #0 read */ +#define MISC_REG_MISC_PRTY_STS 0xa38c /* [RW 32] 32 LSB of storm PLL first register; reset val = 0x 071d2911. inside order of the bits is: [0] P1 divider[0] (reset value 1); [1] P1 divider[1] (reset value 0); [2] P1 divider[2] (reset value 0); [3] P1 @@ -1264,6 +1323,55 @@ /* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is shared with the driver resides */ #define MISC_REG_SHARED_MEM_ADDR 0xa2b4 +/* [RW 32] SPIO. [31-24] FLOAT When any of these bits is written as a '1'; + the corresponding SPIO bit will turn off it's drivers and become an + input. This is the reset state of all SPIO pins. The read value of these + bits will be a '1' if that last command (#SET; #CL; or #FLOAT) for this + bit was a #FLOAT. (reset value 0xff). [23-16] CLR When any of these bits + is written as a '1'; the corresponding SPIO bit will drive low. The read + value of these bits will be a '1' if that last command (#SET; #CLR; or +#FLOAT) for this bit was a #CLR. (reset value 0). [15-8] SET When any of + these bits is written as a '1'; the corresponding SPIO bit will drive + high (if it has that capability). The read value of these bits will be a + '1' if that last command (#SET; #CLR; or #FLOAT) for this bit was a #SET. + (reset value 0). [7-0] VALUE RO; These bits indicate the read value of + each of the eight SPIO pins. This is the result value of the pin; not the + drive value. Writing these bits will have not effect. Each 8 bits field + is divided as follows: [0] VAUX Enable; when pulsed low; enables supply + from VAUX. (This is an output pin only; the FLOAT field is not applicable + for this pin); [1] VAUX Disable; when pulsed low; disables supply form + VAUX. (This is an output pin only; FLOAT field is not applicable for this + pin); [2] SEL_VAUX_B - Control to power switching logic. Drive low to + select VAUX supply. (This is an output pin only; it is not controlled by + the SET and CLR fields; it is controlled by the Main Power SM; the FLOAT + field is not applicable for this pin; only the VALUE fields is relevant - + it reflects the output value); [3] reserved; [4] spio_4; [5] spio_5; [6] + Bit 0 of UMP device ID select; read by UMP firmware; [7] Bit 1 of UMP + device ID select; read by UMP firmware. */ +#define MISC_REG_SPIO 0xa4fc +/* [RW 8] These bits enable the SPIO_INTs to signals event to the IGU/MC. + according to the following map: [3:0] reserved; [4] spio_4 [5] spio_5; + [7:0] reserved */ +#define MISC_REG_SPIO_EVENT_EN 0xa2b8 +/* [RW 32] SPIO INT. [31-24] OLD_CLR Writing a '1' to these bit clears the + corresponding bit in the #OLD_VALUE register. This will acknowledge an + interrupt on the falling edge of corresponding SPIO input (reset value + 0). [23-16] OLD_SET Writing a '1' to these bit sets the corresponding bit + in the #OLD_VALUE register. This will acknowledge an interrupt on the + rising edge of corresponding SPIO input (reset value 0). [15-8] OLD_VALUE + RO; These bits indicate the old value of the SPIO input value. When the + ~INT_STATE bit is set; this bit indicates the OLD value of the pin such + that if ~INT_STATE is set and this bit is '0'; then the interrupt is due + to a low to high edge. If ~INT_STATE is set and this bit is '1'; then the + interrupt is due to a high to low edge (reset value 0). [7-0] INT_STATE + RO; These bits indicate the current SPIO interrupt state for each SPIO + pin. This bit is cleared when the appropriate #OLD_SET or #OLD_CLR + command bit is written. This bit is set when the SPIO input does not + match the current value in #OLD_VALUE (reset value 0). */ +#define MISC_REG_SPIO_INT 0xa500 +/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are + loaded; 0-prepare; -unprepare */ +#define MISC_REG_UNPREPARED 0xa424 #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15) @@ -1392,6 +1500,9 @@ #define NIG_REG_NIG_INGRESS_EMAC0_NO_CRC 0x10044 /* [RW 1] Input enable for RX PBF LP IF */ #define NIG_REG_PBF_LB_IN_EN 0x100b4 +/* [RW 1] Value of this register will be transmitted to port swap when + ~nig_registers_strap_override.strap_override =1 */ +#define NIG_REG_PORT_SWAP 0x10394 /* [RW 1] output enable for RX parser descriptor IF */ #define NIG_REG_PRS_EOP_OUT_EN 0x10104 /* [RW 1] Input enable for RX parser request IF */ @@ -1410,6 +1521,10 @@ #define NIG_REG_STAT2_BRB_OCTET 0x107e0 #define NIG_REG_STATUS_INTERRUPT_PORT0 0x10328 #define NIG_REG_STATUS_INTERRUPT_PORT1 0x1032c +/* [RW 1] port swap mux selection. If this register equal to 0 then port + swap is equal to SPIO pin that inputs from ifmux_serdes_swap. If 1 then + ort swap is equal to ~nig_registers_port_swap.port_swap */ +#define NIG_REG_STRAP_OVERRIDE 0x10398 /* [RW 1] output enable for RX_XCM0 IF */ #define NIG_REG_XCM0_OUT_EN 0x100f0 /* [RW 1] output enable for RX_XCM1 IF */ @@ -1499,6 +1614,8 @@ #define PB_REG_PB_INT_STS 0x1c /* [RW 4] Parity mask register #0 read/write */ #define PB_REG_PB_PRTY_MASK 0x38 +/* [R 4] Parity register #0 read */ +#define PB_REG_PB_PRTY_STS 0x2c #define PRS_REG_A_PRSU_20 0x40134 /* [R 8] debug only: CFC load request current credit. Transaction based. */ #define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164 @@ -1590,6 +1707,8 @@ #define PRS_REG_PRS_INT_STS 0x40188 /* [RW 8] Parity mask register #0 read/write */ #define PRS_REG_PRS_PRTY_MASK 0x401a4 +/* [R 8] Parity register #0 read */ +#define PRS_REG_PRS_PRTY_STS 0x40198 /* [RW 8] Context region for pure acknowledge packets. Used in CFC load request message */ #define PRS_REG_PURE_REGIONS 0x40024 @@ -1718,6 +1837,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define PXP2_REG_PXP2_PRTY_MASK_0 0x120588 #define PXP2_REG_PXP2_PRTY_MASK_1 0x120598 +/* [R 32] Parity register #0 read */ +#define PXP2_REG_PXP2_PRTY_STS_0 0x12057c +#define PXP2_REG_PXP2_PRTY_STS_1 0x12058c /* [R 1] Debug only: The 'almost full' indication from each fifo (gives indication about backpressure) */ #define PXP2_REG_RD_ALMOST_FULL_0 0x120424 @@ -1911,6 +2033,8 @@ #define PXP2_REG_RQ_HC_ENDIAN_M 0x1201a8 /* [WB 53] Onchip address table */ #define PXP2_REG_RQ_ONCHIP_AT 0x122000 +/* [RW 13] Pending read limiter threshold; in Dwords */ +#define PXP2_REG_RQ_PDR_LIMIT 0x12033c /* [RW 2] Endian mode for qm */ #define PXP2_REG_RQ_QM_ENDIAN_M 0x120194 /* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k; @@ -1921,6 +2045,9 @@ /* [RW 3] Max burst size filed for read requests port 0; 000 - 128B; 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */ #define PXP2_REG_RQ_RD_MBS0 0x120160 +/* [RW 3] Max burst size filed for read requests port 1; 000 - 128B; + 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */ +#define PXP2_REG_RQ_RD_MBS1 0x120168 /* [RW 2] Endian mode for src */ #define PXP2_REG_RQ_SRC_ENDIAN_M 0x12019c /* [RW 3] page size in L2P table for SRC module; -4k; -8k; -16k; -32k; -64k; @@ -2000,10 +2127,17 @@ /* [RW 3] Max burst size filed for write requests port 0; 000 - 128B; 001:256B; 010: 512B; */ #define PXP2_REG_RQ_WR_MBS0 0x12015c +/* [RW 3] Max burst size filed for write requests port 1; 000 - 128B; + 001:256B; 010: 512B; */ +#define PXP2_REG_RQ_WR_MBS1 0x120164 /* [RW 10] if Number of entries in dmae fifo will be higer than this threshold then has_payload indication will be asserted; the default value should be equal to > write MBS size! */ #define PXP2_REG_WR_DMAE_TH 0x120368 +/* [RW 10] if Number of entries in usdmdp fifo will be higer than this + threshold then has_payload indication will be asserted; the default value + should be equal to > write MBS size! */ +#define PXP2_REG_WR_USDMDP_TH 0x120348 /* [R 1] debug only: Indication if PSWHST arbiter is idle */ #define PXP_REG_HST_ARB_IS_IDLE 0x103004 /* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means @@ -2021,6 +2155,8 @@ #define PXP_REG_PXP_INT_STS_CLR_0 0x10306c /* [RW 26] Parity mask register #0 read/write */ #define PXP_REG_PXP_PRTY_MASK 0x103094 +/* [R 26] Parity register #0 read */ +#define PXP_REG_PXP_PRTY_STS 0x103088 /* [RW 4] The activity counter initial increment value sent in the load request */ #define QM_REG_ACTCTRINITVAL_0 0x168040 @@ -2127,6 +2263,8 @@ #define QM_REG_QM_INT_STS 0x168438 /* [RW 9] Parity mask register #0 read/write */ #define QM_REG_QM_PRTY_MASK 0x168454 +/* [R 9] Parity register #0 read */ +#define QM_REG_QM_PRTY_STS 0x168448 /* [R 32] Current queues in pipeline: Queues from 32 to 63 */ #define QM_REG_QSTATUS_HIGH 0x16802c /* [R 32] Current queues in pipeline: Queues from 0 to 31 */ @@ -2410,6 +2548,8 @@ #define SRC_REG_SRC_INT_STS 0x404ac /* [RW 3] Parity mask register #0 read/write */ #define SRC_REG_SRC_PRTY_MASK 0x404c8 +/* [R 3] Parity register #0 read */ +#define SRC_REG_SRC_PRTY_STS 0x404bc /* [R 4] Used to read the value of the XX protection CAM occupancy counter. */ #define TCM_REG_CAM_OCCUP 0x5017c /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -2730,6 +2870,8 @@ #define TSDM_REG_TSDM_INT_MASK_1 0x422ac /* [RW 11] Parity mask register #0 read/write */ #define TSDM_REG_TSDM_PRTY_MASK 0x422bc +/* [R 11] Parity register #0 read */ +#define TSDM_REG_TSDM_PRTY_STS 0x422b0 /* [RW 5] The number of time_slots in the arbitration cycle */ #define TSEM_REG_ARB_CYCLE_SIZE 0x180034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -2854,6 +2996,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define TSEM_REG_TSEM_PRTY_MASK_0 0x180120 #define TSEM_REG_TSEM_PRTY_MASK_1 0x180130 +/* [R 32] Parity register #0 read */ +#define TSEM_REG_TSEM_PRTY_STS_0 0x180114 +#define TSEM_REG_TSEM_PRTY_STS_1 0x180124 /* [R 5] Used to read the XX protection CAM occupancy counter. */ #define UCM_REG_CAM_OCCUP 0xe0170 /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -3155,6 +3300,8 @@ #define USDM_REG_USDM_INT_MASK_1 0xc42b0 /* [RW 11] Parity mask register #0 read/write */ #define USDM_REG_USDM_PRTY_MASK 0xc42c0 +/* [R 11] Parity register #0 read */ +#define USDM_REG_USDM_PRTY_STS 0xc42b4 /* [RW 5] The number of time_slots in the arbitration cycle */ #define USEM_REG_ARB_CYCLE_SIZE 0x300034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -3279,6 +3426,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define USEM_REG_USEM_PRTY_MASK_0 0x300130 #define USEM_REG_USEM_PRTY_MASK_1 0x300140 +/* [R 32] Parity register #0 read */ +#define USEM_REG_USEM_PRTY_STS_0 0x300124 +#define USEM_REG_USEM_PRTY_STS_1 0x300134 /* [RW 2] The queue index for registration on Aux1 counter flag. */ #define XCM_REG_AUX1_Q 0x20134 /* [RW 2] Per each decision rule the queue index to register to. */ @@ -3684,6 +3834,8 @@ #define XSDM_REG_XSDM_INT_MASK_1 0x1662ac /* [RW 11] Parity mask register #0 read/write */ #define XSDM_REG_XSDM_PRTY_MASK 0x1662bc +/* [R 11] Parity register #0 read */ +#define XSDM_REG_XSDM_PRTY_STS 0x1662b0 /* [RW 5] The number of time_slots in the arbitration cycle */ #define XSEM_REG_ARB_CYCLE_SIZE 0x280034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -3808,6 +3960,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define XSEM_REG_XSEM_PRTY_MASK_0 0x280130 #define XSEM_REG_XSEM_PRTY_MASK_1 0x280140 +/* [R 32] Parity register #0 read */ +#define XSEM_REG_XSEM_PRTY_STS_0 0x280124 +#define XSEM_REG_XSEM_PRTY_STS_1 0x280134 #define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0) #define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1) #define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) @@ -3847,6 +4002,8 @@ #define EMAC_MDIO_COMM_START_BUSY (1L<<29) #define EMAC_MDIO_MODE_AUTO_POLL (1L<<4) #define EMAC_MDIO_MODE_CLAUSE_45 (1L<<31) +#define EMAC_MDIO_MODE_CLOCK_CNT (0x3fL<<16) +#define EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT 16 #define EMAC_MODE_25G_MODE (1L<<5) #define EMAC_MODE_ACPI_RCVD (1L<<20) #define EMAC_MODE_HALF_DUPLEX (1L<<1) @@ -3874,6 +4031,17 @@ #define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31) #define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3) #define EMAC_TX_MODE_RESET (1L<<0) +#define MISC_REGISTERS_GPIO_1 1 +#define MISC_REGISTERS_GPIO_2 2 +#define MISC_REGISTERS_GPIO_3 3 +#define MISC_REGISTERS_GPIO_CLR_POS 16 +#define MISC_REGISTERS_GPIO_FLOAT (0xffL<<24) +#define MISC_REGISTERS_GPIO_FLOAT_POS 24 +#define MISC_REGISTERS_GPIO_INPUT_HI_Z 2 +#define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1 +#define MISC_REGISTERS_GPIO_OUTPUT_LOW 0 +#define MISC_REGISTERS_GPIO_PORT_SHIFT 4 +#define MISC_REGISTERS_GPIO_SET_POS 8 #define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 #define MISC_REGISTERS_RESET_REG_1_SET 0x584 #define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598 @@ -3891,6 +4059,25 @@ #define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW (0x1<<4) #define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB (0x1<<8) #define MISC_REGISTERS_RESET_REG_3_SET 0x5a4 +#define MISC_REGISTERS_SPIO_4 4 +#define MISC_REGISTERS_SPIO_5 5 +#define MISC_REGISTERS_SPIO_7 7 +#define MISC_REGISTERS_SPIO_CLR_POS 16 +#define MISC_REGISTERS_SPIO_FLOAT (0xffL<<24) +#define GRC_MISC_REGISTERS_SPIO_FLOAT7 0x80000000 +#define GRC_MISC_REGISTERS_SPIO_FLOAT6 0x40000000 +#define GRC_MISC_REGISTERS_SPIO_FLOAT5 0x20000000 +#define GRC_MISC_REGISTERS_SPIO_FLOAT4 0x10000000 +#define MISC_REGISTERS_SPIO_FLOAT_POS 24 +#define MISC_REGISTERS_SPIO_INPUT_HI_Z 2 +#define MISC_REGISTERS_SPIO_INT_OLD_SET_POS 16 +#define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1 +#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0 +#define MISC_REGISTERS_SPIO_SET_POS 8 +#define HW_LOCK_MAX_RESOURCE_VALUE 31 +#define HW_LOCK_RESOURCE_8072_MDIO 0 +#define HW_LOCK_RESOURCE_GPIO 1 +#define HW_LOCK_RESOURCE_SPIO 2 #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) #define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31) #define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9) @@ -3918,6 +4105,7 @@ #define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (1<<3) #define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (1<<2) #define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (1<<22) +#define AEU_INPUTS_ATTN_BITS_SPIO5 (1<<15) #define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (1<<27) #define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (1<<5) #define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (1<<25) @@ -4206,6 +4394,9 @@ #define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE 0x4000 #define MDIO_XGXS_BLOCK2_TX_LN_SWAP 0x11 #define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE 0x8000 +#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G 0x14 +#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS 0x0001 +#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS 0x0010 #define MDIO_XGXS_BLOCK2_TEST_MODE_LANE 0x15 #define MDIO_REG_BANK_GP_STATUS 0x8120 @@ -4362,11 +4553,13 @@ #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE 0x0001 +#define EXT_PHY_AUTO_NEG_DEVAD 0x7 #define EXT_PHY_OPT_PMA_PMD_DEVAD 0x1 #define EXT_PHY_OPT_WIS_DEVAD 0x2 #define EXT_PHY_OPT_PCS_DEVAD 0x3 #define EXT_PHY_OPT_PHY_XS_DEVAD 0x4 #define EXT_PHY_OPT_CNTL 0x0 +#define EXT_PHY_OPT_CNTL2 0x7 #define EXT_PHY_OPT_PMD_RX_SD 0xa #define EXT_PHY_OPT_PMD_MISC_CNTL 0xca0a #define EXT_PHY_OPT_PHY_IDENTIFIER 0xc800 @@ -4378,11 +4571,24 @@ #define EXT_PHY_OPT_LASI_STATUS 0x9005 #define EXT_PHY_OPT_PCS_STATUS 0x0020 #define EXT_PHY_OPT_XGXS_LANE_STATUS 0x0018 +#define EXT_PHY_OPT_AN_LINK_STATUS 0x8304 +#define EXT_PHY_OPT_AN_CL37_CL73 0x8370 +#define EXT_PHY_OPT_AN_CL37_FD 0xffe4 +#define EXT_PHY_OPT_AN_CL37_AN 0xffe0 +#define EXT_PHY_OPT_AN_ADV 0x11 #define EXT_PHY_KR_PMA_PMD_DEVAD 0x1 #define EXT_PHY_KR_PCS_DEVAD 0x3 #define EXT_PHY_KR_AUTO_NEG_DEVAD 0x7 #define EXT_PHY_KR_CTRL 0x0000 +#define EXT_PHY_KR_STATUS 0x0001 +#define EXT_PHY_KR_AUTO_NEG_COMPLETE 0x0020 +#define EXT_PHY_KR_AUTO_NEG_ADVERT 0x0010 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE 0x0400 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC 0x0800 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH 0x0C00 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK 0x0C00 +#define EXT_PHY_KR_LP_AUTO_NEG 0x0013 #define EXT_PHY_KR_CTRL2 0x0007 #define EXT_PHY_KR_PCS_STATUS 0x0020 #define EXT_PHY_KR_PMD_CTRL 0x0096 @@ -4391,4 +4597,8 @@ #define EXT_PHY_KR_MISC_CTRL1 0xca85 #define EXT_PHY_KR_GEN_CTRL 0xca10 #define EXT_PHY_KR_ROM_CODE 0xca19 +#define EXT_PHY_KR_ROM_RESET_INTERNAL_MP 0x0188 +#define EXT_PHY_KR_ROM_MICRO_RESET 0x018a + +#define EXT_PHY_SFX7101_XGXS_TEST1 0xc00a diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 57175097513..348371fda59 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -172,30 +172,30 @@ static char version[] __initdata = them to system IRQ numbers. This mapping is card specific and is set to the configuration of the Cirrus Eval board for this chip. */ #ifdef CONFIG_ARCH_CLPS7500 -static unsigned int netcard_portlist[] __initdata = +static unsigned int netcard_portlist[] __used __initdata = { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int cs8900_irq_map[] = {12,0,0,0}; #elif defined(CONFIG_SH_HICOSH4) -static unsigned int netcard_portlist[] __initdata = +static unsigned int netcard_portlist[] __used __initdata = { 0x0300, 0}; static unsigned int cs8900_irq_map[] = {1,0,0,0}; #elif defined(CONFIG_MACH_IXDP2351) -static unsigned int netcard_portlist[] __initdata = {IXDP2351_VIRT_CS8900_BASE, 0}; +static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; #include <asm/irq.h> #elif defined(CONFIG_ARCH_IXDP2X01) #include <asm/irq.h> -static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; +static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; #elif defined(CONFIG_ARCH_PNX010X) #include <asm/irq.h> #include <asm/arch/gpio.h> #define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */ #define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */ -static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0}; +static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0}; static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0}; #else -static unsigned int netcard_portlist[] __initdata = +static unsigned int netcard_portlist[] __used __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int cs8900_irq_map[] = {10,11,12,5}; #endif diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 3beace55b58..7fe20310eb5 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -438,7 +438,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw) * For non-82573 silicon, write data to EEPROM at offset using SPI interface. * * If e1000e_update_nvm_checksum is not called after this function, the - * EEPROM will most likley contain an invalid checksum. + * EEPROM will most likely contain an invalid checksum. **/ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) @@ -547,7 +547,7 @@ static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) * poll for completion. * * If e1000e_update_nvm_checksum is not called after this function, the - * EEPROM will most likley contain an invalid checksum. + * EEPROM will most likely contain an invalid checksum. **/ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) @@ -1053,7 +1053,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) /* If SerDes loopback mode is entered, there is no form * of reset to take the adapter out of that mode. So we * have to explicitly take the adapter out of loopback - * mode. This prevents drivers from twidling their thumbs + * mode. This prevents drivers from twiddling their thumbs * if another tool failed to take it out of loopback mode. */ ew32(SCTL, @@ -1098,7 +1098,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) * e1000e_get_laa_state_82571 - Get locally administered address state * @hw: pointer to the HW structure * - * Retrieve and return the current locally administed address state. + * Retrieve and return the current locally administered address state. **/ bool e1000e_get_laa_state_82571(struct e1000_hw *hw) { @@ -1113,7 +1113,7 @@ bool e1000e_get_laa_state_82571(struct e1000_hw *hw) * @hw: pointer to the HW structure * @state: enable/disable locally administered address * - * Enable/Disable the current locally administed address state. + * Enable/Disable the current locally administers address state. **/ void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state) { @@ -1281,16 +1281,6 @@ static struct e1000_phy_operations e82_phy_ops_m88 = { static struct e1000_nvm_operations e82571_nvm_ops = { .acquire_nvm = e1000_acquire_nvm_82571, - .read_nvm = e1000e_read_nvm_spi, - .release_nvm = e1000_release_nvm_82571, - .update_nvm = e1000_update_nvm_checksum_82571, - .valid_led_default = e1000_valid_led_default_82571, - .validate_nvm = e1000_validate_nvm_checksum_82571, - .write_nvm = e1000_write_nvm_82571, -}; - -static struct e1000_nvm_operations e82573_nvm_ops = { - .acquire_nvm = e1000_acquire_nvm_82571, .read_nvm = e1000e_read_nvm_eerd, .release_nvm = e1000_release_nvm_82571, .update_nvm = e1000_update_nvm_checksum_82571, @@ -1355,6 +1345,6 @@ struct e1000_info e1000_82573_info = { .get_invariants = e1000_get_invariants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_m88, - .nvm_ops = &e82573_nvm_ops, + .nvm_ops = &e82571_nvm_ops, }; diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 6232c3e9668..a4f511f549f 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -66,7 +66,7 @@ #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ /* Extended Device Control */ -#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */ +#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 @@ -75,12 +75,12 @@ #define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ -/* Receive Decriptor bit definitions */ +/* Receive Descriptor bit definitions */ #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ #define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ #define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ #define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ -#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ +#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */ #define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ #define E1000_RXD_ERR_CE 0x01 /* CRC Error */ #define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ @@ -223,7 +223,7 @@ #define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */ #define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ -/* Constants used to intrepret the masked PCI-X bus speed. */ +/* Constants used to interpret the masked PCI-X bus speed. */ #define HALF_DUPLEX 1 #define FULL_DUPLEX 2 @@ -517,7 +517,7 @@ /* PHY 1000 MII Register/Bit Definitions */ /* PHY Registers defined by IEEE */ #define PHY_CONTROL 0x00 /* Control Register */ -#define PHY_STATUS 0x01 /* Status Regiser */ +#define PHY_STATUS 0x01 /* Status Register */ #define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ #define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ #define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 8b88c226e85..327c0620da3 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -42,8 +42,7 @@ struct e1000_info; #define ndev_printk(level, netdev, format, arg...) \ - printk(level "%s: %s: " format, (netdev)->dev.parent->bus_id, \ - (netdev)->name, ## arg) + printk(level "%s: " format, (netdev)->name, ## arg) #ifdef DEBUG #define ndev_dbg(netdev, format, arg...) \ diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 3c5862f97db..916025b30fc 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -184,7 +184,7 @@ enum e1e_registers { E1000_ICRXDMTC = 0x04120, /* Irq Cause Rx Desc MinThreshold Count */ E1000_ICRXOC = 0x04124, /* Irq Cause Receiver Overrun Count */ E1000_RXCSUM = 0x05000, /* RX Checksum Control - RW */ - E1000_RFCTL = 0x05008, /* Receive Filter Control*/ + E1000_RFCTL = 0x05008, /* Receive Filter Control */ E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */ E1000_RA = 0x05400, /* Receive Address - RW Array */ E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */ @@ -202,7 +202,7 @@ enum e1e_registers { E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ E1000_SWSM = 0x05B50, /* SW Semaphore */ E1000_FWSM = 0x05B54, /* FW Semaphore */ - E1000_HICR = 0x08F00, /* Host Inteface Control */ + E1000_HICR = 0x08F00, /* Host Interface Control */ }; /* RSS registers */ diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 8f8139de1f4..0ae39550768 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -671,7 +671,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) * e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY * @hw: pointer to the HW structure * - * Polarity is determined on the polarity reveral feature being enabled. + * Polarity is determined on the polarity reversal feature being enabled. * This function is only called by other family-specific * routines. **/ @@ -947,7 +947,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) /* Either we should have a hardware SPI cycle in progress * bit to check against, in order to start a new cycle or * FDONE bit should be changed in the hardware so that it - * is 1 after harware reset, which can then be used as an + * is 1 after hardware reset, which can then be used as an * indication whether a cycle is in progress or has been * completed. */ @@ -1155,7 +1155,7 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, * which writes the checksum to the shadow ram. The changes in the shadow * ram are then committed to the EEPROM by processing each bank at a time * checking for the modified bit and writing only the pending changes. - * After a succesful commit, the shadow ram is cleared and is ready for + * After a successful commit, the shadow ram is cleared and is ready for * future writes. **/ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) @@ -1680,7 +1680,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) * - initialize LED identification * - setup receive address registers * - setup flow control - * - setup transmit discriptors + * - setup transmit descriptors * - clear statistics **/ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) @@ -1961,7 +1961,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_NOND0A_GBE_DISABLE); ew32(PHY_CTRL, phy_ctrl); - /* Call gig speed drop workaround on Giga disable before accessing + /* Call gig speed drop workaround on Gig disable before accessing * any PHY registers */ e1000e_gig_downshift_workaround_ich8lan(hw); @@ -1972,7 +1972,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) /** * e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state * @hw: pointer to the HW structure - * @state: boolean value used to set the current Kumaran workaround state + * @state: boolean value used to set the current Kumeran workaround state * * If ICH8, set the current Kumeran workaround state (enabled - TRUE * /disabled - FALSE). @@ -2017,7 +2017,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_NOND0A_GBE_DISABLE); ew32(PHY_CTRL, reg); - /* Call gig speed drop workaround on Giga disable before + /* Call gig speed drop workaround on Gig disable before * accessing any PHY registers */ if (hw->mac.type == e1000_ich8lan) e1000e_gig_downshift_workaround_ich8lan(hw); @@ -2045,7 +2045,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) * @hw: pointer to the HW structure * * Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC), - * LPLU, Giga disable, MDIC PHY reset): + * LPLU, Gig disable, MDIC PHY reset): * 1) Set Kumeran Near-end loopback * 2) Clear Kumeran Near-end loopback * Should only be called for ICH8[m] devices with IGP_3 Phy. @@ -2089,10 +2089,10 @@ static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) } /** - * e1000_led_on_ich8lan - Turn LED's on + * e1000_led_on_ich8lan - Turn LEDs on * @hw: pointer to the HW structure * - * Turn on the LED's. + * Turn on the LEDs. **/ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) { @@ -2105,10 +2105,10 @@ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) } /** - * e1000_led_off_ich8lan - Turn LED's off + * e1000_led_off_ich8lan - Turn LEDs off * @hw: pointer to the HW structure * - * Turn off the LED's. + * Turn off the LEDs. **/ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) { diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 16f35fadb74..95f75a43c9f 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -589,9 +589,6 @@ static s32 e1000_set_default_fc_generic(struct e1000_hw *hw) s32 ret_val; u16 nvm_data; - if (mac->fc != e1000_fc_default) - return 0; - /* Read and store word 0x0F of the EEPROM. This word contains bits * that determine the hardware's default PAUSE (flow control) mode, * a bit that determines whether the HW defaults to enabling or @@ -1107,34 +1104,13 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { mac->fc = e1000_fc_rx_pause; hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n"); - } - /* Per the IEEE spec, at this point flow control should be - * disabled. However, we want to consider that we could - * be connected to a legacy switch that doesn't advertise - * desired flow control, but can be forced on the link - * partner. So if we advertised no flow control, that is - * what we will resolve to. If we advertised some kind of - * receive capability (Rx Pause Only or Full Flow Control) - * and the link partner advertised none, we will configure - * ourselves to enable Rx Flow Control only. We can do - * this safely for two reasons: If the link partner really - * didn't want flow control enabled, and we enable Rx, no - * harm done since we won't be receiving any PAUSE frames - * anyway. If the intent on the link partner was to have - * flow control enabled, then by us enabling RX only, we - * can at least receive pause frames and process them. - * This is a good idea because in most cases, since we are - * predominantly a server NIC, more times than not we will - * be asked to delay transmission of packets than asking - * our link partner to pause transmission of frames. - */ - else if ((mac->original_fc == e1000_fc_none) || - (mac->original_fc == e1000_fc_tx_pause)) { + } else { + /* + * Per the IEEE spec, at this point flow control + * should be disabled. + */ mac->fc = e1000_fc_none; hw_dbg(hw, "Flow Control = NONE.\r\n"); - } else { - mac->fc = e1000_fc_rx_pause; - hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n"); } /* Now we need to do one last check... If we auto- @@ -1164,7 +1140,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) } /** - * e1000e_get_speed_and_duplex_copper - Retreive current speed/duplex + * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex * @hw: pointer to the HW structure * @speed: stores the current speed * @duplex: stores the current duplex @@ -1200,7 +1176,7 @@ s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *dup } /** - * e1000e_get_speed_and_duplex_fiber_serdes - Retreive current speed/duplex + * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex * @hw: pointer to the HW structure * @speed: stores the current speed * @duplex: stores the current duplex @@ -1410,7 +1386,7 @@ s32 e1000e_cleanup_led_generic(struct e1000_hw *hw) * e1000e_blink_led - Blink LED * @hw: pointer to the HW structure * - * Blink the led's which are set to be on. + * Blink the LEDs which are set to be on. **/ s32 e1000e_blink_led(struct e1000_hw *hw) { @@ -1515,7 +1491,7 @@ void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop) * @hw: pointer to the HW structure * * Returns 0 if successful, else returns -10 - * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued + * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused * the master requests to be disabled. * * Disables PCI-Express master access and verifies there are no pending @@ -1876,7 +1852,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) } /** - * e1000e_read_nvm_spi - Read EEPROM's using SPI + * e1000e_read_nvm_spi - Reads EEPROM using SPI * @hw: pointer to the HW structure * @offset: offset of word in the EEPROM to read * @words: number of words to read @@ -1980,7 +1956,7 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * Writes data to EEPROM at offset using SPI interface. * * If e1000e_update_nvm_checksum is not called after this function , the - * EEPROM will most likley contain an invalid checksum. + * EEPROM will most likely contain an invalid checksum. **/ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { @@ -2222,7 +2198,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length) * * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND * - * This function checks whether the HOST IF is enabled for command operaton + * This function checks whether the HOST IF is enabled for command operation * and also checks whether the previous command is completed. It busy waits * in case of previous command is not completed. **/ @@ -2254,7 +2230,7 @@ static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) } /** - * e1000e_check_mng_mode - check managament mode + * e1000e_check_mng_mode - check management mode * @hw: pointer to the HW structure * * Reads the firmware semaphore register and returns true (>0) if diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3031d6d1624..fc5c63f4f57 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1006,7 +1006,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) * e1000_get_hw_control - get control of the h/w from f/w * @adapter: address of board private structure * - * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit. + * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit. * For ASF and Pass Through versions of f/w this means that * the driver is loaded. For AMT version (only with 82573) * of the f/w this means that the network i/f is open. @@ -1032,7 +1032,7 @@ static void e1000_get_hw_control(struct e1000_adapter *adapter) * e1000_release_hw_control - release control of the h/w to f/w * @adapter: address of board private structure * - * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit. + * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit. * For ASF and Pass Through versions of f/w this means that the * driver is no longer loaded. For AMT version (only with 82573) i * of the f/w this means that the network i/f is closed. @@ -1241,6 +1241,11 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter) /** * e1000_update_itr - update the dynamic ITR value based on statistics + * @adapter: pointer to adapter + * @itr_setting: current adapter->itr + * @packets: the number of packets during this measurement interval + * @bytes: the number of bytes during this measurement interval + * * Stores a new ITR value based on packets and byte * counts during the last interrupt. The advantage of per interrupt * computation is faster updates and more accurate ITR for the current @@ -1250,10 +1255,6 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter) * while increasing bulk throughput. * this functionality is controlled by the InterruptThrottleRate module * parameter (see e1000_param.c) - * @adapter: pointer to adapter - * @itr_setting: current adapter->itr - * @packets: the number of packets during this measurement interval - * @bytes: the number of bytes during this measurement interval **/ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, u16 itr_setting, int packets, @@ -1366,6 +1367,7 @@ set_itr_now: /** * e1000_clean - NAPI Rx polling callback * @adapter: board private structure + * @budget: amount of packets driver is allowed to process this poll **/ static int e1000_clean(struct napi_struct *napi, int budget) { @@ -2000,7 +2002,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter) e1000_check_reset_block(hw)) return; - /* managebility (AMT) is enabled */ + /* manageability (AMT) is enabled */ if (er32(MANC) & E1000_MANC_SMBUS_EN) return; @@ -3488,7 +3490,6 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) static void e1000e_disable_l1aspm(struct pci_dev *pdev) { int pos; - u32 cap; u16 val; /* @@ -3503,7 +3504,6 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev) * active. */ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); - pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap); pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val); if (val & 0x2) { dev_warn(&pdev->dev, "Disabling L1 ASPM\n"); diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index fc6fee112f1..dab3c468a76 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -121,7 +121,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw) * @offset: register offset to be read * @data: pointer to the read data * - * Reads the MDI control regsiter in the PHY at offset and stores the + * Reads the MDI control register in the PHY at offset and stores the * information read to data. **/ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) @@ -1172,7 +1172,7 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active) } /** - * e1000e_check_downshift - Checks whether a downshift in speed occured + * e1000e_check_downshift - Checks whether a downshift in speed occurred * @hw: pointer to the HW structure * * Success returns 0, Failure returns 1 @@ -1388,8 +1388,8 @@ s32 e1000e_get_cable_length_m88(struct e1000_hw *hw) * * The automatic gain control (agc) normalizes the amplitude of the * received signal, adjusting for the attenuation produced by the - * cable. By reading the AGC registers, which reperesent the - * cobination of course and fine gain value, the value can be put + * cable. By reading the AGC registers, which represent the + * combination of course and fine gain value, the value can be put * into a lookup table to obtain the approximate cable length * for each channel. **/ @@ -1619,7 +1619,7 @@ s32 e1000e_phy_sw_reset(struct e1000_hw *hw) * Verify the reset block is not blocking us from resetting. Acquire * semaphore (if necessary) and read/set/write the device control reset * bit in the PHY. Wait the appropriate delay time for the device to - * reset and relase the semaphore (if necessary). + * reset and release the semaphore (if necessary). **/ s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw) { diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 88fb53eba71..7c4ead35cfa 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0083" +#define DRV_VERSION "EHEA_0087" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 @@ -386,6 +386,13 @@ struct ehea_port_res { #define EHEA_MAX_PORTS 16 + +#define EHEA_NUM_PORTRES_FW_HANDLES 6 /* QP handle, SendCQ handle, + RecvCQ handle, EQ handle, + SendMR handle, RecvMR handle */ +#define EHEA_NUM_PORT_FW_HANDLES 1 /* EQ handle */ +#define EHEA_NUM_ADAPTER_FW_HANDLES 2 /* MR handle, NEQ handle */ + struct ehea_adapter { u64 handle; struct of_device *ofdev; @@ -405,6 +412,31 @@ struct ehea_mc_list { u64 macaddr; }; +/* kdump support */ +struct ehea_fw_handle_entry { + u64 adh; /* Adapter Handle */ + u64 fwh; /* Firmware Handle */ +}; + +struct ehea_fw_handle_array { + struct ehea_fw_handle_entry *arr; + int num_entries; + struct semaphore lock; +}; + +struct ehea_bcmc_reg_entry { + u64 adh; /* Adapter Handle */ + u32 port_id; /* Logical Port Id */ + u8 reg_type; /* Registration Type */ + u64 macaddr; +}; + +struct ehea_bcmc_reg_array { + struct ehea_bcmc_reg_entry *arr; + int num_entries; + struct semaphore lock; +}; + #define EHEA_PORT_UP 1 #define EHEA_PORT_DOWN 0 #define EHEA_PHY_LINK_UP 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index c051c7e09b9..21af674b764 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -35,6 +35,7 @@ #include <linux/if_ether.h> #include <linux/notifier.h> #include <linux/reboot.h> +#include <asm/kexec.h> #include <net/ip.h> @@ -98,8 +99,10 @@ static int port_name_cnt; static LIST_HEAD(adapter_list); u64 ehea_driver_flags; struct work_struct ehea_rereg_mr_task; - struct semaphore dlpar_mem_lock; +struct ehea_fw_handle_array ehea_fw_handles; +struct ehea_bcmc_reg_array ehea_bcmc_regs; + static int __devinit ehea_probe_adapter(struct of_device *dev, const struct of_device_id *id); @@ -132,6 +135,160 @@ void ehea_dump(void *adr, int len, char *msg) } } +static void ehea_update_firmware_handles(void) +{ + struct ehea_fw_handle_entry *arr = NULL; + struct ehea_adapter *adapter; + int num_adapters = 0; + int num_ports = 0; + int num_portres = 0; + int i = 0; + int num_fw_handles, k, l; + + /* Determine number of handles */ + list_for_each_entry(adapter, &adapter_list, list) { + num_adapters++; + + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + num_ports++; + num_portres += port->num_def_qps + port->num_add_tx_qps; + } + } + + num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES + + num_ports * EHEA_NUM_PORT_FW_HANDLES + + num_portres * EHEA_NUM_PORTRES_FW_HANDLES; + + if (num_fw_handles) { + arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL); + if (!arr) + return; /* Keep the existing array */ + } else + goto out_update; + + list_for_each_entry(adapter, &adapter_list, list) { + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + for (l = 0; + l < port->num_def_qps + port->num_add_tx_qps; + l++) { + struct ehea_port_res *pr = &port->port_res[l]; + + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->qp->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->send_cq->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->recv_cq->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->eq->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->send_mr.handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->recv_mr.handle; + } + arr[i].adh = adapter->handle; + arr[i++].fwh = port->qp_eq->fw_handle; + } + + arr[i].adh = adapter->handle; + arr[i++].fwh = adapter->neq->fw_handle; + + if (adapter->mr.handle) { + arr[i].adh = adapter->handle; + arr[i++].fwh = adapter->mr.handle; + } + } + +out_update: + kfree(ehea_fw_handles.arr); + ehea_fw_handles.arr = arr; + ehea_fw_handles.num_entries = i; +} + +static void ehea_update_bcmc_registrations(void) +{ + struct ehea_bcmc_reg_entry *arr = NULL; + struct ehea_adapter *adapter; + struct ehea_mc_list *mc_entry; + int num_registrations = 0; + int i = 0; + int k; + + /* Determine number of registrations */ + list_for_each_entry(adapter, &adapter_list, list) + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + num_registrations += 2; /* Broadcast registrations */ + + list_for_each_entry(mc_entry, &port->mc_list->list,list) + num_registrations += 2; + } + + if (num_registrations) { + arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL); + if (!arr) + return; /* Keep the existing array */ + } else + goto out_update; + + list_for_each_entry(adapter, &adapter_list, list) { + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_BROADCAST | + EHEA_BCMC_UNTAGGED; + arr[i++].macaddr = port->mac_addr; + + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_BROADCAST | + EHEA_BCMC_VLANID_ALL; + arr[i++].macaddr = port->mac_addr; + + list_for_each_entry(mc_entry, + &port->mc_list->list, list) { + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | + EHEA_BCMC_UNTAGGED; + arr[i++].macaddr = mc_entry->macaddr; + + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | + EHEA_BCMC_VLANID_ALL; + arr[i++].macaddr = mc_entry->macaddr; + } + } + } + +out_update: + kfree(ehea_bcmc_regs.arr); + ehea_bcmc_regs.arr = arr; + ehea_bcmc_regs.num_entries = i; +} + static struct net_device_stats *ehea_get_stats(struct net_device *dev) { struct ehea_port *port = netdev_priv(dev); @@ -1601,19 +1758,25 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); + down(&ehea_bcmc_regs.lock); + /* Deregister old MAC in pHYP */ ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); if (ret) - goto out_free; + goto out_upregs; port->mac_addr = cb0->port_mac_addr << 16; /* Register new MAC in pHYP */ ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); if (ret) - goto out_free; + goto out_upregs; ret = 0; + +out_upregs: + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); out_free: kfree(cb0); out: @@ -1775,9 +1938,11 @@ static void ehea_set_multicast_list(struct net_device *dev) } ehea_promiscuous(dev, 0); + down(&ehea_bcmc_regs.lock); + if (dev->flags & IFF_ALLMULTI) { ehea_allmulti(dev, 1); - return; + goto out; } ehea_allmulti(dev, 0); @@ -1803,6 +1968,8 @@ static void ehea_set_multicast_list(struct net_device *dev) } out: + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); return; } @@ -2285,6 +2452,8 @@ static int ehea_up(struct net_device *dev) if (port->state == EHEA_PORT_UP) return 0; + down(&ehea_fw_handles.lock); + ret = ehea_port_res_setup(port, port->num_def_qps, port->num_add_tx_qps); if (ret) { @@ -2321,8 +2490,17 @@ static int ehea_up(struct net_device *dev) } } - ret = 0; + down(&ehea_bcmc_regs.lock); + + ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); + if (ret) { + ret = -EIO; + goto out_free_irqs; + } + port->state = EHEA_PORT_UP; + + ret = 0; goto out; out_free_irqs: @@ -2334,6 +2512,12 @@ out: if (ret) ehea_info("Failed starting %s. ret=%i", dev->name, ret); + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); + + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); + return ret; } @@ -2382,16 +2566,27 @@ static int ehea_down(struct net_device *dev) if (port->state == EHEA_PORT_DOWN) return 0; + down(&ehea_bcmc_regs.lock); ehea_drop_multicast_list(dev); + ehea_broadcast_reg_helper(port, H_DEREG_BCMC); + ehea_free_interrupts(dev); + down(&ehea_fw_handles.lock); + port->state = EHEA_PORT_DOWN; + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); + ret = ehea_clean_all_portres(port); if (ret) ehea_info("Failed freeing resources for %s. ret=%i", dev->name, ret); + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); + return ret; } @@ -2920,19 +3115,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; INIT_WORK(&port->reset_task, ehea_reset_port); - - ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); - if (ret) { - ret = -EIO; - goto out_unreg_port; - } - ehea_set_ethtool_ops(dev); ret = register_netdev(dev); if (ret) { ehea_error("register_netdev failed. ret=%d", ret); - goto out_dereg_bc; + goto out_unreg_port; } port->lro_max_aggr = lro_max_aggr; @@ -2949,9 +3137,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, return port; -out_dereg_bc: - ehea_broadcast_reg_helper(port, H_DEREG_BCMC); - out_unreg_port: ehea_unregister_port(port); @@ -2971,7 +3156,6 @@ static void ehea_shutdown_single_port(struct ehea_port *port) { unregister_netdev(port->netdev); ehea_unregister_port(port); - ehea_broadcast_reg_helper(port, H_DEREG_BCMC); kfree(port->mc_list); free_netdev(port->netdev); port->adapter->active_ports--; @@ -3014,7 +3198,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) i++; }; - return 0; } @@ -3159,6 +3342,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, ehea_error("Invalid ibmebus device probed"); return -EINVAL; } + down(&ehea_fw_handles.lock); adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); if (!adapter) { @@ -3239,7 +3423,10 @@ out_kill_eq: out_free_ad: kfree(adapter); + out: + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); return ret; } @@ -3258,18 +3445,41 @@ static int __devexit ehea_remove(struct of_device *dev) flush_scheduled_work(); + down(&ehea_fw_handles.lock); + ibmebus_free_irq(adapter->neq->attr.ist1, adapter); tasklet_kill(&adapter->neq_tasklet); ehea_destroy_eq(adapter->neq); ehea_remove_adapter_mr(adapter); list_del(&adapter->list); - kfree(adapter); + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); + return 0; } +void ehea_crash_handler(void) +{ + int i; + + if (ehea_fw_handles.arr) + for (i = 0; i < ehea_fw_handles.num_entries; i++) + ehea_h_free_resource(ehea_fw_handles.arr[i].adh, + ehea_fw_handles.arr[i].fwh, + FORCE_FREE); + + if (ehea_bcmc_regs.arr) + for (i = 0; i < ehea_bcmc_regs.num_entries; i++) + ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh, + ehea_bcmc_regs.arr[i].port_id, + ehea_bcmc_regs.arr[i].reg_type, + ehea_bcmc_regs.arr[i].macaddr, + 0, H_DEREG_BCMC); +} + static int ehea_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused) { @@ -3330,7 +3540,12 @@ int __init ehea_module_init(void) INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs); + memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles)); + memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); + sema_init(&dlpar_mem_lock, 1); + sema_init(&ehea_fw_handles.lock, 1); + sema_init(&ehea_bcmc_regs.lock, 1); ret = check_module_parm(); if (ret) @@ -3340,12 +3555,18 @@ int __init ehea_module_init(void) if (ret) goto out; - register_reboot_notifier(&ehea_reboot_nb); + ret = register_reboot_notifier(&ehea_reboot_nb); + if (ret) + ehea_info("failed registering reboot notifier"); + + ret = crash_shutdown_register(&ehea_crash_handler); + if (ret) + ehea_info("failed registering crash handler"); ret = ibmebus_register_driver(&ehea_driver); if (ret) { ehea_error("failed registering eHEA device driver on ebus"); - goto out; + goto out2; } ret = driver_create_file(&ehea_driver.driver, @@ -3353,21 +3574,33 @@ int __init ehea_module_init(void) if (ret) { ehea_error("failed to register capabilities attribute, ret=%d", ret); - unregister_reboot_notifier(&ehea_reboot_nb); - ibmebus_unregister_driver(&ehea_driver); - goto out; + goto out3; } + return ret; + +out3: + ibmebus_unregister_driver(&ehea_driver); +out2: + unregister_reboot_notifier(&ehea_reboot_nb); + crash_shutdown_unregister(&ehea_crash_handler); out: return ret; } static void __exit ehea_module_exit(void) { + int ret; + flush_scheduled_work(); driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); unregister_reboot_notifier(&ehea_reboot_nb); + ret = crash_shutdown_unregister(&ehea_crash_handler); + if (ret) + ehea_info("failed unregistering crash handler"); + kfree(ehea_fw_handles.arr); + kfree(ehea_bcmc_regs.arr); ehea_destroy_busmap(); } diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 42d94edeee2..af869cf9ae7 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -946,16 +946,11 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct fs_enet_private *fep = netdev_priv(dev); struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; - unsigned long flags; - int rc; if (!netif_running(dev)) return -EINVAL; - spin_lock_irqsave(&fep->lock, flags); - rc = phy_mii_ioctl(fep->phydev, mii, cmd); - spin_unlock_irqrestore(&fep->lock, flags); - return rc; + return phy_mii_ioctl(fep->phydev, mii, cmd); } extern int fs_mii_connect(struct net_device *dev); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 4244fc282f2..718cf77e345 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -605,7 +605,7 @@ void stop_gfar(struct net_device *dev) free_skb_resources(priv); - dma_free_coherent(NULL, + dma_free_coherent(&dev->dev, sizeof(struct txbd8)*priv->tx_ring_size + sizeof(struct rxbd8)*priv->rx_ring_size, priv->tx_bd_base, @@ -626,7 +626,7 @@ static void free_skb_resources(struct gfar_private *priv) for (i = 0; i < priv->tx_ring_size; i++) { if (priv->tx_skbuff[i]) { - dma_unmap_single(NULL, txbdp->bufPtr, + dma_unmap_single(&priv->dev->dev, txbdp->bufPtr, txbdp->length, DMA_TO_DEVICE); dev_kfree_skb_any(priv->tx_skbuff[i]); @@ -643,7 +643,7 @@ static void free_skb_resources(struct gfar_private *priv) if(priv->rx_skbuff != NULL) { for (i = 0; i < priv->rx_ring_size; i++) { if (priv->rx_skbuff[i]) { - dma_unmap_single(NULL, rxbdp->bufPtr, + dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr, priv->rx_buffer_size, DMA_FROM_DEVICE); @@ -708,7 +708,7 @@ int startup_gfar(struct net_device *dev) gfar_write(®s->imask, IMASK_INIT_CLEAR); /* Allocate memory for the buffer descriptors */ - vaddr = (unsigned long) dma_alloc_coherent(NULL, + vaddr = (unsigned long) dma_alloc_coherent(&dev->dev, sizeof (struct txbd8) * priv->tx_ring_size + sizeof (struct rxbd8) * priv->rx_ring_size, &addr, GFP_KERNEL); @@ -919,7 +919,7 @@ err_irq_fail: rx_skb_fail: free_skb_resources(priv); tx_skb_fail: - dma_free_coherent(NULL, + dma_free_coherent(&dev->dev, sizeof(struct txbd8)*priv->tx_ring_size + sizeof(struct rxbd8)*priv->rx_ring_size, priv->tx_bd_base, @@ -1053,7 +1053,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Set buffer length and pointer */ txbdp->length = skb->len; - txbdp->bufPtr = dma_map_single(NULL, skb->data, + txbdp->bufPtr = dma_map_single(&dev->dev, skb->data, skb->len, DMA_TO_DEVICE); /* Save the skb pointer so we can free it later */ @@ -1332,7 +1332,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp) */ skb_reserve(skb, alignamount); - bdp->bufPtr = dma_map_single(NULL, skb->data, + bdp->bufPtr = dma_map_single(&dev->dev, skb->data, priv->rx_buffer_size, DMA_FROM_DEVICE); bdp->length = 0; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index bff280eff5e..6a1f2309209 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -439,7 +439,7 @@ static int igb_request_irq(struct igb_adapter *adapter) err = igb_request_msix(adapter); if (!err) { /* enable IAM, auto-mask, - * DO NOT USE EIAME or IAME in legacy mode */ + * DO NOT USE EIAM or IAM in legacy mode */ wr32(E1000_IAM, IMS_ENABLE_MASK); goto request_done; } @@ -465,14 +465,9 @@ static int igb_request_irq(struct igb_adapter *adapter) err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED, netdev->name, netdev); - if (err) { + if (err) dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n", err); - goto request_done; - } - - /* enable IAM, auto-mask */ - wr32(E1000_IAM, IMS_ENABLE_MASK); request_done: return err; @@ -821,7 +816,8 @@ void igb_reset(struct igb_adapter *adapter) wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE); igb_reset_adaptive(&adapter->hw); - adapter->hw.phy.ops.get_phy_info(&adapter->hw); + if (adapter->hw.phy.ops.get_phy_info) + adapter->hw.phy.ops.get_phy_info(&adapter->hw); } /** @@ -2057,7 +2053,8 @@ static void igb_set_multi(struct net_device *netdev) static void igb_update_phy_info(unsigned long data) { struct igb_adapter *adapter = (struct igb_adapter *) data; - adapter->hw.phy.ops.get_phy_info(&adapter->hw); + if (adapter->hw.phy.ops.get_phy_info) + adapter->hw.phy.ops.get_phy_info(&adapter->hw); } /** diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index 53a9fd086f9..75f3a68ee35 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -67,6 +67,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = { {"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)}, {"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)}, {"rx_frame_errors", IXGB_STAT(net_stats.rx_frame_errors)}, + {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)}, {"rx_fifo_errors", IXGB_STAT(net_stats.rx_fifo_errors)}, {"rx_missed_errors", IXGB_STAT(net_stats.rx_missed_errors)}, {"tx_aborted_errors", IXGB_STAT(net_stats.tx_aborted_errors)}, diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 81bf005ff28..1d210ed4613 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -148,7 +148,7 @@ static void macb_handle_link_change(struct net_device *dev) if (phydev->duplex) reg |= MACB_BIT(FD); - if (phydev->speed) + if (phydev->speed == SPEED_100) reg |= MACB_BIT(SPD); macb_writel(bp, NCFGR, reg); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 6323988dfa1..fd8158a86f6 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -590,6 +590,13 @@ static int pcnet_config(struct pcmcia_device *link) dev->if_port = 0; } + if ((link->conf.ConfigBase == 0x03c0) + && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) { + printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n"); + printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n"); + goto failed; + } + local_hw_info = get_hwinfo(link); if (local_hw_info == NULL) local_hw_info = get_prom(link); @@ -1567,12 +1574,11 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145), PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230), PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), -/* PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), conflict with axnet_cs */ + PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), -/* PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), conflict with axnet_cs */ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a), diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 6e9f619c491..963630c65ca 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -49,13 +49,13 @@ int mdiobus_register(struct mii_bus *bus) int i; int err = 0; - mutex_init(&bus->mdio_lock); - if (NULL == bus || NULL == bus->name || NULL == bus->read || NULL == bus->write) return -EINVAL; + mutex_init(&bus->mdio_lock); + if (bus->reset) bus->reset(bus); diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 750d2a99cb4..daf5abab953 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -2690,6 +2690,7 @@ int gelic_wl_driver_probe(struct gelic_card *card) return -ENOMEM; /* setup net_device structure */ + SET_NETDEV_DEV(netdev, &card->dev->core); gelic_wl_setup_netdev_ops(netdev); /* setup some of net_device and register it */ diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 202fdf35662..20745fd4e97 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1633,13 +1633,18 @@ static inline void sis190_init_rxfilter(struct net_device *dev) static int __devinit sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev) { - u8 from; + int rc; + + rc = sis190_get_mac_addr_from_eeprom(pdev, dev); + if (rc < 0) { + u8 reg; - pci_read_config_byte(pdev, 0x73, &from); + pci_read_config_byte(pdev, 0x73, ®); - return (from & 0x00000001) ? - sis190_get_mac_addr_from_apc(pdev, dev) : - sis190_get_mac_addr_from_eeprom(pdev, dev); + if (reg & 0x00000001) + rc = sis190_get_mac_addr_from_apc(pdev, dev); + } + return rc; } static void sis190_set_speed_auto(struct net_device *dev) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 9a6295909e4..54c662690f6 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -572,8 +572,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) default: /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; + /* turn off the Rx LED (LED_RX) */ - ledover &= ~PHY_M_LED_MO_RX; + ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); } if (hw->chip_id == CHIP_ID_YUKON_EC_U && @@ -602,7 +603,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { /* turn on 100 Mbps LED (LED_LINK100) */ - ledover |= PHY_M_LED_MO_100; + ledover |= PHY_M_LED_MO_100(MO_LED_ON); } if (ledover) @@ -3322,82 +3323,80 @@ static void sky2_set_multicast(struct net_device *dev) /* Can have one global because blinking is controlled by * ethtool and that is always under RTNL mutex */ -static void sky2_led(struct sky2_hw *hw, unsigned port, int on) +static void sky2_led(struct sky2_port *sky2, enum led_mode mode) { - u16 pg; + struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; - switch (hw->chip_id) { - case CHIP_ID_YUKON_XL: + spin_lock_bh(&sky2->phy_lock); + if (hw->chip_id == CHIP_ID_YUKON_EC_U || + hw->chip_id == CHIP_ID_YUKON_EX || + hw->chip_id == CHIP_ID_YUKON_SUPR) { + u16 pg; pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, - on ? (PHY_M_LEDC_LOS_CTRL(1) | - PHY_M_LEDC_INIT_CTRL(7) | - PHY_M_LEDC_STA1_CTRL(7) | - PHY_M_LEDC_STA0_CTRL(7)) - : 0); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - break; + switch (mode) { + case MO_LED_OFF: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(8) | + PHY_M_LEDC_INIT_CTRL(8) | + PHY_M_LEDC_STA1_CTRL(8) | + PHY_M_LEDC_STA0_CTRL(8)); + break; + case MO_LED_ON: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(9) | + PHY_M_LEDC_INIT_CTRL(9) | + PHY_M_LEDC_STA1_CTRL(9) | + PHY_M_LEDC_STA0_CTRL(9)); + break; + case MO_LED_BLINK: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(0xa) | + PHY_M_LEDC_INIT_CTRL(0xa) | + PHY_M_LEDC_STA1_CTRL(0xa) | + PHY_M_LEDC_STA0_CTRL(0xa)); + break; + case MO_LED_NORM: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(1) | + PHY_M_LEDC_INIT_CTRL(8) | + PHY_M_LEDC_STA1_CTRL(7) | + PHY_M_LEDC_STA0_CTRL(7)); + } - default: - gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); + } else gm_phy_write(hw, port, PHY_MARV_LED_OVER, - on ? PHY_M_LED_ALL : 0); - } + PHY_M_LED_MO_DUP(mode) | + PHY_M_LED_MO_10(mode) | + PHY_M_LED_MO_100(mode) | + PHY_M_LED_MO_1000(mode) | + PHY_M_LED_MO_RX(mode) | + PHY_M_LED_MO_TX(mode)); + + spin_unlock_bh(&sky2->phy_lock); } /* blink LED's for finding board */ static int sky2_phys_id(struct net_device *dev, u32 data) { struct sky2_port *sky2 = netdev_priv(dev); - struct sky2_hw *hw = sky2->hw; - unsigned port = sky2->port; - u16 ledctrl, ledover = 0; - long ms; - int interrupted; - int onoff = 1; + unsigned int i; - if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)) - ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT); - else - ms = data * 1000; - - /* save initial values */ - spin_lock_bh(&sky2->phy_lock); - if (hw->chip_id == CHIP_ID_YUKON_XL) { - u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - } else { - ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL); - ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER); - } - - interrupted = 0; - while (!interrupted && ms > 0) { - sky2_led(hw, port, onoff); - onoff = !onoff; - - spin_unlock_bh(&sky2->phy_lock); - interrupted = msleep_interruptible(250); - spin_lock_bh(&sky2->phy_lock); - - ms -= 250; - } + if (data == 0) + data = UINT_MAX; - /* resume regularly scheduled programming */ - if (hw->chip_id == CHIP_ID_YUKON_XL) { - u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - } else { - gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); - gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); + for (i = 0; i < data; i++) { + sky2_led(sky2, MO_LED_ON); + if (msleep_interruptible(500)) + break; + sky2_led(sky2, MO_LED_OFF); + if (msleep_interruptible(500)) + break; } - spin_unlock_bh(&sky2->phy_lock); + sky2_led(sky2, MO_LED_NORM); return 0; } diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 5ab5c1c7c5a..7bb3ba9bcbd 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1318,18 +1318,21 @@ enum { BLINK_670MS = 4,/* 670 ms */ }; -/**** PHY_MARV_LED_OVER 16 bit r/w LED control */ -enum { - PHY_M_LED_MO_DUP = 3<<10,/* Bit 11..10: Duplex */ - PHY_M_LED_MO_10 = 3<<8, /* Bit 9.. 8: Link 10 */ - PHY_M_LED_MO_100 = 3<<6, /* Bit 7.. 6: Link 100 */ - PHY_M_LED_MO_1000 = 3<<4, /* Bit 5.. 4: Link 1000 */ - PHY_M_LED_MO_RX = 3<<2, /* Bit 3.. 2: Rx */ - PHY_M_LED_MO_TX = 3<<0, /* Bit 1.. 0: Tx */ - - PHY_M_LED_ALL = PHY_M_LED_MO_DUP | PHY_M_LED_MO_10 - | PHY_M_LED_MO_100 | PHY_M_LED_MO_1000 - | PHY_M_LED_MO_RX, +/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ +#define PHY_M_LED_MO_SGMII(x) ((x)<<14) /* Bit 15..14: SGMII AN Timer */ + +#define PHY_M_LED_MO_DUP(x) ((x)<<10) /* Bit 11..10: Duplex */ +#define PHY_M_LED_MO_10(x) ((x)<<8) /* Bit 9.. 8: Link 10 */ +#define PHY_M_LED_MO_100(x) ((x)<<6) /* Bit 7.. 6: Link 100 */ +#define PHY_M_LED_MO_1000(x) ((x)<<4) /* Bit 5.. 4: Link 1000 */ +#define PHY_M_LED_MO_RX(x) ((x)<<2) /* Bit 3.. 2: Rx */ +#define PHY_M_LED_MO_TX(x) ((x)<<0) /* Bit 1.. 0: Tx */ + +enum led_mode { + MO_LED_NORM = 0, + MO_LED_BLINK = 1, + MO_LED_OFF = 2, + MO_LED_ON = 3, }; /***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/ diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 3af5b92b48c..0166407d706 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -1400,7 +1400,7 @@ static void TLan_SetMulticastList( struct net_device *dev ) * **************************************************************/ -u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) { /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */ return 0; @@ -1432,7 +1432,7 @@ u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); int eoc = 0; @@ -1518,7 +1518,7 @@ u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) { TLan_ReadAndClearStats( dev, TLAN_RECORD ); @@ -1554,7 +1554,7 @@ u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); u32 ack = 0; @@ -1689,7 +1689,7 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) { printk( "TLAN: Test interrupt on %s.\n", dev->name ); return 1; @@ -1719,7 +1719,7 @@ u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); TLanList *head_list; @@ -1767,7 +1767,7 @@ u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); u32 ack; @@ -1842,7 +1842,7 @@ u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); dma_addr_t head_list_phys; @@ -1902,7 +1902,7 @@ u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) * **************************************************************/ -void TLan_Timer( unsigned long data ) +static void TLan_Timer( unsigned long data ) { struct net_device *dev = (struct net_device *) data; TLanPrivateInfo *priv = netdev_priv(dev); @@ -1983,7 +1983,7 @@ void TLan_Timer( unsigned long data ) * **************************************************************/ -void TLan_ResetLists( struct net_device *dev ) +static void TLan_ResetLists( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); int i; @@ -2043,7 +2043,7 @@ void TLan_ResetLists( struct net_device *dev ) } /* TLan_ResetLists */ -void TLan_FreeLists( struct net_device *dev ) +static void TLan_FreeLists( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); int i; @@ -2092,7 +2092,7 @@ void TLan_FreeLists( struct net_device *dev ) * **************************************************************/ -void TLan_PrintDio( u16 io_base ) +static void TLan_PrintDio( u16 io_base ) { u32 data0, data1; int i; @@ -2127,7 +2127,7 @@ void TLan_PrintDio( u16 io_base ) * **************************************************************/ -void TLan_PrintList( TLanList *list, char *type, int num) +static void TLan_PrintList( TLanList *list, char *type, int num) { int i; @@ -2163,7 +2163,7 @@ void TLan_PrintList( TLanList *list, char *type, int num) * **************************************************************/ -void TLan_ReadAndClearStats( struct net_device *dev, int record ) +static void TLan_ReadAndClearStats( struct net_device *dev, int record ) { TLanPrivateInfo *priv = netdev_priv(dev); u32 tx_good, tx_under; @@ -2238,7 +2238,7 @@ void TLan_ReadAndClearStats( struct net_device *dev, int record ) * **************************************************************/ -void +static void TLan_ResetAdapter( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); @@ -2324,7 +2324,7 @@ TLan_ResetAdapter( struct net_device *dev ) -void +static void TLan_FinishReset( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); @@ -2448,7 +2448,7 @@ TLan_FinishReset( struct net_device *dev ) * **************************************************************/ -void TLan_SetMac( struct net_device *dev, int areg, char *mac ) +static void TLan_SetMac( struct net_device *dev, int areg, char *mac ) { int i; @@ -2490,7 +2490,7 @@ void TLan_SetMac( struct net_device *dev, int areg, char *mac ) * ********************************************************************/ -void TLan_PhyPrint( struct net_device *dev ) +static void TLan_PhyPrint( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 i, data0, data1, data2, data3, phy; @@ -2539,7 +2539,7 @@ void TLan_PhyPrint( struct net_device *dev ) * ********************************************************************/ -void TLan_PhyDetect( struct net_device *dev ) +static void TLan_PhyDetect( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 control; @@ -2586,7 +2586,7 @@ void TLan_PhyDetect( struct net_device *dev ) -void TLan_PhyPowerDown( struct net_device *dev ) +static void TLan_PhyPowerDown( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 value; @@ -2611,7 +2611,7 @@ void TLan_PhyPowerDown( struct net_device *dev ) -void TLan_PhyPowerUp( struct net_device *dev ) +static void TLan_PhyPowerUp( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 value; @@ -2632,7 +2632,7 @@ void TLan_PhyPowerUp( struct net_device *dev ) -void TLan_PhyReset( struct net_device *dev ) +static void TLan_PhyReset( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 phy; @@ -2660,7 +2660,7 @@ void TLan_PhyReset( struct net_device *dev ) -void TLan_PhyStartLink( struct net_device *dev ) +static void TLan_PhyStartLink( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 ability; @@ -2747,7 +2747,7 @@ void TLan_PhyStartLink( struct net_device *dev ) -void TLan_PhyFinishAutoNeg( struct net_device *dev ) +static void TLan_PhyFinishAutoNeg( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 an_adv; @@ -2903,7 +2903,7 @@ void TLan_PhyMonitor( struct net_device *dev ) * **************************************************************/ -int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) +static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) { u8 nack; u16 sio, tmp; @@ -2993,7 +2993,7 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) * **************************************************************/ -void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) +static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) { u16 sio; u32 i; @@ -3035,7 +3035,7 @@ void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) * **************************************************************/ -void TLan_MiiSync( u16 base_port ) +static void TLan_MiiSync( u16 base_port ) { int i; u16 sio; @@ -3074,7 +3074,7 @@ void TLan_MiiSync( u16 base_port ) * **************************************************************/ -void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) +static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) { u16 sio; int minten; @@ -3144,7 +3144,7 @@ void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) * **************************************************************/ -void TLan_EeSendStart( u16 io_base ) +static void TLan_EeSendStart( u16 io_base ) { u16 sio; @@ -3184,7 +3184,7 @@ void TLan_EeSendStart( u16 io_base ) * **************************************************************/ -int TLan_EeSendByte( u16 io_base, u8 data, int stop ) +static int TLan_EeSendByte( u16 io_base, u8 data, int stop ) { int err; u8 place; @@ -3245,7 +3245,7 @@ int TLan_EeSendByte( u16 io_base, u8 data, int stop ) * **************************************************************/ -void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) +static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) { u8 place; u16 sio; @@ -3303,7 +3303,7 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) * **************************************************************/ -int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) +static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) { int err; TLanPrivateInfo *priv = netdev_priv(dev); diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index a7afeea156b..a59c1f224aa 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -482,9 +482,11 @@ static void uli526x_init(struct net_device *dev) struct uli526x_board_info *db = netdev_priv(dev); unsigned long ioaddr = db->ioaddr; u8 phy_tmp; + u8 timeout; u16 phy_value; u16 phy_reg_reset; + ULI526X_DBUG(0, "uli526x_init()", 0); /* Reset M526x MAC controller */ @@ -509,11 +511,19 @@ static void uli526x_init(struct net_device *dev) /* Parser SROM and media mode */ db->media_mode = uli526x_media_mode; - /* Phyxcer capability setting */ + /* phyxcer capability setting */ phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id); phy_reg_reset = (phy_reg_reset | 0x8000); phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id); + + /* See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management + * functions") or phy data sheet for details on phy reset + */ udelay(500); + timeout = 10; + while (timeout-- && + phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id) & 0x8000) + udelay(100); /* Process Phyxcer Media Mode */ uli526x_set_phyxcer(db); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 7c851b1e6da..8c9d6ae2bb3 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -1893,7 +1893,7 @@ static void rhine_shutdown (struct pci_dev *pdev) /* Make sure we use pattern 0, 1 and not 4, 5 */ if (rp->quirks & rq6patterns) - iowrite8(0x04, ioaddr + 0xA7); + iowrite8(0x04, ioaddr + WOLcgClr); if (rp->wolopts & WAKE_MAGIC) { iowrite8(WOLmagic, ioaddr + WOLcrSet); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index fdc23678117..19fd4cb0ddf 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -361,6 +361,7 @@ static int virtnet_probe(struct virtio_device *vdev) netif_napi_add(dev, &vi->napi, virtnet_poll, napi_weight); vi->dev = dev; vi->vdev = vdev; + vdev->priv = vi; /* We expect two virtqueues, receive then send. */ vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); @@ -395,7 +396,6 @@ static int virtnet_probe(struct virtio_device *vdev) } pr_debug("virtnet: registered device %s\n", dev->name); - vdev->priv = vi; return 0; unregister: diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 1a2141dabdc..8bc4bc4c330 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -32,6 +32,7 @@ config B43_PCI_AUTOSELECT bool depends on B43 && SSB_PCIHOST_POSSIBLE select SSB_PCIHOST + select SSB_B43_PCI_BRIDGE default y # Auto-select SSB PCICORE driver, if possible diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 6745579ba96..13c65faf024 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig @@ -25,6 +25,7 @@ config B43LEGACY_PCI_AUTOSELECT bool depends on B43LEGACY && SSB_PCIHOST_POSSIBLE select SSB_PCIHOST + select SSB_B43_PCI_BRIDGE default y # Auto-select SSB PCICORE driver, if possible diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig index 0159701e845..afb8f4305c2 100644 --- a/drivers/net/wireless/bcm43xx/Kconfig +++ b/drivers/net/wireless/bcm43xx/Kconfig @@ -1,6 +1,6 @@ config BCM43XX tristate "Broadcom BCM43xx wireless support (DEPRECATED)" - depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL + depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && (!SSB_B43_PCI_BRIDGE || SSB != y) && EXPERIMENTAL select WIRELESS_EXT select FW_LOADER select HW_RANDOM diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index eab020338fd..b3c1acbcc65 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1040,7 +1040,6 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, lbs_deb_leave(LBS_DEB_CMD); return ret; } -EXPORT_SYMBOL_GPL(lbs_mesh_access); int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan) { @@ -1576,7 +1575,6 @@ done: lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command); /** * @brief This function allocates the command buffer and link diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index aaacd9bd6bd..4e22341b4f3 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -69,7 +69,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev); int lbs_remove_card(struct lbs_private *priv); int lbs_start_card(struct lbs_private *priv); int lbs_stop_card(struct lbs_private *priv); -int lbs_reset_device(struct lbs_private *priv); void lbs_host_to_card_done(struct lbs_private *priv); int lbs_update_channel(struct lbs_private *priv); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 84fb49ca0fa..4d4e2f3b66a 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1351,8 +1351,6 @@ done: lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(lbs_add_mesh); - static void lbs_remove_mesh(struct lbs_private *priv) { @@ -1372,7 +1370,6 @@ static void lbs_remove_mesh(struct lbs_private *priv) free_netdev(mesh_dev); lbs_deb_leave(LBS_DEB_MESH); } -EXPORT_SYMBOL_GPL(lbs_remove_mesh); /** * @brief This function finds the CFP in @@ -1458,20 +1455,6 @@ void lbs_interrupt(struct lbs_private *priv) } EXPORT_SYMBOL_GPL(lbs_interrupt); -int lbs_reset_device(struct lbs_private *priv) -{ - int ret; - - lbs_deb_enter(LBS_DEB_MAIN); - ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET, - CMD_ACT_HALT, 0, 0, NULL); - msleep_interruptible(10); - - lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); - return ret; -} -EXPORT_SYMBOL_GPL(lbs_reset_device); - static int __init lbs_init_module(void) { lbs_deb_enter(LBS_DEB_MAIN); diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 8ce2ddf8024..d9460aed1f2 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -228,9 +228,9 @@ struct NDIS_WLAN_BSSID_EX { struct NDIS_802_11_SSID Ssid; __le32 Privacy; __le32 Rssi; - enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + __le32 NetworkTypeInUse; struct NDIS_802_11_CONFIGURATION Configuration; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + __le32 InfrastructureMode; u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; __le32 IELength; u8 IEs[0]; @@ -279,11 +279,11 @@ struct RNDIS_CONFIG_PARAMETER_INFOBUFFER { } __attribute__((packed)); /* these have to match what is in wpa_supplicant */ -enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg; -enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 } - wpa_cipher; -enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA, - KEY_MGMT_WPA_NONE } wpa_key_mgmt; +enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; +enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, + CIPHER_WEP104 }; +enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, + KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE }; /* * private data diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index d6cba138c7a..c69f85ed766 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -960,8 +960,12 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2400pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt2400pci_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index e874fdcae20..91e87b53374 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1112,8 +1112,12 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt2500pci_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 4ca9730e5e9..638c3d24310 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1001,8 +1001,12 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt2500usb_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 72cfe00c1ed..07adc576db4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -97,12 +97,16 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, libconf.ant.rx = rx; libconf.ant.tx = tx; + if (rx == rt2x00dev->link.ant.active.rx && + tx == rt2x00dev->link.ant.active.tx) + return; + /* * Antenna setup changes require the RX to be disabled, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); /* * Write new antenna setup to device and reset the link tuner. @@ -116,7 +120,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, rt2x00dev->link.ant.active.tx = libconf.ant.tx; if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); } void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c4be2ac4d7a..0d51f478bcd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -61,11 +61,33 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); /* * Link tuning handlers */ -static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) +void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) { + if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) + return; + + /* + * Reset link information. + * Both the currently active vgc level as well as + * the link tuner counter should be reset. Resetting + * the counter is important for devices where the + * device should only perform link tuning during the + * first minute after being enabled. + */ rt2x00dev->link.count = 0; rt2x00dev->link.vgc_level = 0; + /* + * Reset the link tuner. + */ + rt2x00dev->ops->lib->reset_tuner(rt2x00dev); +} + +static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) +{ + /* + * Clear all (possibly) pre-existing quality statistics. + */ memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual)); /* @@ -79,10 +101,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) rt2x00dev->link.qual.rx_percentage = 50; rt2x00dev->link.qual.tx_percentage = 50; - /* - * Reset the link tuner. - */ - rt2x00dev->ops->lib->reset_tuner(rt2x00dev); + rt2x00lib_reset_link_tuner(rt2x00dev); queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, LINK_TUNE_INTERVAL); @@ -93,15 +112,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) cancel_delayed_work_sync(&rt2x00dev->link.work); } -void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) -{ - if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - return; - - rt2x00lib_stop_link_tuner(rt2x00dev); - rt2x00lib_start_link_tuner(rt2x00dev); -} - /* * Ring initialization */ @@ -260,19 +270,11 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev) if (sample_a == sample_b) return; - if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) { - if (sample_a > sample_b && rx == ANTENNA_B) - rx = ANTENNA_A; - else if (rx == ANTENNA_A) - rx = ANTENNA_B; - } + if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) + rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; - if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) { - if (sample_a > sample_b && tx == ANTENNA_B) - tx = ANTENNA_A; - else if (tx == ANTENNA_A) - tx = ANTENNA_B; - } + if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) + tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; rt2x00lib_config_antenna(rt2x00dev, rx, tx); } @@ -293,7 +295,7 @@ static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev) * sample the rssi from the other antenna to make a valid * comparison between the 2 antennas. */ - if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5) + if (abs(rssi_curr - rssi_old) < 5) return; rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE; @@ -319,15 +321,15 @@ static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev) rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY; if (rt2x00dev->hw->conf.antenna_sel_rx == 0 && - rt2x00dev->default_ant.rx != ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY; if (rt2x00dev->hw->conf.antenna_sel_tx == 0 && - rt2x00dev->default_ant.tx != ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY; if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) && !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) { - rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE; + rt2x00dev->link.ant.flags = 0; return; } @@ -441,17 +443,18 @@ static void rt2x00lib_link_tuner(struct work_struct *work) rt2x00dev->ops->lib->link_tuner(rt2x00dev); /* - * Evaluate antenna setup. - */ - rt2x00lib_evaluate_antenna(rt2x00dev); - - /* * Precalculate a portion of the link signal which is * in based on the tx/rx success/failure counters. */ rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); /* + * Evaluate antenna setup, make this the last step since this could + * possibly reset some statistics. + */ + rt2x00lib_evaluate_antenna(rt2x00dev); + + /* * Increase tuner counter, and reschedule the next link tuner run. */ rt2x00dev->link.count++; diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index 838421216da..b1915dc7dda 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -85,6 +85,8 @@ enum dev_state { STATE_RADIO_OFF, STATE_RADIO_RX_ON, STATE_RADIO_RX_OFF, + STATE_RADIO_RX_ON_LINK, + STATE_RADIO_RX_OFF_LINK, STATE_RADIO_IRQ_ON, STATE_RADIO_IRQ_OFF, }; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index b31f0c26c32..e808db98f2f 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1482,8 +1482,12 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt61pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt61pci_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 4d576ab3e7f..4fac2d414d8 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1208,8 +1208,12 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt73usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt73usb_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index a98b2470b9e..bd5c0e03139 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -242,8 +242,7 @@ void pci_remove_rom(struct pci_dev *pdev) #endif /* 0 */ /** - * pci_cleanup_rom - internal routine for freeing the ROM copy created - * by pci_map_rom_copy called from remove.c + * pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy * @pdev: pointer to pci device struct * * Free the copied ROM if we allocated one. diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 5480119ff9d..3ce9f3defc1 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -78,8 +78,7 @@ void rio_dev_put(struct rio_dev *rdev) } /** - * rio_device_probe - Tell if a RIO device structure has a matching RIO - * device id structure + * rio_device_probe - Tell if a RIO device structure has a matching RIO device id structure * @id: the RIO device id structure to match against * @dev: the RIO device structure to match against * @@ -137,7 +136,7 @@ static int rio_device_remove(struct device *dev) * rio_register_driver - register a new RIO driver * @rdrv: the RIO driver structure to register * - * Adds a &struct rio_driver to the list of registered drivers + * Adds a &struct rio_driver to the list of registered drivers. * Returns a negative value on error, otherwise 0. If no error * occurred, the driver remains registered even if no device * was claimed during registration. @@ -167,8 +166,7 @@ void rio_unregister_driver(struct rio_driver *rdrv) } /** - * rio_match_bus - Tell if a RIO device structure has a matching RIO - * driver device id structure + * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure * @dev: the standard device structure to match against * @drv: the standard driver structure containing the ids to match against * diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index c3076217871..d8a5c229c5a 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -1851,8 +1851,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid) } } /* See how many write buffers are required to hold this data */ - numBuffers= ( skb->len + privptr->p_env->write_size - 1) / - ( privptr->p_env->write_size); + numBuffers = DIV_ROUND_UP(skb->len, privptr->p_env->write_size); /* If that number of buffers isn't available, give up for now */ if (privptr->write_free_count < numBuffers || @@ -2114,8 +2113,7 @@ init_ccw_bk(struct net_device *dev) */ ccw_blocks_perpage= PAGE_SIZE / CCWBK_SIZE; ccw_pages_required= - (ccw_blocks_required+ccw_blocks_perpage -1) / - ccw_blocks_perpage; + DIV_ROUND_UP(ccw_blocks_required, ccw_blocks_perpage); #ifdef DEBUGMSG printk(KERN_INFO "%s: %s() > ccw_blocks_perpage=%d\n", @@ -2131,30 +2129,29 @@ init_ccw_bk(struct net_device *dev) * provide good performance. With packing buffers support 32k * buffers are used. */ - if (privptr->p_env->read_size < PAGE_SIZE) { - claw_reads_perpage= PAGE_SIZE / privptr->p_env->read_size; - claw_read_pages= (privptr->p_env->read_buffers + - claw_reads_perpage -1) / claw_reads_perpage; + if (privptr->p_env->read_size < PAGE_SIZE) { + claw_reads_perpage = PAGE_SIZE / privptr->p_env->read_size; + claw_read_pages = DIV_ROUND_UP(privptr->p_env->read_buffers, + claw_reads_perpage); } else { /* > or equal */ - privptr->p_buff_pages_perread= - (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE; - claw_read_pages= - privptr->p_env->read_buffers * privptr->p_buff_pages_perread; + privptr->p_buff_pages_perread = + DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE); + claw_read_pages = privptr->p_env->read_buffers * + privptr->p_buff_pages_perread; } if (privptr->p_env->write_size < PAGE_SIZE) { - claw_writes_perpage= - PAGE_SIZE / privptr->p_env->write_size; - claw_write_pages= - (privptr->p_env->write_buffers + claw_writes_perpage -1) / - claw_writes_perpage; + claw_writes_perpage = + PAGE_SIZE / privptr->p_env->write_size; + claw_write_pages = DIV_ROUND_UP(privptr->p_env->write_buffers, + claw_writes_perpage); } else { /* > or equal */ - privptr->p_buff_pages_perwrite= - (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE; - claw_write_pages= - privptr->p_env->write_buffers * privptr->p_buff_pages_perwrite; + privptr->p_buff_pages_perwrite = + DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE); + claw_write_pages = privptr->p_env->write_buffers * + privptr->p_buff_pages_perwrite; } #ifdef DEBUGMSG if (privptr->p_env->read_size < PAGE_SIZE) { diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 1dc165ad17f..e67c14e31ba 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1577,8 +1577,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, } /** - * scsi_scan_target - scan a target id, possibly including all LUNs on the - * target. + * scsi_scan_target - scan a target id, possibly including all LUNs on the target. * @parent: host to scan * @channel: channel to scan * @id: target id to scan diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b82595cf13e..cf627cd1b4c 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -686,7 +686,7 @@ config UART0_RTS_PIN config SERIAL_BFIN_UART1 bool "Enable UART1" - depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x) + depends on SERIAL_BFIN && (!BF531 && !BF532 && !BF533 && !BF561) help Enable UART1 @@ -699,14 +699,14 @@ config BFIN_UART1_CTSRTS config UART1_CTS_PIN int "UART1 CTS pin" - depends on BFIN_UART1_CTSRTS && (BF53x || BF561) + depends on BFIN_UART1_CTSRTS && !BF54x default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. config UART1_RTS_PIN int "UART1 RTS pin" - depends on BFIN_UART1_CTSRTS && (BF53x || BF561) + depends on BFIN_UART1_CTSRTS && !BF54x default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index ac2a3ef28d5..0aa345b9a38 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -1,30 +1,11 @@ /* - * File: drivers/serial/bfin_5xx.c - * Based on: Based on drivers/serial/sa1100.c - * Author: Aubrey Li <aubrey.li@analog.com> + * Blackfin On-Chip Serial Driver * - * Created: - * Description: Driver for blackfin 5xx serial ports + * Copyright 2006-2007 Analog Devices Inc. * - * Modified: - * Copyright 2006 Analog Devices Inc. + * Enter bugs at http://blackfin.uclinux.org/ * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Licensed under the GPL-2 or later. */ #if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) @@ -67,14 +48,12 @@ #define DMA_RX_XCOUNT 512 #define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) -#define DMA_RX_FLUSH_JIFFIES 5 +#define DMA_RX_FLUSH_JIFFIES (HZ / 50) #ifdef CONFIG_SERIAL_BFIN_DMA static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); #else -static void bfin_serial_do_work(struct work_struct *work); static void bfin_serial_tx_chars(struct bfin_serial_port *uart); -static void local_put_char(struct bfin_serial_port *uart, char ch); #endif static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); @@ -85,23 +64,26 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); static void bfin_serial_stop_tx(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; + struct circ_buf *xmit = &uart->port.info->xmit; +#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA) + unsigned short ier; +#endif while (!(UART_GET_LSR(uart) & TEMT)) - continue; + cpu_relax(); #ifdef CONFIG_SERIAL_BFIN_DMA disable_dma(uart->tx_dma_channel); + xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx += uart->tx_count; + uart->tx_count = 0; + uart->tx_done = 1; #else #ifdef CONFIG_BF54x - /* Waiting for Transmission Finished */ - while (!(UART_GET_LSR(uart) & TFI)) - continue; /* Clear TFI bit */ UART_PUT_LSR(uart, TFI); UART_CLEAR_IER(uart, ETBEI); #else - unsigned short ier; - ier = UART_GET_IER(uart); ier &= ~ETBEI; UART_PUT_IER(uart, ier); @@ -117,7 +99,8 @@ static void bfin_serial_start_tx(struct uart_port *port) struct bfin_serial_port *uart = (struct bfin_serial_port *)port; #ifdef CONFIG_SERIAL_BFIN_DMA - bfin_serial_dma_tx_chars(uart); + if (uart->tx_done) + bfin_serial_dma_tx_chars(uart); #else #ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); @@ -209,34 +192,27 @@ int kgdb_get_debug_char(void) } #endif -#ifdef CONFIG_SERIAL_BFIN_PIO -static void local_put_char(struct bfin_serial_port *uart, char ch) -{ - unsigned short status; - int flags = 0; - - spin_lock_irqsave(&uart->port.lock, flags); - - do { - status = UART_GET_LSR(uart); - } while (!(status & THRE)); - - UART_PUT_CHAR(uart, ch); - SSYNC(); - - spin_unlock_irqrestore(&uart->port.lock, flags); -} +#if ANOMALY_05000230 && defined(CONFIG_SERIAL_BFIN_PIO) +# define UART_GET_ANOMALY_THRESHOLD(uart) ((uart)->anomaly_threshold) +# define UART_SET_ANOMALY_THRESHOLD(uart, v) ((uart)->anomaly_threshold = (v)) +#else +# define UART_GET_ANOMALY_THRESHOLD(uart) 0 +# define UART_SET_ANOMALY_THRESHOLD(uart, v) +#endif +#ifdef CONFIG_SERIAL_BFIN_PIO static void bfin_serial_rx_chars(struct bfin_serial_port *uart) { struct tty_struct *tty = uart->port.info->tty; unsigned int status, ch, flg; - static int in_break = 0; + static struct timeval anomaly_start = { .tv_sec = 0 }; #ifdef CONFIG_KGDB_UART struct pt_regs *regs = get_irq_regs(); #endif status = UART_GET_LSR(uart); + UART_CLEAR_LSR(uart); + ch = UART_GET_CHAR(uart); uart->port.icount.rx++; @@ -262,28 +238,56 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) #endif if (ANOMALY_05000230) { - /* The BF533 family of processors have a nice misbehavior where - * they continuously generate characters for a "single" break. + /* The BF533 (and BF561) family of processors have a nice anomaly + * where they continuously generate characters for a "single" break. * We have to basically ignore this flood until the "next" valid - * character comes across. All other Blackfin families operate - * properly though. + * character comes across. Due to the nature of the flood, it is + * not possible to reliably catch bytes that are sent too quickly + * after this break. So application code talking to the Blackfin + * which sends a break signal must allow at least 1.5 character + * times after the end of the break for things to stabilize. This + * timeout was picked as it must absolutely be larger than 1 + * character time +/- some percent. So 1.5 sounds good. All other + * Blackfin families operate properly. Woo. * Note: While Anomaly 05000230 does not directly address this, * the changes that went in for it also fixed this issue. + * That anomaly was fixed in 0.5+ silicon. I like bunnies. */ - if (in_break) { - if (ch != 0) { - in_break = 0; - ch = UART_GET_CHAR(uart); - if (bfin_revid() < 5) - return; - } else - return; + if (anomaly_start.tv_sec) { + struct timeval curr; + suseconds_t usecs; + + if ((~ch & (~ch + 1)) & 0xff) + goto known_good_char; + + do_gettimeofday(&curr); + if (curr.tv_sec - anomaly_start.tv_sec > 1) + goto known_good_char; + + usecs = 0; + if (curr.tv_sec != anomaly_start.tv_sec) + usecs += USEC_PER_SEC; + usecs += curr.tv_usec - anomaly_start.tv_usec; + + if (usecs > UART_GET_ANOMALY_THRESHOLD(uart)) + goto known_good_char; + + if (ch) + anomaly_start.tv_sec = 0; + else + anomaly_start = curr; + + return; + + known_good_char: + anomaly_start.tv_sec = 0; } } if (status & BI) { if (ANOMALY_05000230) - in_break = 1; + if (bfin_revid() < 5) + do_gettimeofday(&anomaly_start); uart->port.icount.brk++; if (uart_handle_break(&uart->port)) goto ignore_char; @@ -324,7 +328,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) UART_PUT_CHAR(uart, uart->port.x_char); uart->port.icount.tx++; uart->port.x_char = 0; - return; } /* * Check the modem control lines before @@ -337,9 +340,12 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) return; } - local_put_char(uart, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - uart->port.icount.tx++; + while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) { + UART_PUT_CHAR(uart, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx++; + SSYNC(); + } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); @@ -352,21 +358,11 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; -#ifdef CONFIG_BF54x - unsigned short status; - spin_lock(&uart->port.lock); - status = UART_GET_LSR(uart); - while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) { - bfin_serial_rx_chars(uart); - status = UART_GET_LSR(uart); - } - spin_unlock(&uart->port.lock); -#else spin_lock(&uart->port.lock); - while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) + while (UART_GET_LSR(uart) & DR) bfin_serial_rx_chars(uart); spin_unlock(&uart->port.lock); -#endif + return IRQ_HANDLED; } @@ -374,25 +370,16 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; -#ifdef CONFIG_BF54x - unsigned short status; spin_lock(&uart->port.lock); - status = UART_GET_LSR(uart); - while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) { + if (UART_GET_LSR(uart) & THRE) bfin_serial_tx_chars(uart); - status = UART_GET_LSR(uart); - } spin_unlock(&uart->port.lock); -#else - spin_lock(&uart->port.lock); - while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) - bfin_serial_tx_chars(uart); - spin_unlock(&uart->port.lock); -#endif + return IRQ_HANDLED; } +#endif - +#ifdef CONFIG_SERIAL_BFIN_CTSRTS static void bfin_serial_do_work(struct work_struct *work) { struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue); @@ -406,33 +393,27 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) { struct circ_buf *xmit = &uart->port.info->xmit; unsigned short ier; - int flags = 0; - - if (!uart->tx_done) - return; uart->tx_done = 0; + if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { + uart->tx_count = 0; + uart->tx_done = 1; + return; + } + if (uart->port.x_char) { UART_PUT_CHAR(uart, uart->port.x_char); uart->port.icount.tx++; uart->port.x_char = 0; - uart->tx_done = 1; - return; } + /* * Check the modem control lines before * transmitting anything. */ bfin_serial_mctrl_check(uart); - if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { - bfin_serial_stop_tx(&uart->port); - uart->tx_done = 1; - return; - } - - spin_lock_irqsave(&uart->port.lock, flags); uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail)) uart->tx_count = UART_XMIT_SIZE - xmit->tail; @@ -448,6 +429,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) set_dma_x_count(uart->tx_dma_channel, uart->tx_count); set_dma_x_modify(uart->tx_dma_channel, 1); enable_dma(uart->tx_dma_channel); + #ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); #else @@ -455,7 +437,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) ier |= ETBEI; UART_PUT_IER(uart, ier); #endif - spin_unlock_irqrestore(&uart->port.lock, flags); } static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) @@ -464,7 +445,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) int i, flg, status; status = UART_GET_LSR(uart); - uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);; + UART_CLEAR_LSR(uart); + + uart->port.icount.rx += + CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, + UART_XMIT_SIZE); if (status & BI) { uart->port.icount.brk++; @@ -490,10 +475,12 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) else flg = TTY_NORMAL; - for (i = uart->rx_dma_buf.head; i < uart->rx_dma_buf.tail; i++) { - if (uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) - goto dma_ignore_char; - uart_insert_char(&uart->port, status, OE, uart->rx_dma_buf.buf[i], flg); + for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) { + if (i >= UART_XMIT_SIZE) + i = 0; + if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) + uart_insert_char(&uart->port, status, OE, + uart->rx_dma_buf.buf[i], flg); } dma_ignore_char: @@ -503,23 +490,23 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) { int x_pos, pos; - int flags = 0; - - bfin_serial_dma_tx_chars(uart); - spin_lock_irqsave(&uart->port.lock, flags); - x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel); + uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel); + x_pos = get_dma_curr_xcount(uart->rx_dma_channel); + uart->rx_dma_nrows = DMA_RX_YCOUNT - uart->rx_dma_nrows; + if (uart->rx_dma_nrows == DMA_RX_YCOUNT) + uart->rx_dma_nrows = 0; + x_pos = DMA_RX_XCOUNT - x_pos; if (x_pos == DMA_RX_XCOUNT) x_pos = 0; pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos; - - if (pos>uart->rx_dma_buf.tail) { - uart->rx_dma_buf.tail = pos; + if (pos != uart->rx_dma_buf.tail) { + uart->rx_dma_buf.head = pos; bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail; + uart->rx_dma_buf.tail = uart->rx_dma_buf.head; } - spin_unlock_irqrestore(&uart->port.lock, flags); + uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; add_timer(&(uart->rx_dma_timer)); } @@ -532,8 +519,8 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) spin_lock(&uart->port.lock); if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { - clear_dma_irqstat(uart->tx_dma_channel); disable_dma(uart->tx_dma_channel); + clear_dma_irqstat(uart->tx_dma_channel); #ifdef CONFIG_BF54x UART_CLEAR_IER(uart, ETBEI); #else @@ -541,15 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) ier &= ~ETBEI; UART_PUT_IER(uart, ier); #endif - xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); - uart->port.icount.tx+=uart->tx_count; + xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx += uart->tx_count; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); - if (uart_circ_empty(xmit)) - bfin_serial_stop_tx(&uart->port); - uart->tx_done = 1; + bfin_serial_dma_tx_chars(uart); } spin_unlock(&uart->port.lock); @@ -561,18 +546,15 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) struct bfin_serial_port *uart = dev_id; unsigned short irqstat; - uart->rx_dma_nrows++; - if (uart->rx_dma_nrows == DMA_RX_YCOUNT) { - uart->rx_dma_nrows = 0; - uart->rx_dma_buf.tail = DMA_RX_XCOUNT*DMA_RX_YCOUNT; - bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail = 0; - } spin_lock(&uart->port.lock); irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); clear_dma_irqstat(uart->rx_dma_channel); - spin_unlock(&uart->port.lock); + + del_timer(&(uart->rx_dma_timer)); + uart->rx_dma_timer.expires = jiffies; + add_timer(&(uart->rx_dma_timer)); + return IRQ_HANDLED; } #endif @@ -599,7 +581,11 @@ static unsigned int bfin_serial_get_mctrl(struct uart_port *port) if (uart->cts_pin < 0) return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +# ifdef BF54x + if (UART_GET_MSR(uart) & CTS) +# else if (gpio_get_value(uart->cts_pin)) +# endif return TIOCM_DSR | TIOCM_CAR; else #endif @@ -614,9 +600,17 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) return; if (mctrl & TIOCM_RTS) +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) & ~MRTS); +# else gpio_set_value(uart->rts_pin, 0); +# endif else +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) | MRTS); +# else gpio_set_value(uart->rts_pin, 1); +# endif #endif } @@ -627,22 +621,17 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) { #ifdef CONFIG_SERIAL_BFIN_CTSRTS unsigned int status; -# ifdef CONFIG_SERIAL_BFIN_DMA struct uart_info *info = uart->port.info; struct tty_struct *tty = info->tty; status = bfin_serial_get_mctrl(&uart->port); + uart_handle_cts_change(&uart->port, status & TIOCM_CTS); if (!(status & TIOCM_CTS)) { tty->hw_stopped = 1; + schedule_work(&uart->cts_workqueue); } else { tty->hw_stopped = 0; } -# else - status = bfin_serial_get_mctrl(&uart->port); - uart_handle_cts_change(&uart->port, status & TIOCM_CTS); - if (!(status & TIOCM_CTS)) - schedule_work(&uart->cts_workqueue); -# endif #endif } @@ -743,6 +732,7 @@ static void bfin_serial_shutdown(struct uart_port *port) disable_dma(uart->rx_dma_channel); free_dma(uart->rx_dma_channel); del_timer(&(uart->rx_dma_timer)); + dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0); #else #ifdef CONFIG_KGDB_UART if (uart->port.line != CONFIG_KGDB_UART_PORT) @@ -814,6 +804,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, quot = uart_get_divisor(port, baud); spin_lock_irqsave(&uart->port.lock, flags); + UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); + do { lsr = UART_GET_LSR(uart); } while (!(lsr & TEMT)); @@ -956,10 +948,9 @@ static void __init bfin_serial_init_ports(void) bfin_serial_ports[i].rx_dma_channel = bfin_serial_resource[i].uart_rx_dma_channel; init_timer(&(bfin_serial_ports[i].rx_dma_timer)); -#else - INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); bfin_serial_ports[i].cts_pin = bfin_serial_resource[i].uart_cts_pin; bfin_serial_ports[i].rts_pin = diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 9ce12cb2ceb..a8c116b80bf 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -41,6 +41,7 @@ #include <linux/delay.h> #include <linux/console.h> #include <linux/platform_device.h> +#include <linux/serial_sci.h> #ifdef CONFIG_CPU_FREQ #include <linux/notifier.h> @@ -54,7 +55,6 @@ #include <asm/kgdb.h> #endif -#include <asm/sci.h> #include "sh-sci.h" struct sci_port { diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index 9cfcfd8dad5..617efb1640b 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -1,7 +1,7 @@ /* * Core maple bus functionality * - * Copyright (C) 2007 Adrian McMenamin + * Copyright (C) 2007, 2008 Adrian McMenamin * * Based on 2.4 code by: * @@ -18,7 +18,6 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/device.h> -#include <linux/module.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/io.h> @@ -54,7 +53,7 @@ static struct device maple_bus; static int subdevice_map[MAPLE_PORTS]; static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; static unsigned long maple_pnp_time; -static int started, scanning, liststatus, realscan; +static int started, scanning, liststatus, fullscan; static struct kmem_cache *maple_queue_cache; struct maple_device_specify { @@ -62,6 +61,9 @@ struct maple_device_specify { int unit; }; +static bool checked[4]; +static struct maple_device *baseunits[4]; + /** * maple_driver_register - register a device driver * automatically makes the driver bus a maple bus @@ -309,11 +311,9 @@ static void maple_attach_driver(struct maple_device *mdev) else break; - if (realscan) { - printk(KERN_INFO "Maple device detected: %s\n", - mdev->product_name); - printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); - } + printk(KERN_INFO "Maple device detected: %s\n", + mdev->product_name); + printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); function = be32_to_cpu(mdev->devinfo.function); @@ -323,10 +323,9 @@ static void maple_attach_driver(struct maple_device *mdev) mdev->driver = &maple_dummy_driver; sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port); } else { - if (realscan) - printk(KERN_INFO - "Maple bus at (%d, %d): Function 0x%lX\n", - mdev->port, mdev->unit, function); + printk(KERN_INFO + "Maple bus at (%d, %d): Function 0x%lX\n", + mdev->port, mdev->unit, function); matched = bus_for_each_drv(&maple_bus_type, NULL, mdev, @@ -334,9 +333,8 @@ static void maple_attach_driver(struct maple_device *mdev) if (matched == 0) { /* Driver does not exist yet */ - if (realscan) - printk(KERN_INFO - "No maple driver found.\n"); + printk(KERN_INFO + "No maple driver found.\n"); mdev->driver = &maple_dummy_driver; } sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port, @@ -472,9 +470,12 @@ static void maple_response_none(struct maple_device *mdev, maple_detach_driver(mdev); return; } - if (!started) { - printk(KERN_INFO "No maple devices attached to port %d\n", - mdev->port); + if (!started || !fullscan) { + if (checked[mdev->port] == false) { + checked[mdev->port] = true; + printk(KERN_INFO "No maple devices attached" + " to port %d\n", mdev->port); + } return; } maple_clean_submap(mdev); @@ -485,8 +486,14 @@ static void maple_response_devinfo(struct maple_device *mdev, char *recvbuf) { char submask; - if ((!started) || (scanning == 2)) { - maple_attach_driver(mdev); + if (!started || (scanning == 2) || !fullscan) { + if ((mdev->unit == 0) && (checked[mdev->port] == false)) { + checked[mdev->port] = true; + maple_attach_driver(mdev); + } else { + if (mdev->unit != 0) + maple_attach_driver(mdev); + } return; } if (mdev->unit == 0) { @@ -505,6 +512,7 @@ static void maple_dma_handler(struct work_struct *work) struct maple_device *dev; char *recvbuf; enum maple_code code; + int i; if (!maple_dma_done()) return; @@ -557,6 +565,19 @@ static void maple_dma_handler(struct work_struct *work) } else scanning = 0; + if (!fullscan) { + fullscan = 1; + for (i = 0; i < MAPLE_PORTS; i++) { + if (checked[i] == false) { + fullscan = 0; + dev = baseunits[i]; + dev->mq->command = + MAPLE_COMMAND_DEVINFO; + dev->mq->length = 0; + maple_add_packet(dev->mq); + } + } + } if (started == 0) started = 1; } @@ -694,7 +715,9 @@ static int __init maple_bus_init(void) /* setup maple ports */ for (i = 0; i < MAPLE_PORTS; i++) { + checked[i] = false; mdev[i] = maple_alloc_dev(i, 0); + baseunits[i] = mdev[i]; if (!mdev[i]) { while (i-- > 0) maple_free_dev(mdev[i]); @@ -703,12 +726,9 @@ static int __init maple_bus_init(void) mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; mdev[i]->mq->length = 0; maple_add_packet(mdev[i]->mq); - /* delay aids hardware detection */ - mdelay(5); subdevice_map[i] = 0; } - realscan = 1; /* setup maplebus hardware */ maplebus_dma_reset(); /* initial detection */ diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 78fd33125e0..adea792fb67 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig @@ -35,6 +35,11 @@ config SSB_PCIHOST If unsure, say Y +config SSB_B43_PCI_BRIDGE + bool + depends on SSB_PCIHOST + default n + config SSB_PCMCIAHOST_POSSIBLE bool depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile index e235144add7..de94c2eb7a3 100644 --- a/drivers/ssb/Makefile +++ b/drivers/ssb/Makefile @@ -14,6 +14,6 @@ ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o # b43 pci-ssb-bridge driver # Not strictly a part of SSB, but kept here for convenience -ssb-$(CONFIG_SSB_PCIHOST) += b43_pci_bridge.o +ssb-$(CONFIG_SSB_B43_PCI_BRIDGE) += b43_pci_bridge.o obj-$(CONFIG_SSB) += ssb.o diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 6d99a988005..07ab48d9cea 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -393,7 +393,7 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) chipid_top != 0x5300) return 0; - if (bus->sprom.r1.boardflags_lo & SSB_PCICORE_BFL_NOPCI) + if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI) return 0; /* The 200-pin BCM4712 package does not bond out PCI. Even when diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index a789364264a..21eca2b5118 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h @@ -120,10 +120,10 @@ extern int ssb_devices_thaw(struct ssb_bus *bus); extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev); /* b43_pci_bridge.c */ -#ifdef CONFIG_SSB_PCIHOST +#ifdef CONFIG_SSB_B43_PCI_BRIDGE extern int __init b43_pci_ssb_bridge_init(void); extern void __exit b43_pci_ssb_bridge_exit(void); -#else /* CONFIG_SSB_PCIHOST */ +#else /* CONFIG_SSB_B43_PCI_BRIDGR */ static inline int b43_pci_ssb_bridge_init(void) { return 0; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4e984060c98..f6f19908f5f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -99,8 +99,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev, EXPORT_SYMBOL_GPL(usb_ifnum_to_if); /** - * usb_altnum_to_altsetting - get the altsetting structure with a given - * alternate setting number. + * usb_altnum_to_altsetting - get the altsetting structure with a given alternate setting number. * @intf: the interface containing the altsetting in question * @altnum: the desired alternate setting number * @@ -442,8 +441,7 @@ EXPORT_SYMBOL_GPL(usb_put_intf); */ /** - * usb_lock_device_for_reset - cautiously acquire the lock for a - * usb device structure + * usb_lock_device_for_reset - cautiously acquire the lock for a usb device structure * @udev: device that's being locked * @iface: interface bound to the driver making the request (optional) * diff --git a/fs/buffer.c b/fs/buffer.c index 3ebccf4aa7e..897cd7477b3 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -627,8 +627,7 @@ repeat: } /** - * sync_mapping_buffers - write out and wait upon a mapping's "associated" - * buffers + * sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers * @mapping: the mapping which wants those buffers written * * Starts I/O against the buffers at mapping->private_list, and waits upon diff --git a/fs/exec.c b/fs/exec.c index a44b142fb46..54a0a557b67 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, return NULL; if (write) { - struct rlimit *rlim = current->signal->rlim; unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; + struct rlimit *rlim; + + /* + * We've historically supported up to 32 pages (ARG_MAX) + * of argument strings even with small stacks + */ + if (size <= ARG_MAX) + return page; /* * Limit to 1/4-th the stack size for the argv+env strings. @@ -183,6 +190,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, * - the program will have a reasonable amount of stack left * to work from. */ + rlim = current->signal->rlim; if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { put_page(page); return NULL; diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 038ed743619..c6cbb6cd59b 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -369,7 +369,7 @@ out: /** - * int journal_restart() - restart a handle . + * int journal_restart() - restart a handle. * @handle: handle to restart * @nblocks: nr credits requested * @@ -844,8 +844,7 @@ out: } /** - * int journal_get_undo_access() - Notify intent to modify metadata with - * non-rewindable consequences + * int journal_get_undo_access() - Notify intent to modify metadata with non-rewindable consequences * @handle: transaction * @bh: buffer to undo * @credits: store the number of taken credits here (if not NULL) @@ -921,12 +920,14 @@ out: } /** - * int journal_dirty_data() - mark a buffer as containing dirty data which - * needs to be flushed before we can commit the - * current transaction. + * int journal_dirty_data() - mark a buffer as containing dirty data to be flushed * @handle: transaction * @bh: bufferhead to mark * + * Description: + * Mark a buffer as containing dirty data which needs to be flushed before + * we can commit the current transaction. + * * The buffer is placed on the transaction's data list and is marked as * belonging to the transaction. * @@ -1098,11 +1099,11 @@ no_journal: } /** - * int journal_dirty_metadata() - mark a buffer as containing dirty metadata + * int journal_dirty_metadata() - mark a buffer as containing dirty metadata * @handle: transaction to add buffer to. * @bh: buffer to mark * - * mark dirty metadata which needs to be journaled as part of the current + * Mark dirty metadata which needs to be journaled as part of the current * transaction. * * The buffer is placed on the transaction's metadata list and is marked diff --git a/fs/mpage.c b/fs/mpage.c index 5df564366f3..235e4d3873a 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -325,16 +325,12 @@ confused: } /** - * mpage_readpages - populate an address space with some pages, and - * start reads against them. - * + * mpage_readpages - populate an address space with some pages & start reads against them * @mapping: the address_space * @pages: The address of a list_head which contains the target pages. These * pages have their ->index populated and are otherwise uninitialised. - * * The page at @pages->prev has the lowest file offset, and reads should be * issued in @pages->prev to @pages->next order. - * * @nr_pages: The number of pages at *@pages * @get_block: The filesystem's block mapper function. * @@ -360,6 +356,7 @@ confused: * So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be * submitted in the following order: * 12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 + * * because the indirect block has to be read to get the mappings of blocks * 13,14,15,16. Obviously, this impacts performance. * @@ -656,9 +653,7 @@ out: } /** - * mpage_writepages - walk the list of dirty pages of the given - * address space and writepage() all of them. - * + * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them * @mapping: address space structure to write * @wbc: subtract the number of written pages from *@wbc->nr_to_write * @get_block: the filesystem's block mapper function. diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 21dfc9da235..8831d951879 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -171,7 +171,7 @@ xfs_parseargs( char *this_char, *value, *eov; int dsunit, dswidth, vol_dsunit, vol_dswidth; int iosize; - int ikeep = 0; + int dmapi_implies_ikeep = 1; args->flags |= XFSMNT_BARRIER; args->flags2 |= XFSMNT2_COMPAT_IOSIZE; @@ -302,10 +302,10 @@ xfs_parseargs( } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { args->flags &= ~XFSMNT_BARRIER; } else if (!strcmp(this_char, MNTOPT_IKEEP)) { - ikeep = 1; - args->flags &= ~XFSMNT_IDELETE; + args->flags |= XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { - args->flags |= XFSMNT_IDELETE; + dmapi_implies_ikeep = 0; + args->flags &= ~XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { @@ -410,8 +410,8 @@ xfs_parseargs( * Note that if "ikeep" or "noikeep" mount options are * supplied, then they are honored. */ - if (!(args->flags & XFSMNT_DMAPI) && !ikeep) - args->flags |= XFSMNT_IDELETE; + if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep) + args->flags |= XFSMNT_IKEEP; if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { if (dsunit) { @@ -446,6 +446,7 @@ xfs_showargs( { static struct proc_xfs_info xfs_info_set[] = { /* the few simple ones we can get from the mount struct */ + { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, @@ -461,7 +462,6 @@ xfs_showargs( }; static struct proc_xfs_info xfs_info_unset[] = { /* the few simple ones we can get from the mount struct */ - { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP }, { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h index d16c1b97107..d5d1e60ee22 100644 --- a/fs/xfs/xfs_clnt.h +++ b/fs/xfs/xfs_clnt.h @@ -86,7 +86,7 @@ struct xfs_mount_args { #define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */ #define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */ #define XFSMNT_BARRIER 0x04000000 /* use write barriers */ -#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ +#define XFSMNT_IKEEP 0x08000000 /* inode cluster delete */ #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width * allocation */ #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index c5836b951d0..db9d5fa600a 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -1053,7 +1053,7 @@ xfs_difree( /* * When an inode cluster is free, it becomes eligible for removal */ - if ((mp->m_flags & XFS_MOUNT_IDELETE) && + if (!(mp->m_flags & XFS_MOUNT_IKEEP) && (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { *delete = 1; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index f7c620ec6e6..1d8a4728d84 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -366,7 +366,7 @@ typedef struct xfs_mount { #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ #define XFS_MOUNT_BARRIER (1ULL << 17) -#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ +#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width * allocation */ #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 413587f0215..7321304a69c 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -281,8 +281,8 @@ xfs_start_flags( mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; } - if (ap->flags & XFSMNT_IDELETE) - mp->m_flags |= XFS_MOUNT_IDELETE; + if (ap->flags & XFSMNT_IKEEP) + mp->m_flags |= XFS_MOUNT_IKEEP; if (ap->flags & XFSMNT_DIRSYNC) mp->m_flags |= XFS_MOUNT_DIRSYNC; if (ap->flags & XFSMNT_ATTR2) diff --git a/include/asm-arm/arch-pxa/entry-macro.S b/include/asm-arm/arch-pxa/entry-macro.S index b7e73085146..c145bb01bc8 100644 --- a/include/asm-arm/arch-pxa/entry-macro.S +++ b/include/asm-arm/arch-pxa/entry-macro.S @@ -35,7 +35,7 @@ 1004: mrc p6, 0, \irqstat, c6, c0, 0 @ ICIP2 mrc p6, 0, \irqnr, c7, c0, 0 @ ICMR2 - ands \irqstat, \irqstat, \irqnr + ands \irqnr, \irqstat, \irqnr beq 1003f rsb \irqstat, \irqnr, #0 and \irqstat, \irqstat, \irqnr diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index ac175b4d10c..2357a73340d 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -520,6 +520,9 @@ #define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ #define GCR __REG(0x4050000C) /* Global Control Register */ +#ifdef CONFIG_PXA3xx +#define GCR_CLKBPB (1 << 31) /* Internal clock enable */ +#endif #define GCR_nDMAEN (1 << 24) /* non DMA Enable */ #define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */ #define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */ diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h index 1ee17b6951d..47fe34d692d 100644 --- a/include/asm-arm/kexec.h +++ b/include/asm-arm/kexec.h @@ -8,7 +8,7 @@ /* Maximum address we can reach in physical address mode */ #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) /* Maximum address we can use for the control code buffer */ -#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE +#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) #define KEXEC_CONTROL_CODE_SIZE 4096 diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h index 8431f6eed5c..5db03cf3b90 100644 --- a/include/asm-arm/unaligned.h +++ b/include/asm-arm/unaligned.h @@ -40,16 +40,16 @@ extern int __bug_unaligned_x(const void *ptr); */ #define __get_unaligned_2_le(__p) \ - (__p[0] | __p[1] << 8) + (unsigned int)(__p[0] | __p[1] << 8) #define __get_unaligned_2_be(__p) \ - (__p[0] << 8 | __p[1]) + (unsigned int)(__p[0] << 8 | __p[1]) #define __get_unaligned_4_le(__p) \ - (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) + (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) #define __get_unaligned_4_be(__p) \ - (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) + (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) #define __get_unaligned_8_le(__p) \ ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h index 018f6e2a024..3ae7b548fce 100644 --- a/include/asm-avr32/pgtable.h +++ b/include/asm-avr32/pgtable.h @@ -157,6 +157,7 @@ extern struct page *empty_zero_page; #define _PAGE_S(x) _PAGE_NORMAL(x) #define PAGE_COPY _PAGE_P(PAGE_WRITE | PAGE_READ) +#define PAGE_SHARED _PAGE_S(PAGE_WRITE | PAGE_READ) #ifndef __ASSEMBLY__ /* diff --git a/include/asm-blackfin/gptimers.h b/include/asm-blackfin/gptimers.h index 8265ea473d5..4f318f1fd2d 100644 --- a/include/asm-blackfin/gptimers.h +++ b/include/asm-blackfin/gptimers.h @@ -1,12 +1,11 @@ /* - * include/asm/bf5xx_timers.h - * - * This file contains the major Data structures and constants - * used for General Purpose Timer Implementation in BF5xx + * gptimers.h - Blackfin General Purpose Timer structs/defines/prototypes * + * Copyright (c) 2005-2008 Analog Devices Inc. * Copyright (C) 2005 John DeHority * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) * + * Licensed under the GPL-2. */ #ifndef _BLACKFIN_TIMERS_H_ diff --git a/include/asm-blackfin/irq.h b/include/asm-blackfin/irq.h index 65480dab244..86b67834354 100644 --- a/include/asm-blackfin/irq.h +++ b/include/asm-blackfin/irq.h @@ -67,4 +67,6 @@ static __inline__ int irq_canonicalize(int irq) #define NO_IRQ ((unsigned int)(-1)) #endif +#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) + #endif /* _BFIN_IRQ_H_ */ diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h index 15dbc21eed8..c0694ecd2ec 100644 --- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v) @@ -58,6 +57,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -67,15 +67,31 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index 7871d4313f4..b6f513bee56 100644 --- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -46,6 +45,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -56,14 +56,34 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else - struct work_struct cts_workqueue; +# if ANOMALY_05000230 + unsigned int anomaly_threshold; +# endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h index 86e45c37983..8fc672d3105 100644 --- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -58,6 +57,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -67,15 +67,31 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index 3770aa38ee9..7e6339f62a5 100644 --- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h @@ -24,6 +24,8 @@ #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) #define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) +#define UART_GET_MSR(uart) bfin_read16(((uart)->port.membase + OFFSET_MSR)) +#define UART_GET_MCR(uart) bfin_read16(((uart)->port.membase + OFFSET_MCR)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) #define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) @@ -32,7 +34,9 @@ #define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) #define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v) #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) +#define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) +#define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v) #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS @@ -68,10 +72,9 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index 7871d4313f4..b6f513bee56 100644 --- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -46,6 +45,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -56,14 +56,34 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else - struct work_struct cts_workqueue; +# if ANOMALY_05000230 + unsigned int anomaly_threshold; +# endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf561/blackfin.h b/include/asm-blackfin/mach-bf561/blackfin.h index 362617f9384..3a16df2c86d 100644 --- a/include/asm-blackfin/mach-bf561/blackfin.h +++ b/include/asm-blackfin/mach-bf561/blackfin.h @@ -49,7 +49,8 @@ #define bfin_read_FIO_INEN() bfin_read_FIO0_INEN() #define bfin_write_FIO_INEN(val) bfin_write_FIO0_INEN(val) - +#define SIC_IWR0 SICA_IWR0 +#define SIC_IWR1 SICA_IWR1 #define SIC_IAR0 SICA_IAR0 #define bfin_write_SIC_IMASK0 bfin_write_SICA_IMASK0 #define bfin_write_SIC_IMASK1 bfin_write_SICA_IMASK1 diff --git a/include/asm-blackfin/mach-bf561/cdefBF561.h b/include/asm-blackfin/mach-bf561/cdefBF561.h index d667816486c..1bc8d2f89cc 100644 --- a/include/asm-blackfin/mach-bf561/cdefBF561.h +++ b/include/asm-blackfin/mach-bf561/cdefBF561.h @@ -559,6 +559,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val) #define bfin_write_PPI0_CONTROL(val) bfin_write16(PPI0_CONTROL,val) #define bfin_read_PPI0_STATUS() bfin_read16(PPI0_STATUS) #define bfin_write_PPI0_STATUS(val) bfin_write16(PPI0_STATUS,val) +#define bfin_clear_PPI0_STATUS() bfin_read_PPI0_STATUS() #define bfin_read_PPI0_COUNT() bfin_read16(PPI0_COUNT) #define bfin_write_PPI0_COUNT(val) bfin_write16(PPI0_COUNT,val) #define bfin_read_PPI0_DELAY() bfin_read16(PPI0_DELAY) @@ -570,6 +571,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val) #define bfin_write_PPI1_CONTROL(val) bfin_write16(PPI1_CONTROL,val) #define bfin_read_PPI1_STATUS() bfin_read16(PPI1_STATUS) #define bfin_write_PPI1_STATUS(val) bfin_write16(PPI1_STATUS,val) +#define bfin_clear_PPI1_STATUS() bfin_read_PPI1_STATUS() #define bfin_read_PPI1_COUNT() bfin_read16(PPI1_COUNT) #define bfin_write_PPI1_COUNT(val) bfin_write16(PPI1_COUNT,val) #define bfin_read_PPI1_DELAY() bfin_read16(PPI1_DELAY) diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 0d6238987df..edc0cfd7f6e 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -153,6 +153,9 @@ #define CTRL_RUNLATCH 0x1 #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ #define DABR_TRANSLATION (1UL << 2) +#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */ +#define DABRX_USER (1UL << 0) +#define DABRX_KERNEL (1UL << 1) #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define DSISR_NOHPTE 0x40000000 /* no translation found */ diff --git a/include/asm-sh/cpu-sh3/cache.h b/include/asm-sh/cpu-sh3/cache.h index 56bd838b7db..bee2d81c56b 100644 --- a/include/asm-sh/cpu-sh3/cache.h +++ b/include/asm-sh/cpu-sh3/cache.h @@ -35,7 +35,7 @@ defined(CONFIG_CPU_SUBTYPE_SH7710) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) -#define CCR3 0xa40000b4 +#define CCR3_REG 0xa40000b4 #define CCR_CACHE_16KB 0x00010000 #define CCR_CACHE_32KB 0x00020000 #endif diff --git a/include/asm-sh/entry-macros.S b/include/asm-sh/entry-macros.S index 500030eae7a..2dab0b8d945 100644 --- a/include/asm-sh/entry-macros.S +++ b/include/asm-sh/entry-macros.S @@ -12,7 +12,7 @@ not r11, r11 stc sr, r10 and r11, r10 -#ifdef CONFIG_HAS_SR_RB +#ifdef CONFIG_CPU_HAS_SR_RB stc k_g_imask, r11 or r11, r10 #endif @@ -20,7 +20,7 @@ .endm .macro get_current_thread_info, ti, tmp -#ifdef CONFIG_HAS_SR_RB +#ifdef CONFIG_CPU_HAS_SR_RB stc r7_bank, \ti #else mov #((THREAD_SIZE - 1) >> 10) ^ 0xff, \tmp diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 81a8ee4c55f..f224eb3c315 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -89,13 +89,13 @@ */ struct ptrace_bts_config { /* requested or actual size of BTS buffer in bytes */ - u32 size; + __u32 size; /* bitmask of below flags */ - u32 flags; + __u32 flags; /* buffer overflow signal */ - u32 signal; + __u32 signal; /* actual size of bts_struct in bytes */ - u32 bts_size; + __u32 bts_size; }; #endif diff --git a/include/linux/connector.h b/include/linux/connector.h index da6dd957f90..96a89d3d672 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -170,7 +170,5 @@ int cn_cb_equal(struct cb_id *, struct cb_id *); void cn_queue_wrapper(struct work_struct *work); -extern int cn_already_initialized; - #endif /* __KERNEL__ */ #endif /* __CONNECTOR_H */ diff --git a/include/linux/elfcore-compat.h b/include/linux/elfcore-compat.h index 532d13adabc..0a90e1c3a42 100644 --- a/include/linux/elfcore-compat.h +++ b/include/linux/elfcore-compat.h @@ -45,8 +45,8 @@ struct compat_elf_prpsinfo char pr_zomb; char pr_nice; compat_ulong_t pr_flag; - compat_uid_t pr_uid; - compat_gid_t pr_gid; + __compat_uid_t pr_uid; + __compat_gid_t pr_gid; compat_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; char pr_fname[16]; char pr_psargs[ELF_PRARGSZ]; diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 2961ec78804..49829988bfa 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -109,6 +109,14 @@ static inline void account_system_vtime(struct task_struct *tsk) } #endif +#if defined(CONFIG_PREEMPT_RCU) && defined(CONFIG_NO_HZ) +extern void rcu_irq_enter(void); +extern void rcu_irq_exit(void); +#else +# define rcu_irq_enter() do { } while (0) +# define rcu_irq_exit() do { } while (0) +#endif /* CONFIG_PREEMPT_RCU */ + /* * It is safe to do non-atomic ops on ->hardirq_context, * because NMI handlers may not preempt and the ops are @@ -117,6 +125,7 @@ static inline void account_system_vtime(struct task_struct *tsk) */ #define __irq_enter() \ do { \ + rcu_irq_enter(); \ account_system_vtime(current); \ add_preempt_count(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ @@ -135,6 +144,7 @@ extern void irq_enter(void); trace_hardirq_exit(); \ account_system_vtime(current); \ sub_preempt_count(HARDIRQ_OFFSET); \ + rcu_irq_exit(); \ } while (0) /* diff --git a/include/linux/maple.h b/include/linux/maple.h index 3f01e2bae1a..d31e36ebb43 100644 --- a/include/linux/maple.h +++ b/include/linux/maple.h @@ -64,7 +64,6 @@ struct maple_driver { int (*connect) (struct maple_device * dev); void (*disconnect) (struct maple_device * dev); struct device_driver drv; - int registered; }; void maple_getcond_callback(struct maple_device *dev, diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index b74b615492e..f0680c2bee7 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -31,7 +31,7 @@ #define NF_VERDICT_QMASK 0xffff0000 #define NF_VERDICT_QBITS 16 -#define NF_QUEUE_NR(x) (((x << NF_VERDICT_QBITS) & NF_VERDICT_QMASK) | NF_QUEUE) +#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE) /* only for userspace compatibility */ #ifndef __KERNEL__ diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 4d6624260b4..b3dccd68629 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -160,5 +160,8 @@ extern void rcu_restart_cpu(int cpu); extern long rcu_batches_completed(void); extern long rcu_batches_completed_bh(void); +#define rcu_enter_nohz() do { } while (0) +#define rcu_exit_nohz() do { } while (0) + #endif /* __KERNEL__ */ #endif /* __LINUX_RCUCLASSIC_H */ diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 60c2a033b19..01152ed532c 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h @@ -82,5 +82,27 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); struct softirq_action; +#ifdef CONFIG_NO_HZ +DECLARE_PER_CPU(long, dynticks_progress_counter); + +static inline void rcu_enter_nohz(void) +{ + __get_cpu_var(dynticks_progress_counter)++; + WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1); + mb(); +} + +static inline void rcu_exit_nohz(void) +{ + mb(); + __get_cpu_var(dynticks_progress_counter)++; + WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1)); +} + +#else /* CONFIG_NO_HZ */ +#define rcu_enter_nohz() do { } while (0) +#define rcu_exit_nohz() do { } while (0) +#endif /* CONFIG_NO_HZ */ + #endif /* __KERNEL__ */ #endif /* __LINUX_RCUPREEMPT_H */ diff --git a/include/asm-sh/sci.h b/include/linux/serial_sci.h index 52e73660c12..893cc53486b 100644 --- a/include/asm-sh/sci.h +++ b/include/linux/serial_sci.h @@ -1,12 +1,10 @@ -#ifndef __ASM_SH_SCI_H -#define __ASM_SH_SCI_H +#ifndef __LINUX_SERIAL_SCI_H +#define __LINUX_SERIAL_SCI_H #include <linux/serial_core.h> /* - * Generic header for SuperH SCI(F) - * - * Do not place SH-specific parts in here, sh64 and h8300 depend on this too. + * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) */ /* Offsets into the sci_port->irqs array */ @@ -31,4 +29,4 @@ struct plat_sci_port { int early_sci_setup(struct uart_port *port); -#endif /* __ASM_SH_SCI_H */ +#endif /* __LINUX_SERIAL_SCI_H */ diff --git a/include/linux/usb.h b/include/linux/usb.h index 2372e2e6b52..5bd3ae8aaaf 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -781,8 +781,7 @@ static inline int usb_endpoint_is_isoc_out( .idVendor = (vend), \ .idProduct = (prod) /** - * USB_DEVICE_VER - macro used to describe a specific usb device with a - * version range + * USB_DEVICE_VER - describe a specific usb device with a version range * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @lo: the bcdDevice_lo value @@ -799,8 +798,7 @@ static inline int usb_endpoint_is_isoc_out( .bcdDevice_hi = (hi) /** - * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb - * device with a specific interface protocol + * USB_DEVICE_INTERFACE_PROTOCOL - describe a usb device with a specific interface protocol * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @pr: bInterfaceProtocol value @@ -846,8 +844,7 @@ static inline int usb_endpoint_is_isoc_out( .bInterfaceProtocol = (pr) /** - * USB_DEVICE_AND_INTERFACE_INFO - macro used to describe a specific usb device - * with a class of usb interfaces + * USB_DEVICE_AND_INTERFACE_INFO - describe a specific usb device with a class of usb interfaces * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @cl: bInterfaceClass value diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 75370ec0923..9f1b4b46151 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -246,8 +246,7 @@ static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) static inline void __dec_zone_page_state(struct page *page, enum zone_stat_item item) { - atomic_long_dec(&page_zone(page)->vm_stat[item]); - atomic_long_dec(&vm_stat[item]); + __dec_zone_state(page_zone(page), item); } /* diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index 9462d6ae2f3..9619b9d35c9 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -411,6 +411,7 @@ struct sctp_event_subscribe { __u8 sctp_shutdown_event; __u8 sctp_partial_delivery_event; __u8 sctp_adaptation_layer_event; + __u8 sctp_authentication_event; }; /* @@ -587,7 +588,7 @@ struct sctp_authchunk { * endpoint requires the peer to use. */ struct sctp_hmacalgo { - __u16 shmac_num_idents; + __u32 shmac_num_idents; __u16 shmac_idents[]; }; @@ -600,7 +601,7 @@ struct sctp_hmacalgo { struct sctp_authkey { sctp_assoc_t sca_assoc_id; __u16 sca_keynumber; - __u16 sca_keylen; + __u16 sca_keylength; __u8 sca_key[]; }; @@ -693,8 +694,9 @@ struct sctp_status { * the peer requires to be received authenticated only. */ struct sctp_authchunks { - sctp_assoc_t gauth_assoc_id; - uint8_t gauth_chunks[]; + sctp_assoc_t gauth_assoc_id; + __u32 gauth_number_of_chunks; + uint8_t gauth_chunks[]; }; /* diff --git a/kernel/audit.c b/kernel/audit.c index 2eeea9a1424..10c4930c2bb 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -170,7 +170,9 @@ void audit_panic(const char *message) printk(KERN_ERR "audit: %s\n", message); break; case AUDIT_FAIL_PANIC: - panic("audit: %s\n", message); + /* test audit_pid since printk is always losey, why bother? */ + if (audit_pid) + panic("audit: %s\n", message); break; } } @@ -352,6 +354,7 @@ static int kauditd_thread(void *dummy) if (err < 0) { BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); + audit_log_lost("auditd dissapeared\n"); audit_pid = 0; } } else { @@ -1350,17 +1353,19 @@ void audit_log_end(struct audit_buffer *ab) if (!audit_rate_check()) { audit_log_lost("rate limit exceeded"); } else { + struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); if (audit_pid) { - struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); skb_queue_tail(&audit_skb_queue, ab->skb); ab->skb = NULL; wake_up_interruptible(&kauditd_wait); - } else if (printk_ratelimit()) { - struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); - printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, ab->skb->data + NLMSG_SPACE(0)); - } else { - audit_log_lost("printk limit exceeded\n"); + } else if (nlh->nlmsg_type != AUDIT_EOE) { + if (printk_ratelimit()) { + printk(KERN_NOTICE "type=%d %s\n", + nlh->nlmsg_type, + ab->skb->data + NLMSG_SPACE(0)); + } else + audit_log_lost("printk limit exceeded\n"); } } audit_buffer_free(ab); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 2087d6de67e..782262e4107 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1070,7 +1070,7 @@ static int audit_log_single_execve_arg(struct audit_context *context, * so we can be sure nothing was lost. */ if ((i == 0) && (too_long)) - audit_log_format(*ab, "a%d_len=%ld ", arg_num, + audit_log_format(*ab, "a%d_len=%zu ", arg_num, has_cntl ? 2*len : len); /* diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 987cfb7ade8..e9517014b57 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -23,6 +23,10 @@ * to Suparna Bhattacharya for pushing me completely away * from atomic instructions on the read side. * + * - Added handling of Dynamic Ticks + * Copyright 2007 - Paul E. Mckenney <paulmck@us.ibm.com> + * - Steven Rostedt <srostedt@redhat.com> + * * Papers: http://www.rdrop.com/users/paulmck/RCU * * Design Document: http://lwn.net/Articles/253651/ @@ -409,6 +413,212 @@ static void __rcu_advance_callbacks(struct rcu_data *rdp) } } +#ifdef CONFIG_NO_HZ + +DEFINE_PER_CPU(long, dynticks_progress_counter) = 1; +static DEFINE_PER_CPU(long, rcu_dyntick_snapshot); +static DEFINE_PER_CPU(int, rcu_update_flag); + +/** + * rcu_irq_enter - Called from Hard irq handlers and NMI/SMI. + * + * If the CPU was idle with dynamic ticks active, this updates the + * dynticks_progress_counter to let the RCU handling know that the + * CPU is active. + */ +void rcu_irq_enter(void) +{ + int cpu = smp_processor_id(); + + if (per_cpu(rcu_update_flag, cpu)) + per_cpu(rcu_update_flag, cpu)++; + + /* + * Only update if we are coming from a stopped ticks mode + * (dynticks_progress_counter is even). + */ + if (!in_interrupt() && + (per_cpu(dynticks_progress_counter, cpu) & 0x1) == 0) { + /* + * The following might seem like we could have a race + * with NMI/SMIs. But this really isn't a problem. + * Here we do a read/modify/write, and the race happens + * when an NMI/SMI comes in after the read and before + * the write. But NMI/SMIs will increment this counter + * twice before returning, so the zero bit will not + * be corrupted by the NMI/SMI which is the most important + * part. + * + * The only thing is that we would bring back the counter + * to a postion that it was in during the NMI/SMI. + * But the zero bit would be set, so the rest of the + * counter would again be ignored. + * + * On return from the IRQ, the counter may have the zero + * bit be 0 and the counter the same as the return from + * the NMI/SMI. If the state machine was so unlucky to + * see that, it still doesn't matter, since all + * RCU read-side critical sections on this CPU would + * have already completed. + */ + per_cpu(dynticks_progress_counter, cpu)++; + /* + * The following memory barrier ensures that any + * rcu_read_lock() primitives in the irq handler + * are seen by other CPUs to follow the above + * increment to dynticks_progress_counter. This is + * required in order for other CPUs to correctly + * determine when it is safe to advance the RCU + * grace-period state machine. + */ + smp_mb(); /* see above block comment. */ + /* + * Since we can't determine the dynamic tick mode from + * the dynticks_progress_counter after this routine, + * we use a second flag to acknowledge that we came + * from an idle state with ticks stopped. + */ + per_cpu(rcu_update_flag, cpu)++; + /* + * If we take an NMI/SMI now, they will also increment + * the rcu_update_flag, and will not update the + * dynticks_progress_counter on exit. That is for + * this IRQ to do. + */ + } +} + +/** + * rcu_irq_exit - Called from exiting Hard irq context. + * + * If the CPU was idle with dynamic ticks active, update the + * dynticks_progress_counter to put let the RCU handling be + * aware that the CPU is going back to idle with no ticks. + */ +void rcu_irq_exit(void) +{ + int cpu = smp_processor_id(); + + /* + * rcu_update_flag is set if we interrupted the CPU + * when it was idle with ticks stopped. + * Once this occurs, we keep track of interrupt nesting + * because a NMI/SMI could also come in, and we still + * only want the IRQ that started the increment of the + * dynticks_progress_counter to be the one that modifies + * it on exit. + */ + if (per_cpu(rcu_update_flag, cpu)) { + if (--per_cpu(rcu_update_flag, cpu)) + return; + + /* This must match the interrupt nesting */ + WARN_ON(in_interrupt()); + + /* + * If an NMI/SMI happens now we are still + * protected by the dynticks_progress_counter being odd. + */ + + /* + * The following memory barrier ensures that any + * rcu_read_unlock() primitives in the irq handler + * are seen by other CPUs to preceed the following + * increment to dynticks_progress_counter. This + * is required in order for other CPUs to determine + * when it is safe to advance the RCU grace-period + * state machine. + */ + smp_mb(); /* see above block comment. */ + per_cpu(dynticks_progress_counter, cpu)++; + WARN_ON(per_cpu(dynticks_progress_counter, cpu) & 0x1); + } +} + +static void dyntick_save_progress_counter(int cpu) +{ + per_cpu(rcu_dyntick_snapshot, cpu) = + per_cpu(dynticks_progress_counter, cpu); +} + +static inline int +rcu_try_flip_waitack_needed(int cpu) +{ + long curr; + long snap; + + curr = per_cpu(dynticks_progress_counter, cpu); + snap = per_cpu(rcu_dyntick_snapshot, cpu); + smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ + + /* + * If the CPU remained in dynticks mode for the entire time + * and didn't take any interrupts, NMIs, SMIs, or whatever, + * then it cannot be in the middle of an rcu_read_lock(), so + * the next rcu_read_lock() it executes must use the new value + * of the counter. So we can safely pretend that this CPU + * already acknowledged the counter. + */ + + if ((curr == snap) && ((curr & 0x1) == 0)) + return 0; + + /* + * If the CPU passed through or entered a dynticks idle phase with + * no active irq handlers, then, as above, we can safely pretend + * that this CPU already acknowledged the counter. + */ + + if ((curr - snap) > 2 || (snap & 0x1) == 0) + return 0; + + /* We need this CPU to explicitly acknowledge the counter flip. */ + + return 1; +} + +static inline int +rcu_try_flip_waitmb_needed(int cpu) +{ + long curr; + long snap; + + curr = per_cpu(dynticks_progress_counter, cpu); + snap = per_cpu(rcu_dyntick_snapshot, cpu); + smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ + + /* + * If the CPU remained in dynticks mode for the entire time + * and didn't take any interrupts, NMIs, SMIs, or whatever, + * then it cannot have executed an RCU read-side critical section + * during that time, so there is no need for it to execute a + * memory barrier. + */ + + if ((curr == snap) && ((curr & 0x1) == 0)) + return 0; + + /* + * If the CPU either entered or exited an outermost interrupt, + * SMI, NMI, or whatever handler, then we know that it executed + * a memory barrier when doing so. So we don't need another one. + */ + if (curr != snap) + return 0; + + /* We need the CPU to execute a memory barrier. */ + + return 1; +} + +#else /* !CONFIG_NO_HZ */ + +# define dyntick_save_progress_counter(cpu) do { } while (0) +# define rcu_try_flip_waitack_needed(cpu) (1) +# define rcu_try_flip_waitmb_needed(cpu) (1) + +#endif /* CONFIG_NO_HZ */ + /* * Get here when RCU is idle. Decide whether we need to * move out of idle state, and return non-zero if so. @@ -447,8 +657,10 @@ rcu_try_flip_idle(void) /* Now ask each CPU for acknowledgement of the flip. */ - for_each_cpu_mask(cpu, rcu_cpu_online_map) + for_each_cpu_mask(cpu, rcu_cpu_online_map) { per_cpu(rcu_flip_flag, cpu) = rcu_flipped; + dyntick_save_progress_counter(cpu); + } return 1; } @@ -464,7 +676,8 @@ rcu_try_flip_waitack(void) RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); for_each_cpu_mask(cpu, rcu_cpu_online_map) - if (per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { + if (rcu_try_flip_waitack_needed(cpu) && + per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); return 0; } @@ -509,8 +722,10 @@ rcu_try_flip_waitzero(void) smp_mb(); /* ^^^^^^^^^^^^ */ /* Call for a memory barrier from each CPU. */ - for_each_cpu_mask(cpu, rcu_cpu_online_map) + for_each_cpu_mask(cpu, rcu_cpu_online_map) { per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; + dyntick_save_progress_counter(cpu); + } RCU_TRACE_ME(rcupreempt_trace_try_flip_z2); return 1; @@ -528,7 +743,8 @@ rcu_try_flip_waitmb(void) RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); for_each_cpu_mask(cpu, rcu_cpu_online_map) - if (per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { + if (rcu_try_flip_waitmb_needed(cpu) && + per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); return 0; } @@ -702,8 +918,9 @@ void rcu_offline_cpu(int cpu) * fix. */ + local_irq_save(flags); rdp = RCU_DATA_ME(); - spin_lock_irqsave(&rdp->lock, flags); + spin_lock(&rdp->lock); *rdp->nexttail = list; if (list) rdp->nexttail = tail; @@ -735,9 +952,11 @@ static void rcu_process_callbacks(struct softirq_action *unused) { unsigned long flags; struct rcu_head *next, *list; - struct rcu_data *rdp = RCU_DATA_ME(); + struct rcu_data *rdp; - spin_lock_irqsave(&rdp->lock, flags); + local_irq_save(flags); + rdp = RCU_DATA_ME(); + spin_lock(&rdp->lock); list = rdp->donelist; if (list == NULL) { spin_unlock_irqrestore(&rdp->lock, flags); diff --git a/kernel/softirq.c b/kernel/softirq.c index 5b3aea5f471..31e9f2a4792 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -313,6 +313,7 @@ void irq_exit(void) /* Make sure that timer wheel updates are propagated */ if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched()) tick_nohz_stop_sched_tick(); + rcu_irq_exit(); #endif preempt_enable_no_resched(); } diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 7c2da88db4e..01b6522fd92 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -216,26 +216,27 @@ static int watchdog(void *__bind_cpu) /* initialize timestamp */ touch_softlockup_watchdog(); + set_current_state(TASK_INTERRUPTIBLE); /* * Run briefly once per second to reset the softlockup timestamp. * If this gets delayed for more than 60 seconds then the * debug-printout triggers in softlockup_tick(). */ while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); touch_softlockup_watchdog(); schedule(); if (kthread_should_stop()) break; - if (this_cpu != check_cpu) - continue; - - if (sysctl_hung_task_timeout_secs) - check_hung_uninterruptible_tasks(this_cpu); + if (this_cpu == check_cpu) { + if (sysctl_hung_task_timeout_secs) + check_hung_uninterruptible_tasks(this_cpu); + } + set_current_state(TASK_INTERRUPTIBLE); } + __set_current_state(TASK_RUNNING); return 0; } diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index fa9bb73dbdb..2968298f8f3 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -282,6 +282,7 @@ void tick_nohz_stop_sched_tick(void) ts->idle_tick = ts->sched_timer.expires; ts->tick_stopped = 1; ts->idle_jiffies = last_jiffies; + rcu_enter_nohz(); } /* @@ -375,6 +376,8 @@ void tick_nohz_restart_sched_tick(void) return; } + rcu_exit_nohz(); + /* Update jiffies first */ select_nohz_load_balancer(0); now = ktime_get(); diff --git a/mm/truncate.c b/mm/truncate.c index c35c49e54fb..7d20ce41ecf 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -134,8 +134,7 @@ invalidate_complete_page(struct address_space *mapping, struct page *page) } /** - * truncate_inode_pages - truncate range of pages specified by start and - * end byte offsets + * truncate_inode_pages - truncate range of pages specified by start & end byte offsets * @mapping: mapping to truncate * @lstart: offset from which to truncate * @lend: offset to which to truncate diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index a0ec4792559..146cfb0e988 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -161,11 +161,10 @@ int __init vlan_proc_init(void) if (!proc_vlan_dir) goto err; - proc_vlan_conf = create_proc_entry(name_conf, S_IFREG|S_IRUSR|S_IWUSR, - proc_vlan_dir); + proc_vlan_conf = proc_create(name_conf, S_IFREG|S_IRUSR|S_IWUSR, + proc_vlan_dir, &vlan_fops); if (!proc_vlan_conf) goto err; - proc_vlan_conf->proc_fops = &vlan_fops; return 0; err: @@ -182,13 +181,11 @@ int vlan_proc_add_dev(struct net_device *vlandev) { struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); - dev_info->dent = create_proc_entry(vlandev->name, - S_IFREG|S_IRUSR|S_IWUSR, - proc_vlan_dir); + dev_info->dent = proc_create(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, + proc_vlan_dir, &vlandev_fops); if (!dev_info->dent) return -ENOBUFS; - dev_info->dent->proc_fops = &vlandev_fops; dev_info->dent->data = vlandev; return 0; } diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index 8e8dcfd532d..162199a2d74 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c @@ -283,25 +283,24 @@ int __init atalk_proc_init(void) goto out; atalk_proc_dir->owner = THIS_MODULE; - p = create_proc_entry("interface", S_IRUGO, atalk_proc_dir); + p = proc_create("interface", S_IRUGO, atalk_proc_dir, + &atalk_seq_interface_fops); if (!p) goto out_interface; - p->proc_fops = &atalk_seq_interface_fops; - p = create_proc_entry("route", S_IRUGO, atalk_proc_dir); + p = proc_create("route", S_IRUGO, atalk_proc_dir, + &atalk_seq_route_fops); if (!p) goto out_route; - p->proc_fops = &atalk_seq_route_fops; - p = create_proc_entry("socket", S_IRUGO, atalk_proc_dir); + p = proc_create("socket", S_IRUGO, atalk_proc_dir, + &atalk_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &atalk_seq_socket_fops; - p = create_proc_entry("arp", S_IRUGO, atalk_proc_dir); + p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops); if (!p) goto out_arp; - p->proc_fops = &atalk_seq_arp_fops; rc = 0; out: diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 574d9a96417..1b228065e74 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -742,9 +742,9 @@ static int __init br2684_init(void) { #ifdef CONFIG_PROC_FS struct proc_dir_entry *p; - if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL) + p = proc_create("br2684", 0, atm_proc_root, &br2684_proc_ops); + if (p == NULL) return -ENOMEM; - p->proc_fops = &br2684_proc_ops; #endif register_atm_ioctl(&br2684_ioctl_ops); return 0; diff --git a/net/atm/clip.c b/net/atm/clip.c index 86b885ec1cb..d30167c0b48 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -962,9 +962,7 @@ static int __init atm_clip_init(void) { struct proc_dir_entry *p; - p = create_proc_entry("arp", S_IRUGO, atm_proc_root); - if (p) - p->proc_fops = &arp_seq_fops; + p = proc_create("arp", S_IRUGO, atm_proc_root, &arp_seq_fops); } #endif diff --git a/net/atm/lec.c b/net/atm/lec.c index 1a8c4c6c0cd..0e450d12f03 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -1249,9 +1249,7 @@ static int __init lane_module_init(void) #ifdef CONFIG_PROC_FS struct proc_dir_entry *p; - p = create_proc_entry("lec", S_IRUGO, atm_proc_root); - if (p) - p->proc_fops = &lec_seq_fops; + p = proc_create("lec", S_IRUGO, atm_proc_root, &lec_seq_fops); #endif register_atm_ioctl(&lane_ioctl_ops); diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index 91f3ffc90db..4990541ef5d 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -276,12 +276,11 @@ int mpc_proc_init(void) { struct proc_dir_entry *p; - p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root); + p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_file_operations); if (!p) { printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME); return -ENOMEM; } - p->proc_fops = &mpc_file_operations; p->owner = THIS_MODULE; return 0; } diff --git a/net/atm/proc.c b/net/atm/proc.c index 49125110bb8..e9693aed7ef 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c @@ -435,11 +435,11 @@ int atm_proc_dev_register(struct atm_dev *dev) goto err_out; sprintf(dev->proc_name,"%s:%d",dev->type, dev->number); - dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root); + dev->proc_entry = proc_create(dev->proc_name, 0, atm_proc_root, + &proc_atm_dev_ops); if (!dev->proc_entry) goto err_free_name; dev->proc_entry->data = dev; - dev->proc_entry->proc_fops = &proc_atm_dev_ops; dev->proc_entry->owner = THIS_MODULE; return 0; err_free_name: @@ -492,10 +492,10 @@ int __init atm_proc_init(void) for (e = atm_proc_ents; e->name; e++) { struct proc_dir_entry *dirent; - dirent = create_proc_entry(e->name, S_IRUGO, atm_proc_root); + dirent = proc_create(e->name, S_IRUGO, + atm_proc_root, e->proc_fops); if (!dirent) goto err_out_remove; - dirent->proc_fops = e->proc_fops; dirent->owner = THIS_MODULE; e->dirent = dirent; } diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index a8811c0a0ce..7c5459c8e8e 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -417,6 +417,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) l2cap_sock_kill(sk); } + del_timer_sync(&conn->info_timer); + hcon->l2cap_data = NULL; kfree(conn); } diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 2328acbd16c..aef01533dfb 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1389,10 +1389,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) panic("cannot create neighbour cache statistics"); #ifdef CONFIG_PROC_FS - tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat); + tbl->pde = proc_create(tbl->id, 0, init_net.proc_net_stat, + &neigh_stat_seq_fops); if (!tbl->pde) panic("cannot create neighbour proc dir entry"); - tbl->pde->proc_fops = &neigh_stat_seq_fops; tbl->pde->data = tbl; #endif diff --git a/net/core/pktgen.c b/net/core/pktgen.c index bfcdfaebca5..20e63b302ba 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3570,14 +3570,14 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) if (err) goto out1; - pkt_dev->entry = create_proc_entry(ifname, 0600, pg_proc_dir); + pkt_dev->entry = proc_create(ifname, 0600, + pg_proc_dir, &pktgen_if_fops); if (!pkt_dev->entry) { printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, ifname); err = -EINVAL; goto out2; } - pkt_dev->entry->proc_fops = &pktgen_if_fops; pkt_dev->entry->data = pkt_dev; #ifdef CONFIG_XFRM pkt_dev->ipsmode = XFRM_MODE_TRANSPORT; @@ -3628,7 +3628,7 @@ static int __init pktgen_create_thread(int cpu) kthread_bind(p, cpu); t->tsk = p; - pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir); + pe = proc_create(t->tsk->comm, 0600, pg_proc_dir, &pktgen_thread_fops); if (!pe) { printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, t->tsk->comm); @@ -3638,7 +3638,6 @@ static int __init pktgen_create_thread(int cpu) return -EINVAL; } - pe->proc_fops = &pktgen_thread_fops; pe->data = t; wake_up_process(p); @@ -3709,7 +3708,7 @@ static int __init pg_init(void) return -ENODEV; pg_proc_dir->owner = THIS_MODULE; - pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir); + pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); if (pe == NULL) { printk(KERN_ERR "pktgen: ERROR: cannot create %s " "procfs entry.\n", PGCTRL); @@ -3717,7 +3716,6 @@ static int __init pg_init(void) return -EINVAL; } - pe->proc_fops = &pktgen_fops; pe->data = NULL; /* Register us to receive netdevice events */ diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index f282b26f63e..87490f7bb0f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -752,6 +752,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) inet_del_ifa(in_dev, ifap, 0); ifa->ifa_broadcast = 0; ifa->ifa_anycast = 0; + ifa->ifa_scope = 0; } ifa->ifa_address = ifa->ifa_local = sin->sin_addr.s_addr; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 906cb1ada4c..e7821ba7a9a 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -266,20 +266,24 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int if (!dev) return NULL; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + dev->init = ipgre_tunnel_init; nt = netdev_priv(dev); nt->parms = *parms; - if (register_netdevice(dev) < 0) { - free_netdev(dev); - goto failed; - } + if (register_netdevice(dev) < 0) + goto failed_free; dev_hold(dev); ipgre_tunnel_link(nt); return nt; -failed: +failed_free: + free_netdev(dev); return NULL; } diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index ae1f45fc23b..58b60b2fb01 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -108,8 +108,11 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) const int cpu = get_cpu(); u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); - int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + int err; + local_bh_disable(); + err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + local_bh_enable(); if (err) goto out; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e77e3b85583..dbaed69de06 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -228,20 +228,24 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c if (dev == NULL) return NULL; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + nt = netdev_priv(dev); dev->init = ipip_tunnel_init; nt->parms = *parms; - if (register_netdevice(dev) < 0) { - free_netdev(dev); - goto failed; - } + if (register_netdevice(dev) < 0) + goto failed_free; dev_hold(dev); ipip_tunnel_link(nt); return nt; -failed: +failed_free: + free_netdev(dev); return NULL; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 525787b52b7..7b5e8e1d94b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -542,12 +542,11 @@ static __init int ip_rt_proc_init(struct net *net) if (!pde) goto err1; - pde = create_proc_entry("rt_cache", S_IRUGO, net->proc_net_stat); + pde = proc_create("rt_cache", S_IRUGO, + net->proc_net_stat, &rt_cpu_seq_fops); if (!pde) goto err2; - pde->proc_fops = &rt_cpu_seq_fops; - #ifdef CONFIG_NET_CLS_ROUTE pde = create_proc_read_entry("rt_acct", 0, net->proc_net, ip_rt_acct_read, NULL); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e40213db9e4..101e0e70ba2 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1557,6 +1557,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, .fc_expires = expires, .fc_dst_len = plen, .fc_flags = RTF_UP | flags, + .fc_nlinfo.nl_net = &init_net, }; ipv6_addr_copy(&cfg.fc_dst, pfx); @@ -1583,6 +1584,7 @@ static void addrconf_add_mroute(struct net_device *dev) .fc_ifindex = dev->ifindex, .fc_dst_len = 8, .fc_flags = RTF_UP, + .fc_nlinfo.nl_net = &init_net, }; ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); @@ -1599,6 +1601,7 @@ static void sit_route_add(struct net_device *dev) .fc_ifindex = dev->ifindex, .fc_dst_len = 96, .fc_flags = RTF_UP | RTF_NONEXTHOP, + .fc_nlinfo.nl_net = &init_net, }; /* prefix length - 96 bits "::d.d.d.d" */ diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 2a124e9a1b2..78f43888092 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -238,17 +238,24 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p) if (dev == NULL) goto failed; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + t = netdev_priv(dev); dev->init = ip6_tnl_dev_init; t->parms = *p; - if ((err = register_netdevice(dev)) < 0) { - free_netdev(dev); - goto failed; - } + if ((err = register_netdevice(dev)) < 0) + goto failed_free; + dev_hold(dev); ip6_tnl_link(t); return t; + +failed_free: + free_netdev(dev); failed: return NULL; } diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index b90039593a7..e3dcfa2f436 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -146,7 +146,9 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); tfm = *per_cpu_ptr(ipcd->tfms, cpu); + local_bh_disable(); err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + local_bh_enable(); if (err || (dlen + sizeof(*ipch)) >= plen) { put_cpu(); goto out_ok; diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 35e502a7249..199ef379e50 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -217,12 +217,12 @@ int snmp6_register_dev(struct inet6_dev *idev) if (!proc_net_devsnmp6) return -ENOENT; - p = create_proc_entry(idev->dev->name, S_IRUGO, proc_net_devsnmp6); + p = proc_create(idev->dev->name, S_IRUGO, + proc_net_devsnmp6, &snmp6_seq_fops); if (!p) return -ENOMEM; p->data = idev; - p->proc_fops = &snmp6_seq_fops; idev->stats.proc_dir_entry = p; return 0; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 6e7b56ef444..e8b241cb60b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1719,6 +1719,8 @@ static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg, cfg->fc_src_len = rtmsg->rtmsg_src_len; cfg->fc_flags = rtmsg->rtmsg_flags; + cfg->fc_nlinfo.nl_net = &init_net; + ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst); ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src); ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway); diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index dde7801abef..1656c003b98 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -171,6 +171,11 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int if (dev == NULL) return NULL; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + nt = netdev_priv(dev); dev->init = ipip6_tunnel_init; nt->parms = *parms; @@ -178,16 +183,16 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int if (parms->i_flags & SIT_ISATAP) dev->priv_flags |= IFF_ISATAP; - if (register_netdevice(dev) < 0) { - free_netdev(dev); - goto failed; - } + if (register_netdevice(dev) < 0) + goto failed_free; dev_hold(dev); ipip6_tunnel_link(nt); return nt; +failed_free: + free_netdev(dev); failed: return NULL; } diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 408691b777c..d6d3e68086f 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -102,9 +102,6 @@ static int ipv6_sysctl_net_init(struct net *net) net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, ipv6_table); if (!net->ipv6.sysctl.table) - return -ENOMEM; - - if (!net->ipv6.sysctl.table) goto out_ipv6_icmp_table; err = 0; diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index d483a00dc42..5ed97ad0e2e 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c @@ -358,22 +358,19 @@ int __init ipx_proc_init(void) if (!ipx_proc_dir) goto out; - p = create_proc_entry("interface", S_IRUGO, ipx_proc_dir); + p = proc_create("interface", S_IRUGO, + ipx_proc_dir, &ipx_seq_interface_fops); if (!p) goto out_interface; - p->proc_fops = &ipx_seq_interface_fops; - p = create_proc_entry("route", S_IRUGO, ipx_proc_dir); + p = proc_create("route", S_IRUGO, ipx_proc_dir, &ipx_seq_route_fops); if (!p) goto out_route; - p->proc_fops = &ipx_seq_route_fops; - p = create_proc_entry("socket", S_IRUGO, ipx_proc_dir); + p = proc_create("socket", S_IRUGO, ipx_proc_dir, &ipx_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &ipx_seq_socket_fops; - rc = 0; out: return rc; diff --git a/net/key/af_key.c b/net/key/af_key.c index 1c853927810..8b5f486ac80 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -3807,17 +3807,16 @@ static int pfkey_init_proc(void) { struct proc_dir_entry *e; - e = create_proc_entry("pfkey", 0, init_net.proc_net); + e = proc_net_fops_create(&init_net, "pfkey", 0, &pfkey_proc_ops); if (e == NULL) return -ENOMEM; - e->proc_fops = &pfkey_proc_ops; return 0; } static void pfkey_exit_proc(void) { - remove_proc_entry("net/pfkey", NULL); + proc_net_remove(&init_net, "pfkey"); } #else static inline int pfkey_init_proc(void) diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index cb34bc0518e..48212c0a961 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c @@ -239,18 +239,14 @@ int __init llc_proc_init(void) goto out; llc_proc_dir->owner = THIS_MODULE; - p = create_proc_entry("socket", S_IRUGO, llc_proc_dir); + p = proc_create("socket", S_IRUGO, llc_proc_dir, &llc_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &llc_seq_socket_fops; - - p = create_proc_entry("core", S_IRUGO, llc_proc_dir); + p = proc_create("core", S_IRUGO, llc_proc_dir, &llc_seq_core_fops); if (!p) goto out_core; - p->proc_fops = &llc_seq_core_fops; - rc = 0; out: return rc; diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 2019b4f0528..9aeed532022 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -1116,9 +1116,10 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, /* prepare reordering buffer */ tid_agg_rx->reorder_buf = kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); - if ((!tid_agg_rx->reorder_buf) && net_ratelimit()) { - printk(KERN_ERR "can not allocate reordering buffer " - "to tid %d\n", tid); + if (!tid_agg_rx->reorder_buf) { + if (net_ratelimit()) + printk(KERN_ERR "can not allocate reordering buffer " + "to tid %d\n", tid); goto end; } memset(tid_agg_rx->reorder_buf, 0, diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 327e847d270..b77eb56a87e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -256,13 +256,19 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple) struct hlist_node *n; unsigned int hash = hash_conntrack(tuple); + /* Disable BHs the entire time since we normally need to disable them + * at least once for the stats anyway. + */ + local_bh_disable(); hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { if (nf_ct_tuple_equal(tuple, &h->tuple)) { NF_CT_STAT_INC(found); + local_bh_enable(); return h; } NF_CT_STAT_INC(searched); } + local_bh_enable(); return NULL; } @@ -400,17 +406,20 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, struct hlist_node *n; unsigned int hash = hash_conntrack(tuple); - rcu_read_lock(); + /* Disable BHs the entire time since we need to disable them at + * least once for the stats anyway. + */ + rcu_read_lock_bh(); hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && nf_ct_tuple_equal(tuple, &h->tuple)) { NF_CT_STAT_INC(found); - rcu_read_unlock(); + rcu_read_unlock_bh(); return 1; } NF_CT_STAT_INC(searched); } - rcu_read_unlock(); + rcu_read_unlock_bh(); return 0; } diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 85330856a29..0c50b289405 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c @@ -122,7 +122,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr, const union nf_inet_addr *umask, unsigned int l3proto) { if (l3proto == AF_INET) - return (kaddr->ip & umask->ip) == uaddr->ip; + return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0; else if (l3proto == AF_INET6) return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6, &uaddr->in6) == 0; @@ -231,7 +231,7 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in, if (test_bit(IPS_DST_NAT_BIT, &ct->status)) statebit |= XT_CONNTRACK_STATE_DNAT; } - if ((info->state_mask & statebit) ^ + if (!!(info->state_mask & statebit) ^ !(info->invert_flags & XT_CONNTRACK_STATE)) return false; } diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 8bb79f28177..675a5c3e68a 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -838,11 +838,11 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, } /* Create a new key data based on the info passed in */ - key = sctp_auth_create_key(auth_key->sca_keylen, GFP_KERNEL); + key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL); if (!key) goto nomem; - memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylen); + memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength); /* If we are replacing, remove the old keys data from the * key id. If we are adding new key id, add it to the diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 4d7ec961ae1..87f940587d5 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -966,7 +966,7 @@ static struct inet6_protocol sctpv6_protocol = { .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, }; -static struct sctp_af sctp_ipv6_specific = { +static struct sctp_af sctp_af_inet6 = { .sa_family = AF_INET6, .sctp_xmit = sctp_v6_xmit, .setsockopt = ipv6_setsockopt, @@ -998,7 +998,7 @@ static struct sctp_af sctp_ipv6_specific = { #endif }; -static struct sctp_pf sctp_pf_inet6_specific = { +static struct sctp_pf sctp_pf_inet6 = { .event_msgname = sctp_inet6_event_msgname, .skb_msgname = sctp_inet6_skb_msgname, .af_supported = sctp_inet6_af_supported, @@ -1008,7 +1008,7 @@ static struct sctp_pf sctp_pf_inet6_specific = { .supported_addrs = sctp_inet6_supported_addrs, .create_accept_sk = sctp_v6_create_accept_sk, .addr_v4map = sctp_v6_addr_v4map, - .af = &sctp_ipv6_specific, + .af = &sctp_af_inet6, }; /* Initialize IPv6 support and register with socket layer. */ @@ -1017,10 +1017,10 @@ int sctp_v6_init(void) int rc; /* Register the SCTP specific PF_INET6 functions. */ - sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6); + sctp_register_pf(&sctp_pf_inet6, PF_INET6); /* Register the SCTP specific AF_INET6 functions. */ - sctp_register_af(&sctp_ipv6_specific); + sctp_register_af(&sctp_af_inet6); rc = proto_register(&sctpv6_prot, 1); if (rc) @@ -1051,7 +1051,7 @@ void sctp_v6_exit(void) inet6_unregister_protosw(&sctpv6_seqpacket_protosw); inet6_unregister_protosw(&sctpv6_stream_protosw); proto_unregister(&sctpv6_prot); - list_del(&sctp_ipv6_specific.list); + list_del(&sctp_af_inet6.list); } /* Unregister with inet6 layer. */ diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c index 14e294e3762..cfeb07ea1b0 100644 --- a/net/sctp/objcnt.c +++ b/net/sctp/objcnt.c @@ -132,12 +132,11 @@ void sctp_dbg_objcnt_init(void) { struct proc_dir_entry *ent; - ent = create_proc_entry("sctp_dbg_objcnt", 0, proc_net_sctp); + ent = proc_create("sctp_dbg_objcnt", 0, + proc_net_sctp, &sctp_objcnt_ops); if (!ent) printk(KERN_WARNING "sctp_dbg_objcnt: Unable to create /proc entry.\n"); - else - ent->proc_fops = &sctp_objcnt_ops; } /* Cleanup the objcount entry in the proc filesystem. */ diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 69bb5a63fd8..9e214da82d9 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -108,12 +108,10 @@ int __init sctp_snmp_proc_init(void) { struct proc_dir_entry *p; - p = create_proc_entry("snmp", S_IRUGO, proc_net_sctp); + p = proc_create("snmp", S_IRUGO, proc_net_sctp, &sctp_snmp_seq_fops); if (!p) return -ENOMEM; - p->proc_fops = &sctp_snmp_seq_fops; - return 0; } diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 22a16571499..688546dccd8 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -832,7 +832,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, return ip_queue_xmit(skb, ipfragok); } -static struct sctp_af sctp_ipv4_specific; +static struct sctp_af sctp_af_inet; static struct sctp_pf sctp_pf_inet = { .event_msgname = sctp_inet_event_msgname, @@ -844,7 +844,7 @@ static struct sctp_pf sctp_pf_inet = { .supported_addrs = sctp_inet_supported_addrs, .create_accept_sk = sctp_v4_create_accept_sk, .addr_v4map = sctp_v4_addr_v4map, - .af = &sctp_ipv4_specific, + .af = &sctp_af_inet }; /* Notifier for inetaddr addition/deletion events. */ @@ -906,7 +906,7 @@ static struct net_protocol sctp_protocol = { }; /* IPv4 address related functions. */ -static struct sctp_af sctp_ipv4_specific = { +static struct sctp_af sctp_af_inet = { .sa_family = AF_INET, .sctp_xmit = sctp_v4_xmit, .setsockopt = ip_setsockopt, @@ -1192,7 +1192,7 @@ SCTP_STATIC __init int sctp_init(void) sctp_sysctl_register(); INIT_LIST_HEAD(&sctp_address_families); - sctp_register_af(&sctp_ipv4_specific); + sctp_register_af(&sctp_af_inet); status = proto_register(&sctp_prot, 1); if (status) @@ -1249,7 +1249,7 @@ err_v6_init: proto_unregister(&sctp_prot); err_proto_register: sctp_sysctl_unregister(); - list_del(&sctp_ipv4_specific.list); + list_del(&sctp_af_inet.list); free_pages((unsigned long)sctp_port_hashtable, get_order(sctp_port_hashsize * sizeof(struct sctp_bind_hashbucket))); @@ -1299,7 +1299,7 @@ SCTP_STATIC __exit void sctp_exit(void) inet_unregister_protosw(&sctp_seqpacket_protosw); sctp_sysctl_unregister(); - list_del(&sctp_ipv4_specific.list); + list_del(&sctp_af_inet.list); free_pages((unsigned long)sctp_assoc_hashtable, get_order(sctp_assoc_hashsize * diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 44797ad88a0..939892691a2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1964,7 +1964,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, static int sctp_setsockopt_events(struct sock *sk, char __user *optval, int optlen) { - if (optlen != sizeof(struct sctp_event_subscribe)) + if (optlen > sizeof(struct sctp_event_subscribe)) return -EINVAL; if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) return -EFAULT; @@ -5070,6 +5070,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks; char __user *to; if (len <= sizeof(struct sctp_authchunks)) @@ -5086,12 +5087,15 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, ch = asoc->peer.peer_chunks; /* See if the user provided enough room for all the data */ - if (len < ntohs(ch->param_hdr.length)) + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); + len = num_chunks; if (put_user(len, optlen)) return -EFAULT; + if (put_user(num_chunks, &p->gauth_number_of_chunks)) + return -EFAULT; if (copy_to_user(to, ch->chunks, len)) return -EFAULT; @@ -5105,6 +5109,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks; char __user *to; if (len <= sizeof(struct sctp_authchunks)) @@ -5123,12 +5128,15 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, else ch = sctp_sk(sk)->ep->auth_chunk_list; - if (len < ntohs(ch->param_hdr.length)) + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); + len = num_chunks; if (put_user(len, optlen)) return -EFAULT; + if (put_user(num_chunks, &p->gauth_number_of_chunks)) + return -EFAULT; if (copy_to_user(to, ch->chunks, len)) return -EFAULT; diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index e27b11f18b7..b43f1f110f8 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -206,7 +206,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( * This field is the total length of the notification data, including * the notification header. */ - sac->sac_length = sizeof(struct sctp_assoc_change); + sac->sac_length = skb->len; /* Socket Extensions for SCTP * 5.3.1.1 SCTP_ASSOC_CHANGE diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 636c8e04e0b..b5f2786251b 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -316,31 +316,29 @@ static int create_cache_proc_entries(struct cache_detail *cd) cd->proc_ent->owner = cd->owner; cd->channel_ent = cd->content_ent = NULL; - p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); + p = proc_create("flush", S_IFREG|S_IRUSR|S_IWUSR, + cd->proc_ent, &cache_flush_operations); cd->flush_ent = p; if (p == NULL) goto out_nomem; - p->proc_fops = &cache_flush_operations; p->owner = cd->owner; p->data = cd; if (cd->cache_request || cd->cache_parse) { - p = create_proc_entry("channel", S_IFREG|S_IRUSR|S_IWUSR, - cd->proc_ent); + p = proc_create("channel", S_IFREG|S_IRUSR|S_IWUSR, + cd->proc_ent, &cache_file_operations); cd->channel_ent = p; if (p == NULL) goto out_nomem; - p->proc_fops = &cache_file_operations; p->owner = cd->owner; p->data = cd; } if (cd->cache_show) { - p = create_proc_entry("content", S_IFREG|S_IRUSR|S_IWUSR, - cd->proc_ent); + p = proc_create("content", S_IFREG|S_IRUSR|S_IWUSR, + cd->proc_ent, &content_file_operations); cd->content_ent = p; if (p == NULL) goto out_nomem; - p->proc_fops = &content_file_operations; p->owner = cd->owner; p->data = cd; } diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 5a16875f5ac..c6061a4346c 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -229,9 +229,8 @@ do_register(const char *name, void *data, const struct file_operations *fops) rpc_proc_init(); dprintk("RPC: registering /proc/net/rpc/%s\n", name); - ent = create_proc_entry(name, 0, proc_net_rpc); + ent = proc_create(name, 0, proc_net_rpc, fops); if (ent) { - ent->proc_fops = fops; ent->data = data; } return ent; diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 95b373913aa..4bb3404f610 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -142,7 +142,7 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr) max_n_num = tipc_highest_allowed_slave; assert(n_num > 0); assert(n_num <= max_n_num); - assert(c_ptr->nodes[n_num] == 0); + assert(c_ptr->nodes[n_num] == NULL); c_ptr->nodes[n_num] = n_ptr; if (n_num > c_ptr->highest_node) c_ptr->highest_node = n_num; diff --git a/net/tipc/link.c b/net/tipc/link.c index 1b17fecee74..cefa99824c5 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -3251,7 +3251,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, if ((mod(msg_seqno(buf_msg(l_ptr->last_out)) - msg_seqno(buf_msg(l_ptr->first_out))) != (l_ptr->out_queue_size - 1)) - || (l_ptr->last_out->next != 0)) { + || (l_ptr->last_out->next != NULL)) { tipc_printf(buf, "\nSend queue inconsistency\n"); tipc_printf(buf, "first_out= %x ", l_ptr->first_out); tipc_printf(buf, "next_out= %x ", l_ptr->next_out); diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 6704a58c785..c38744c96ed 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -148,7 +148,7 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) reference = (next_plus_upper & ~index_mask) + index; entry->data.reference = reference; entry->object = object; - if (lock != 0) + if (lock != NULL) *lock = &entry->lock; spin_unlock_bh(&entry->lock); } diff --git a/net/tipc/zone.c b/net/tipc/zone.c index 114e173f11a..3506f856344 100644 --- a/net/tipc/zone.c +++ b/net/tipc/zone.c @@ -82,7 +82,7 @@ void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr) assert(c_ptr->addr); assert(c_num <= tipc_max_clusters); - assert(z_ptr->clusters[c_num] == 0); + assert(z_ptr->clusters[c_num] == NULL); z_ptr->clusters[c_num] = c_ptr; } diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index f2e54c3f064..5bebe40bf4e 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -292,14 +292,12 @@ int __init wanrouter_proc_init(void) if (!proc_router) goto fail; - p = create_proc_entry("config", S_IRUGO, proc_router); + p = proc_create("config", S_IRUGO, proc_router, &config_fops); if (!p) goto fail_config; - p->proc_fops = &config_fops; - p = create_proc_entry("status", S_IRUGO, proc_router); + p = proc_create("status", S_IRUGO, proc_router, &status_fops); if (!p) goto fail_stat; - p->proc_fops = &status_fops; return 0; fail_stat: remove_proc_entry("config", proc_router); @@ -329,10 +327,10 @@ int wanrouter_proc_add(struct wan_device* wandev) if (wandev->magic != ROUTER_MAGIC) return -EINVAL; - wandev->dent = create_proc_entry(wandev->name, S_IRUGO, proc_router); + wandev->dent = proc_create(wandev->name, S_IRUGO, + proc_router, &wandev_fops); if (!wandev->dent) return -ENOMEM; - wandev->dent->proc_fops = &wandev_fops; wandev->dent->data = wandev; return 0; } diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c index 3f52b09bed0..1afa44d25be 100644 --- a/net/x25/x25_proc.c +++ b/net/x25/x25_proc.c @@ -312,20 +312,18 @@ int __init x25_proc_init(void) if (!x25_proc_dir) goto out; - p = create_proc_entry("route", S_IRUGO, x25_proc_dir); + p = proc_create("route", S_IRUGO, x25_proc_dir, &x25_seq_route_fops); if (!p) goto out_route; - p->proc_fops = &x25_seq_route_fops; - p = create_proc_entry("socket", S_IRUGO, x25_proc_dir); + p = proc_create("socket", S_IRUGO, x25_proc_dir, &x25_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &x25_seq_socket_fops; - p = create_proc_entry("forward", S_IRUGO, x25_proc_dir); + p = proc_create("forward", S_IRUGO, x25_proc_dir, + &x25_seq_forward_fops); if (!p) goto out_forward; - p->proc_fops = &x25_seq_forward_fops; rc = 0; out: diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 6304c3a89ba..fe03bb82053 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -277,7 +277,7 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) } else { snd_sbdsp_command(chip, 256 - runtime->rate_den); } - if (chip->capture_format != SB_DSP_OUTPUT) { + if (chip->capture_format != SB_DSP_INPUT) { count--; snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); snd_sbdsp_command(chip, count & 0xff); diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 19f08846d6f..c8649282c2c 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1778,9 +1778,9 @@ static hda_nid_t ad1988_capsrc_nids[3] = { static struct hda_input_mux ad1988_6stack_capture_source = { .num_items = 5, .items = { - { "Front Mic", 0x0 }, - { "Line", 0x1 }, - { "Mic", 0x4 }, + { "Front Mic", 0x1 }, /* port-B */ + { "Line", 0x2 }, /* port-C */ + { "Mic", 0x4 }, /* port-E */ { "CD", 0x5 }, { "Mix", 0x9 }, }, @@ -1789,7 +1789,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = { static struct hda_input_mux ad1988_laptop_capture_source = { .num_items = 3, .items = { - { "Mic/Line", 0x0 }, + { "Mic/Line", 0x1 }, /* port-B */ { "CD", 0x5 }, { "Mix", 0x9 }, }, diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f7cd3a804b1..7206b30cbf9 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1230,6 +1230,11 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { static struct hda_verb cxt5047_hp_init_verbs[] = { /* pin sensing on HP jack */ {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, + /* 0x13 is actually shared by both HP and speaker; + * setting the connection to 0 (=0x19) makes the master volume control + * working mysteriouslly... + */ + {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Record selector: Ext Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 777f8c01ca7..33282f9c01c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3973,8 +3973,8 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), { } /* end */ }; @@ -4005,9 +4005,9 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), - HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, + HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, + HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), @@ -7639,6 +7639,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), + SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), {} @@ -8102,7 +8103,7 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ + HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), @@ -8124,7 +8125,7 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ + HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), { } /* end */ @@ -9238,6 +9239,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), + SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), @@ -12993,8 +12995,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -13007,8 +13009,8 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { }; static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { - HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 9ab4a9f383c..5a158b73dca 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -51,7 +51,7 @@ struct phase28_spec { unsigned short master[2]; unsigned short vol[8]; -} phase28; +}; /* WM8770 registers */ #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index ddd5fc8d4fe..301bf929acd 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -36,7 +36,7 @@ struct revo51_spec { struct snd_i2c_device *dev; struct snd_pt2258 *pt2258; -} revo51; +}; static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) { diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 061072c7db0..c52abd0bf22 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1708,6 +1708,12 @@ static struct ac97_pcm ac97_pcm_defs[] __devinitdata = { }; static struct ac97_quirk ac97_quirks[] __devinitdata = { + { + .subvendor = 0x0e11, + .subdevice = 0x000e, + .name = "Compaq Deskpro EN", /* AD1885 */ + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x0e11, .subdevice = 0x008a, @@ -1740,6 +1746,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { }, { .subvendor = 0x1025, + .subdevice = 0x0082, + .name = "Acer Travelmate 2310", + .type = AC97_TUNE_HP_ONLY + }, + { + .subvendor = 0x1025, .subdevice = 0x0083, .name = "Acer Aspire 3003LCi", .type = AC97_TUNE_HP_ONLY diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 3ea1f05228a..666f69a3312 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -150,6 +150,7 @@ static const struct oxygen_model model_hifier = { .shortname = "C-Media CMI8787", .longname = "C-Media Oxygen HD Audio", .chip = "CMI8788", + .owner = THIS_MODULE, .init = hifier_init, .control_filter = hifier_control_filter, .mixer_init = hifier_mixer_init, diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 40e92f5cd69..d163397b85c 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -389,6 +389,7 @@ static const struct oxygen_model model_xonar = { .shortname = "Asus AV200", .longname = "Asus Virtuoso 200", .chip = "AV200", + .owner = THIS_MODULE, .init = xonar_init, .control_filter = xonar_control_filter, .mixer_init = xonar_mixer_init, diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 710e0287ef8..569ecaca0e8 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -681,8 +681,8 @@ static const struct aic3x_rate_divs aic3x_divs[] = { {22579200, 48000, 48000, 0x0, 8, 7075}, {33868800, 48000, 48000, 0x0, 5, 8049}, /* 64k */ - {22579200, 96000, 96000, 0x1, 8, 7075}, - {33868800, 96000, 96000, 0x1, 5, 8049}, + {22579200, 64000, 96000, 0x1, 8, 7075}, + {33868800, 64000, 96000, 0x1, 5, 8049}, /* 88.2k */ {22579200, 88200, 88200, 0x0, 8, 0}, {33868800, 88200, 88200, 0x0, 5, 3333}, diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 590baea3c4c..524f7450804 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -176,7 +176,8 @@ static int wm9712_add_controls(struct snd_soc_codec *codec) * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path. */ -static int mixer_event (struct snd_soc_dapm_widget *w, int event) +static int mixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { u16 l, r, beep, line, phone, mic, pcm, aux; diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 3f34e531beb..1a70a6ac98c 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -215,7 +215,8 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) +static int corgi_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); @@ -225,7 +226,8 @@ static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) return 0; } -static int corgi_mic_event(struct snd_soc_dapm_widget *w, int event) +static int corgi_mic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 5ae59bd309a..4fbf8bba962 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -196,7 +196,8 @@ static int poodle_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int poodle_amp_event(struct snd_soc_dapm_widget *w, int event) +static int poodle_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) locomo_gpio_write(&poodle_locomo_device.dev, diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index d56709e1543..ecca39033fc 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -215,7 +215,8 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int spitz_mic_bias(struct snd_soc_dapm_widget *w, int event) +static int spitz_mic_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (machine_is_borzoi() || machine_is_spitz()) { if (SND_SOC_DAPM_EVENT_ON(event)) diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index e4d40b528ca..7346d7e5d06 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -135,7 +135,8 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol, } /* tosa dapm event handlers */ -static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event) +static int tosa_hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8fa93566570..675672f313b 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -479,6 +479,33 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, return 0; } +/* + * process after E-Mu 0202/0404 high speed playback sync complete + * + * These devices return the number of samples per packet instead of the number + * of samples per microframe. + */ +static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs, + struct snd_pcm_runtime *runtime, + struct urb *urb) +{ + unsigned int f; + unsigned long flags; + + if (urb->iso_frame_desc[0].status == 0 && + urb->iso_frame_desc[0].actual_length == 4) { + f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff; + f >>= subs->datainterval; + if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) { + spin_lock_irqsave(&subs->lock, flags); + subs->freqm = f; + spin_unlock_irqrestore(&subs->lock, flags); + } + } + + return 0; +} + /* determine the number of frames in the next packet */ static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) { @@ -2219,10 +2246,17 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo subs->stream = as; subs->direction = stream; subs->dev = as->chip->dev; - if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) + if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { subs->ops = audio_urb_ops[stream]; - else + } else { subs->ops = audio_urb_ops_high_speed[stream]; + switch (as->chip->usb_id) { + case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ + case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ + subs->ops.retire_sync = retire_playback_sync_urb_hs_emu; + break; + } + } snd_pcm_set_ops(as->pcm, stream, stream == SNDRV_PCM_STREAM_PLAYBACK ? &snd_usb_playback_ops : &snd_usb_capture_ops); |