diff options
266 files changed, 7300 insertions, 7409 deletions
diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt new file mode 100644 index 000000000000..1f62623f8c3f --- /dev/null +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -0,0 +1,28 @@ +* STMicroelectronics 10/100/1000 Ethernet driver (GMAC) + +Required properties: +- compatible: Should be "st,spear600-gmac" +- reg: Address and length of the register set for the device +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupts: Should contain the STMMAC interrupts +- interrupt-names: Should contain the interrupt names "macirq" + "eth_wake_irq" if this interrupt is supported in the "interrupts" + property +- phy-mode: String, operation mode of the PHY interface. + Supported values are: "mii", "rmii", "gmii", "rgmii". + +Optional properties: +- mac-address: 6 bytes, mac address + +Examples: + + gmac0: ethernet@e0800000 { + compatible = "st,spear600-gmac"; + reg = <0xe0800000 0x8000>; + interrupt-parent = <&vic1>; + interrupts = <24 23>; + interrupt-names = "macirq", "eth_wake_irq"; + mac-address = [000000000000]; /* Filled in by U-Boot */ + phy-mode = "gmii"; + }; diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf index 3f44dbdfda70..ceaf6f652b00 100644 --- a/Documentation/hwmon/w83627ehf +++ b/Documentation/hwmon/w83627ehf @@ -50,7 +50,7 @@ W83627DHG, W83627DHG-P, W83627UHG, W83667HG, W83667HG-B, W83667HG-I (NCT6775F), and NCT6776F super I/O chips. We will refer to them collectively as Winbond chips. -The chips implement 2 to 4 temperature sensors (9 for NCT6775F and NCT6776F), +The chips implement 3 to 4 temperature sensors (9 for NCT6775F and NCT6776F), 2 to 5 fan rotation speed sensors, 8 to 10 analog voltage sensors, one VID (except for 627UHG), alarms with beep warnings (control unimplemented), and some automatic fan regulation strategies (plus manual fan control mode). @@ -143,8 +143,13 @@ pwm[1-4]_min_output - minimum fan speed (range 1 - 255), when the temperature pwm[1-4]_stop_time - how many milliseconds [ms] must elapse to switch corresponding fan off. (when the temperature was below defined range). +pwm[1-4]_start_output-minimum fan speed (range 1 - 255) when spinning up +pwm[1-4]_step_output- rate of fan speed change (1 - 255) +pwm[1-4]_stop_output- minimum fan speed (range 1 - 255) when spinning down +pwm[1-4]_max_output - maximum fan speed (range 1 - 255), when the temperature + is above defined range. -Note: last two functions are influenced by other control bits, not yet exported +Note: last six functions are influenced by other control bits, not yet exported by the driver, so a change might not have any effect. Implementation Details diff --git a/Documentation/hwmon/zl6100 b/Documentation/hwmon/zl6100 index 51f76a189fee..a4e8d90f59f6 100644 --- a/Documentation/hwmon/zl6100 +++ b/Documentation/hwmon/zl6100 @@ -88,14 +88,12 @@ Module parameters delay ----- -Some Intersil/Zilker Labs DC-DC controllers require a minimum interval between -I2C bus accesses. According to Intersil, the minimum interval is 2 ms, though -1 ms appears to be sufficient and has not caused any problems in testing. -The problem is known to affect ZL6100, ZL2105, and ZL2008. It is known not to -affect ZL2004 and ZL6105. The driver automatically sets the interval to 1 ms -except for ZL2004 and ZL6105. To enable manual override, the driver provides a -writeable module parameter, 'delay', which can be used to set the interval to -a value between 0 and 65,535 microseconds. +Intersil/Zilker Labs DC-DC controllers require a minimum interval between I2C +bus accesses. According to Intersil, the minimum interval is 2 ms, though 1 ms +appears to be sufficient and has not caused any problems in testing. The problem +is known to affect all currently supported chips. For manual override, the +driver provides a writeable module parameter, 'delay', which can be used to set +the interval to a value between 0 and 65,535 microseconds. Sysfs entries diff --git a/Documentation/networking/mac80211-auth-assoc-deauth.txt b/Documentation/networking/mac80211-auth-assoc-deauth.txt new file mode 100644 index 000000000000..e0a2aa585ca3 --- /dev/null +++ b/Documentation/networking/mac80211-auth-assoc-deauth.txt @@ -0,0 +1,99 @@ +# +# This outlines the Linux authentication/association and +# deauthentication/disassociation flows. +# +# This can be converted into a diagram using the service +# at http://www.websequencediagrams.com/ +# + +participant userspace +participant mac80211 +participant driver + +alt authentication needed (not FT) +userspace->mac80211: authenticate + +alt authenticated/authenticating already +mac80211->driver: sta_state(AP, not-exists) +mac80211->driver: bss_info_changed(clear BSSID) +else associated +note over mac80211,driver +like deauth/disassoc, without sending the +BA session stop & deauth/disassoc frames +end note +end + +mac80211->driver: config(channel, non-HT) +mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap) +mac80211->driver: sta_state(AP, exists) + +alt no probe request data known +mac80211->driver: TX directed probe request +driver->mac80211: RX probe response +end + +mac80211->driver: TX auth frame +driver->mac80211: RX auth frame + +alt WEP shared key auth +mac80211->driver: TX auth frame +driver->mac80211: RX auth frame +end + +mac80211->driver: sta_state(AP, authenticated) +mac80211->userspace: RX auth frame + +end + +userspace->mac80211: associate +alt authenticated or associated +note over mac80211,driver: cleanup like for authenticate +end + +alt not previously authenticated (FT) +mac80211->driver: config(channel, non-HT) +mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap) +mac80211->driver: sta_state(AP, exists) +mac80211->driver: sta_state(AP, authenticated) +end +mac80211->driver: TX assoc +driver->mac80211: RX assoc response +note over mac80211: init rate control +mac80211->driver: sta_state(AP, associated) + +alt not using WPA +mac80211->driver: sta_state(AP, authorized) +end + +mac80211->driver: set up QoS parameters + +alt is HT channel +mac80211->driver: config(channel, HT params) +end + +mac80211->driver: bss_info_changed(QoS, HT, associated with AID) +mac80211->userspace: associated + +note left of userspace: associated now + +alt using WPA +note over userspace +do 4-way-handshake +(data frames) +end note +userspace->mac80211: authorized +mac80211->driver: sta_state(AP, authorized) +end + +userspace->mac80211: deauthenticate/disassociate +mac80211->driver: stop BA sessions +mac80211->driver: TX deauth/disassoc +mac80211->driver: flush frames +mac80211->driver: sta_state(AP,associated) +mac80211->driver: sta_state(AP,authenticated) +mac80211->driver: sta_state(AP,exists) +mac80211->driver: sta_state(AP,not-exists) +mac80211->driver: turn off powersave +mac80211->driver: bss_info_changed(clear BSSID, not associated, no QoS, ...) +mac80211->driver: config(non-HT channel type) +mac80211->userspace: disconnected diff --git a/MAINTAINERS b/MAINTAINERS index 209a386214c2..9be34c42b677 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1514,19 +1514,23 @@ F: drivers/mtd/devices/block2mtd.c BLUETOOTH DRIVERS M: Marcel Holtmann <[email protected]> -M: "Gustavo F. Padovan" <[email protected]> +M: Gustavo Padovan <[email protected]> +M: Johan Hedberg <[email protected]> W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git S: Maintained F: drivers/bluetooth/ BLUETOOTH SUBSYSTEM M: Marcel Holtmann <[email protected]> -M: "Gustavo F. Padovan" <[email protected]> +M: Gustavo Padovan <[email protected]> +M: Johan Hedberg <[email protected]> W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git S: Maintained F: net/bluetooth/ F: include/net/bluetooth/ @@ -1717,6 +1721,14 @@ F: include/linux/can/error.h F: include/linux/can/netlink.h F: include/linux/can/platform/ +CAPABILITIES +M: Serge Hallyn <[email protected]> +S: Supported +F: include/linux/capability.h +F: security/capability.c +F: security/commoncap.c + CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann <[email protected]> @@ -2352,6 +2364,15 @@ S: Supported F: drivers/gpu/drm/exynos F: include/drm/exynos* +EXYNOS MIPI DISPLAY DRIVERS +M: Inki Dae <[email protected]> +M: Donghwa Lee <[email protected]> +M: Kyungmin Park <[email protected]> +S: Maintained +F: drivers/video/exynos/exynos_mipi* +F: include/video/exynos_mipi* + DSCC4 DRIVER M: Francois Romieu <[email protected]> @@ -2846,6 +2867,12 @@ S: Maintained F: drivers/media/video/m5mols/ F: include/media/m5mols.h +FUJITSU TABLET EXTRAS +M: Robert Gerlach <[email protected]> +S: Maintained +F: drivers/platform/x86/fujitsu-tablet.c + FUSE: FILESYSTEM IN USERSPACE M: Miklos Szeredi <[email protected]> @@ -5863,6 +5890,7 @@ F: drivers/mmc/host/sdhci-s3c.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER M: Viresh Kumar <[email protected]> S: Maintained F: drivers/mmc/host/sdhci-spear.c @@ -6205,24 +6233,32 @@ F: drivers/tty/serial/sunzilog.h SPEAR PLATFORM SUPPORT M: Viresh Kumar <[email protected]> +L: [email protected] (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained F: arch/arm/plat-spear/ SPEAR3XX MACHINE SUPPORT M: Viresh Kumar <[email protected]> +L: [email protected] (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained F: arch/arm/mach-spear3xx/ SPEAR6XX MACHINE SUPPORT M: Rajeev Kumar <[email protected]> +L: [email protected] (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained F: arch/arm/mach-spear6xx/ SPEAR CLOCK FRAMEWORK SUPPORT M: Viresh Kumar <[email protected]> +L: [email protected] (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained F: arch/arm/mach-spear*/clock.c @@ -6231,6 +6267,8 @@ F: arch/arm/plat-spear/include/plat/clock.h SPEAR PAD MULTIPLEXING SUPPORT M: Viresh Kumar <[email protected]> +L: [email protected] (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained F: arch/arm/plat-spear/include/plat/padmux.h @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 3 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 068b754bc348..8aea3a2dd889 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -38,6 +38,7 @@ #include <linux/mmc/sh_mobile_sdhi.h> #include <linux/mfd/tmio.h> #include <linux/sh_clk.h> +#include <linux/videodev2.h> #include <video/sh_mobile_lcdc.h> #include <video/sh_mipi_dsi.h> #include <sound/sh_fsi.h> diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index eeb4d9664584..b4718b00e827 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -794,7 +794,7 @@ static struct fsi_ak4642_info fsi2_ak4643_info = { static struct platform_device fsi_ak4643_device = { .name = "fsi-ak4642-audio", .dev = { - .platform_data = &fsi_info, + .platform_data = &fsi2_ak4643_info, }, }; diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c index 4d2201622323..4bd1162ce0df 100644 --- a/arch/arm/mach-shmobile/board-bonito.c +++ b/arch/arm/mach-shmobile/board-bonito.c @@ -27,6 +27,7 @@ #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/smsc911x.h> +#include <linux/videodev2.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -241,7 +242,7 @@ static struct sh_mobile_lcdc_info lcdc0_info = { .clock_source = LCDC_CLK_BUS, .ch[0] = { .chan = LCDC_CHAN_MAINLCD, - .bpp = 16, + .fourcc = V4L2_PIX_FMT_RGB565, .interface_type = RGB24, .clock_divider = 5, .flags = 0, diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index a2813247b455..7b53cda41851 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1352,6 +1352,10 @@ static struct map_desc mackerel_io_desc[] __initdata = { static void __init mackerel_map_io(void) { iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc)); + /* DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't + * enough to allocate the frame buffer memory. + */ + init_consistent_dma_size(12 << 20); /* setup early devices and console here as well */ sh7372_add_early_devices(); diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 3e977ccda827..30b37e5f4a61 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S @@ -717,33 +717,6 @@ ENTRY(sys_ftruncate64_c6x) #endif ENDPROC(sys_ftruncate64_c6x) -#ifdef __ARCH_WANT_SYSCALL_OFF_T -;; On Entry -;; A4 - fd -;; B4 - offset_lo (LE), offset_hi (BE) -;; A6 - offset_lo (BE), offset_hi (LE) -;; B6 - len -;; A8 - advice -ENTRY(sys_fadvise64_c6x) -#ifdef CONFIG_C6X_BIG_KERNEL - MVKL .S1 sys_fadvise64,A0 - MVKH .S1 sys_fadvise64,A0 - BNOP .S2X A0,2 -#else - B .S2 sys_fadvise64 - NOP 2 -#endif -#ifdef CONFIG_CPU_BIG_ENDIAN - MV .L2 B4,B5 - || MV .D2X A6,B4 -#else - MV .D2X A6,B5 -#endif - MV .D1X B6,A6 - MV .D2X A8,B6 -#endif -ENDPROC(sys_fadvise64_c6x) - ;; On Entry ;; A4 - fd ;; B4 - offset_lo (LE), offset_hi (BE) diff --git a/arch/sh/kernel/cpu/sh2a/ex.S b/arch/sh/kernel/cpu/sh2a/ex.S index 3ead9e63965a..4568066700cf 100644 --- a/arch/sh/kernel/cpu/sh2a/ex.S +++ b/arch/sh/kernel/cpu/sh2a/ex.S @@ -66,6 +66,7 @@ vector = 0 .long exception_entry0 + vector * 6 vector = vector + 1 .endr +vector = 0 .rept 256 .long exception_entry1 + vector * 6 vector = vector + 1 diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index 0fbff1422f54..0bd21c82151b 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -79,7 +79,7 @@ struct clk div4_clks[DIV4_NR] = { #define MSTPCR1 0xffc80034 #define MSTPCR2 0xffc10028 -enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112, +enum { MSTP004, MSTP000, MSTP127, MSTP114, MSTP113, MSTP112, MSTP111, MSTP110, MSTP103, MSTP102, MSTP220, MSTP_NR }; @@ -89,6 +89,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0), /* MSTPCR1 */ + [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 27, 0), [MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0), [MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0), [MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0), @@ -131,6 +132,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]), CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]), CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), + CLKDEV_CON_ID("rspi2", &mstp_clks[MSTP127]), }; int __init arch_clk_init(void) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index e5b420cc1265..2b314439d359 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -156,7 +156,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("siof_fck", &mstp_clks[MSTP003]), CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]), CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]), - CLKDEV_CON_ID("ubc_fck", &mstp_clks[MSTP117]), + CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP117]), CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]), CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]), CLKDEV_CON_ID("gdta_fck", &mstp_clks[MSTP100]), diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index ad1fb5d969f3..eddcfb36aafb 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -31,7 +31,7 @@ UTS_MACHINE := sparc #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 -KBUILD_AFLAGS += -m32 +KBUILD_AFLAGS += -m32 -Wa,-Av8 #LDFLAGS_vmlinux = -N -Ttext 0xf0004000 # Since 2.5.40, the first stage is left not btfix-ed. diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index dafdbbae1124..b8d99aca5431 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig @@ -1,337 +1,93 @@ -# -# Automatically generated make config: don't edit -# Linux/tilegx 2.6.39-rc5 Kernel Configuration -# Wed May 4 11:08:04 2011 -# -CONFIG_TILE=y -CONFIG_MMU=y -CONFIG_GENERIC_CSUM=y -CONFIG_SEMAPHORE_SLEEPERS=y -CONFIG_HAVE_ARCH_ALLOC_REMAP=y -CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_DEFAULT_MIGRATION_COST=10000000 -CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y -CONFIG_ARCH_PHYS_ADDR_T_64BIT=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_ARCH_DISCONTIGMEM_ENABLE=y -CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_STRICT_DEVMEM=y -CONFIG_SMP=y -# CONFIG_DEBUG_COPY_FROM_USER is not set -CONFIG_HVC_TILE=y CONFIG_TILEGX=y -CONFIG_64BIT=y -CONFIG_ARCH_DEFCONFIG="arch/tile/configs/tilegx_defconfig" -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y - -# -# General setup -# CONFIG_EXPERIMENTAL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SWAP=y CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y -# CONFIG_FHANDLE is not set +CONFIG_FHANDLE=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_PENDING_IRQ=y - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_PREEMPT_RCU is not set -# CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=64 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_RCU_FAST_NO_HZ is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=19 CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_NS=y -# CONFIG_CGROUP_FREEZER is not set CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y CONFIG_CGROUP_MEM_RES_CTLR=y CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set -CONFIG_MM_OWNER=y -# CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="usr/contents.txt" -CONFIG_INITRAMFS_ROOT_UID=0 -CONFIG_INITRAMFS_ROOT_GID=0 -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_LZO is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y -# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EXPERT=y CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y CONFIG_EMBEDDED=y - -# -# Kernel Performance Events And Counters -# -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLUB_DEBUG=y # CONFIG_COMPAT_BRK is not set -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_USE_GENERIC_SMP_HELPERS=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_INTEGRITY=y -# CONFIG_BLK_DEV_THROTTLING is not set -CONFIG_BLOCK_COMPAT=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SGI_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y CONFIG_CFQ_GROUP_IOSCHED=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_PADATA=y -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_INLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -CONFIG_MUTEX_SPIN_ON_OWNER=y - -# -# Tilera-specific configuration -# CONFIG_NR_CPUS=100 -CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=100 -CONFIG_SCHED_HRTICK=y -# CONFIG_KEXEC is not set -CONFIG_COMPAT=y -CONFIG_SYSVIPC_COMPAT=y -# CONFIG_HIGHMEM is not set -CONFIG_NUMA=y -CONFIG_NODES_SHIFT=2 -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_DISCONTIGMEM_MANUAL=y -CONFIG_DISCONTIGMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_NEED_MULTIPLE_NODES=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_COMPACTION is not set -CONFIG_MIGRATION=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -# CONFIG_CMDLINE_BOOL is not set -CONFIG_VMALLOC_RESERVE=0x1000000 -CONFIG_HARDWALL=y -CONFIG_KERNEL_PL=1 - -# -# Bus options -# -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_NO_IOMEM is not set -# CONFIG_NO_IOPORT is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_DEBUG=y -# CONFIG_PCI_STUB is not set -# CONFIG_PCI_IOV is not set -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_KCORE_ELF=y -CONFIG_BINFMT_ELF=y -CONFIG_COMPAT_BINFMT_ELF=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=y CONFIG_NET=y - -# -# Networking options -# CONFIG_PACKET=y CONFIG_UNIX=y -CONFIG_XFRM=y CONFIG_XFRM_USER=y CONFIG_XFRM_SUB_POLICY=y -CONFIG_XFRM_MIGRATE=y CONFIG_XFRM_STATISTICS=y -CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_FIB_TRIE_STATS is not set CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_CLASSID=y -# CONFIG_IP_PNP is not set CONFIG_NET_IPIP=m -# CONFIG_NET_IPGRE_DEMUX is not set CONFIG_IP_MROUTE=y -# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_LRO=y CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=m -CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m CONFIG_TCP_CONG_HSTCP=m CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_VEGAS=m CONFIG_TCP_CONG_SCALABLE=m CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y @@ -342,108 +98,60 @@ CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m CONFIG_IPV6_MIP6=m -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y -# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set CONFIG_IPV6_PIMSM_V2=y CONFIG_NETLABEL=y -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_EVENTS=y -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set CONFIG_NF_CT_PROTO_DCCP=m -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_BROADCAST=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m -# CONFIG_NF_CONNTRACK_SNMP is not set CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m -# CONFIG_NF_CT_NETLINK is not set CONFIG_NETFILTER_TPROXY=m -CONFIG_NETFILTER_XTABLES=y - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=m -CONFIG_NETFILTER_XT_CONNMARK=m - -# -# Xtables targets -# -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m CONFIG_NETFILTER_XT_TARGET_CT=m CONFIG_NETFILTER_XT_TARGET_DSCP=m -CONFIG_NETFILTER_XT_TARGET_HL=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -CONFIG_NETFILTER_XT_TARGET_RATEEST=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m - -# -# Xtables matches -# -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -# CONFIG_NETFILTER_XT_MATCH_CPU is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_DCCP=m -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_IPVS=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m @@ -460,55 +168,29 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_RATEEST=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_SOCKET=m -CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m -# CONFIG_IP_SET is not set CONFIG_IP_VS=m CONFIG_IP_VS_IPV6=y -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# CONFIG_IP_VS_PROTO_TCP=y CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_AH_ESP=y CONFIG_IP_VS_PROTO_ESP=y CONFIG_IP_VS_PROTO_AH=y CONFIG_IP_VS_PROTO_SCTP=y - -# -# IPVS scheduler -# CONFIG_IP_VS_RR=m CONFIG_IP_VS_WRR=m CONFIG_IP_VS_LC=m CONFIG_IP_VS_WLC=m CONFIG_IP_VS_LBLC=m CONFIG_IP_VS_LBLCR=m -# CONFIG_IP_VS_DH is not set -# CONFIG_IP_VS_SH is not set CONFIG_IP_VS_SED=m CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -# CONFIG_IP_VS_NFCT is not set -# CONFIG_IP_VS_PE_SIP is not set - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=m # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=y @@ -519,9 +201,7 @@ CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -# CONFIG_NF_NAT is not set CONFIG_IP_NF_MANGLE=m -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m @@ -529,11 +209,6 @@ CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m @@ -574,57 +249,20 @@ CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_ULOG=m CONFIG_BRIDGE_EBT_NFLOG=m -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y CONFIG_RDS=m CONFIG_RDS_TCP=m -# CONFIG_RDS_DEBUG is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_L2TP is not set -CONFIG_STP=m -CONFIG_GARP=m CONFIG_BRIDGE=m -CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_NET_DSA=y -CONFIG_NET_DSA_TAG_DSA=y -CONFIG_NET_DSA_TAG_EDSA=y -CONFIG_NET_DSA_TAG_TRAILER=y -CONFIG_NET_DSA_MV88E6XXX=y -CONFIG_NET_DSA_MV88E6060=y -CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y -CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123_61_65=y CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set CONFIG_PHONET=m -# CONFIG_IEEE802154 is not set CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_MULTIQ=m CONFIG_NET_SCH_RED=m -# CONFIG_NET_SCH_SFB is not set CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m @@ -632,14 +270,7 @@ CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m CONFIG_NET_SCH_DRR=m -# CONFIG_NET_SCH_MQPRIO is not set -# CONFIG_NET_SCH_CHOKE is not set CONFIG_NET_SCH_INGRESS=m - -# -# Classification -# -CONFIG_NET_CLS=y CONFIG_NET_CLS_BASIC=m CONFIG_NET_CLS_TCINDEX=m CONFIG_NET_CLS_ROUTE4=m @@ -652,7 +283,6 @@ CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=y CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=m CONFIG_NET_EMATCH_NBYTE=m CONFIG_NET_EMATCH_U32=m @@ -668,307 +298,46 @@ CONFIG_NET_ACT_NAT=m CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m CONFIG_NET_ACT_SKBEDIT=m -# CONFIG_NET_ACT_CSUM is not set CONFIG_NET_CLS_IND=y -CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y -CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y # CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y # CONFIG_FIRMWARE_IN_KERNEL is not set -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m -# CONFIG_BLK_DEV_DRBD is not set -# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_SX8=m CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -CONFIG_ATA_OVER_ETH=y -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_SENSORS_LIS3LV02D is not set -CONFIG_MISC_DEVICES=y -# CONFIG_AD525X_DPOT is not set -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_DS1682 is not set -# CONFIG_BMP085 is not set -# CONFIG_PCH_PHUB is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_CB710_CORE is not set - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_SENSORS_LIS3_I2C is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=m +CONFIG_ATA_OVER_ETH=m CONFIG_RAID_ATTRS=m -CONFIG_SCSI=m -CONFIG_SCSI_DMA=y CONFIG_SCSI_TGT=m -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=m -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_BLK_DEV_SD=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -CONFIG_SCSI_SAS_ATTRS=m -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_SCSI_CXGB4_ISCSI is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_SCSI_BNX2X_FCOE is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_PMCRAID is not set -# CONFIG_SCSI_PM8001 is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_BFA_FC is not set -# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -CONFIG_ATA=m -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_ATA_VERBOSE_ERROR=y -CONFIG_SATA_PMP=y - -# -# Controllers with non-SFF native interface -# -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_AHCI_PLATFORM is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_SATA_ACARD_AHCI is not set -CONFIG_SATA_SIL24=m -CONFIG_ATA_SFF=y - -# -# SFF controllers with custom DMA interface -# -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_SX4 is not set -CONFIG_ATA_BMDMA=y - -# -# SATA SFF controllers with BMDMA -# -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_SVW is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set - -# -# PATA SFF controllers with BMDMA -# -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARASAN_CF is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_ATP867X is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CS5536 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RDC is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SCH is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_TOSHIBA is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - -# -# PIO-only SFF controllers -# -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_RZ1000 is not set - -# -# Generic fallback / legacy drivers -# -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_LEGACY is not set +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_MVSAS=y +# CONFIG_SCSI_MVSAS_DEBUG is not set +CONFIG_SCSI_MVSAS_TASKLET=y +CONFIG_ATA=y +CONFIG_SATA_SIL24=y +# CONFIG_ATA_SFF is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=y -CONFIG_MD_AUTODETECT=y CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m CONFIG_MULTICORE_RAID456=y -# CONFIG_MD_MULTIPATH is not set CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m CONFIG_DM_DEBUG=y CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m -# CONFIG_DM_RAID is not set CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m @@ -976,558 +345,143 @@ CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_DELAY=m CONFIG_DM_UEVENT=y -# CONFIG_DM_FLAKEY is not set -# CONFIG_TARGET_CORE is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_FIREWIRE is not set -# CONFIG_FIREWIRE_NOSY is not set -# CONFIG_I2O is not set +CONFIG_FUSION=y +CONFIG_FUSION_SAS=y CONFIG_NETDEVICES=y -CONFIG_IFB=m -CONFIG_DUMMY=m CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_IFB=m CONFIG_MACVLAN=m CONFIG_MACVTAP=m -# CONFIG_EQUALIZER is not set +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL_TRAP=y CONFIG_TUN=y CONFIG_VETH=m -# CONFIG_ARCNET is not set -# CONFIG_MII is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_BCM63XX_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_NET_ETHERNET is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -CONFIG_E1000E=m -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_IGBVF is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_CNIC is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -# CONFIG_ATL1C is not set -# CONFIG_JME is not set -# CONFIG_STMMAC_ETH is not set -# CONFIG_PCH_GBE is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set -# CONFIG_WLAN is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set - -# -# CAIF transport drivers -# +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6123_61_65=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EXAR is not set +# CONFIG_NET_VENDOR_HP is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_PACKET_ENGINE is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set # CONFIG_TILE_NET is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_VMXNET3 is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set -# CONFIG_INPUT_SPARSEKMAP is not set - -# -# Userland interfaces -# +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_WLAN is not set # CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# # CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# # CONFIG_VT is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set -# CONFIG_N_GSM is not set -CONFIG_DEVKMEM=y - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MFD_HSU is not set -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_PCH_UART is not set -# CONFIG_TTY_PRINTK is not set -CONFIG_HVC_DRIVER=y -# CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_TIMERIOMEM=m -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# PCMCIA character devices -# -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -# CONFIG_RAMOOPS is not set CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_MUX is not set -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_INTEL_MID is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_XILINX is not set -# CONFIG_I2C_EG20T is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_SPI is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set -CONFIG_MFD_SUPPORT=y -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS6507X is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_LPC_SCH is not set -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_VX855 is not set -# CONFIG_MFD_WL1273_CORE is not set -# CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set - -# -# Graphics support -# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y # CONFIG_VGA_ARB is not set -# CONFIG_DRM is not set -# CONFIG_STUB_POULSBO is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_SOUND is not set # CONFIG_HID_SUPPORT is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_NFC_DEVICES is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y +CONFIG_USB=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_LIBUSUAL=y +CONFIG_EDAC=y +CONFIG_EDAC_MM_EDAC=y CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# CONFIG_RTC_DRV_TILE=y -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT2_FS_XIP=y CONFIG_EXT3_FS=y -CONFIG_EXT3_DEFAULTS_TO_ORDERED=y -CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_XATTR=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_DEBUG is not set -CONFIG_FS_XIP=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=y -CONFIG_JBD2_DEBUG=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_XFS_FS=m +CONFIG_XFS_FS=y CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y -# CONFIG_XFS_RT is not set -# CONFIG_XFS_DEBUG is not set CONFIG_GFS2_FS=m CONFIG_GFS2_FS_LOCKING_DLM=y -# CONFIG_OCFS2_FS is not set CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_NILFS2_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_FANOTIFY is not set CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set -# CONFIG_QUOTA_DEBUG is not set -CONFIG_QUOTA_TREE=y -# CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y -# CONFIG_AUTOFS4_FS is not set +CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=y CONFIG_CUSE=m -CONFIG_GENERIC_ACL=y - -# -# Caches -# CONFIG_FSCACHE=m CONFIG_FSCACHE_STATS=y -# CONFIG_FSCACHE_HISTOGRAM is not set -# CONFIG_FSCACHE_DEBUG is not set -# CONFIG_FSCACHE_OBJECT_LIST is not set CONFIG_CACHEFILES=m -# CONFIG_CACHEFILES_DEBUG is not set -# CONFIG_CACHEFILES_HISTOGRAM is not set - -# -# CD-ROM/DVD Filesystems -# CONFIG_ISO9660_FS=m CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_CONFIGFS_FS=m -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set CONFIG_ECRYPT_FS=m -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_LOGFS is not set CONFIG_CRAMFS=m CONFIG_SQUASHFS=m -# CONFIG_SQUASHFS_XATTR is not set -# CONFIG_SQUASHFS_LZO is not set -# CONFIG_SQUASHFS_XZ is not set -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y -CONFIG_PNFS_FILE_LAYOUT=m CONFIG_NFS_FSCACHE=y -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -# CONFIG_NFS_USE_NEW_IDMAPPER is not set CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m -CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_CEPH_FS is not set CONFIG_CIFS=m CONFIG_CIFS_STATS=y -# CONFIG_CIFS_STATS2 is not set CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_UPCALL=y CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_DEBUG2 is not set CONFIG_CIFS_DFS_UPCALL=y CONFIG_CIFS_FSCACHE=y -# CONFIG_CIFS_ACL is not set -CONFIG_CIFS_EXPERIMENTAL=y -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -CONFIG_AMIGA_PARTITION=y -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_SUN_PARTITION=y -CONFIG_KARMA_PARTITION=y -CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m @@ -1567,185 +521,47 @@ CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m -CONFIG_DLM=m CONFIG_DLM_DEBUG=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 # CONFIG_ENABLE_WARN_DEPRECATED is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y CONFIG_STRIP_ASM_SYMS=y -# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y CONFIG_HEADERS_CHECK=y -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_SHIRQ=y CONFIG_LOCKUP_DETECTOR=y -# CONFIG_HARDLOCKUP_DETECTOR is not set -# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y -# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_REDUCED=y CONFIG_DEBUG_VM=y -# CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_LIST=y -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set CONFIG_DEBUG_CREDENTIALS=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y -# CONFIG_LKDTM is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BUILD_DOCSRC is not set CONFIG_DYNAMIC_DEBUG=y -# CONFIG_ATOMIC64_SELFTEST is not set CONFIG_ASYNC_RAID6_TEST=m -# CONFIG_SAMPLES is not set -# CONFIG_TEST_KSTRTOX is not set -CONFIG_EARLY_PRINTK=y CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_EXTRA_FLAGS="" - -# -# Security options -# -CONFIG_KEYS=y CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y -# CONFIG_SECURITY_PATH is not set -CONFIG_LSM_MMAP_MIN_ADDR=65536 CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y -CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 CONFIG_SECURITY_SELINUX_DISABLE=y -CONFIG_SECURITY_SELINUX_DEVELOP=y -CONFIG_SECURITY_SELINUX_AVC_STATS=y -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 -# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set -# CONFIG_SECURITY_SMACK is not set -# CONFIG_SECURITY_TOMOYO is not set -# CONFIG_SECURITY_APPARMOR is not set -# CONFIG_IMA is not set -CONFIG_DEFAULT_SECURITY_SELINUX=y -# CONFIG_DEFAULT_SECURITY_DAC is not set -CONFIG_DEFAULT_SECURITY="selinux" -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=m -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP=m -CONFIG_CRYPTO_PCOMP2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_PCRYPT=m -CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m - -# -# Authenticated Encryption with Associated Data -# CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_SEQIV=m - -# -# Block modes -# -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_CTR=m CONFIG_CRYPTO_CTS=m -CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m - -# -# Hash modes -# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m - -# -# Digest -# CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_GHASH=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m CONFIG_CRYPTO_RMD160=m @@ -1756,76 +572,16 @@ CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -# CONFIG_CRYPTO_SALSA20 is not set CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m - -# -# Random Number Generation -# -CONFIG_CRYPTO_ANSI_CPRNG=m -# CONFIG_CRYPTO_USER_API_HASH is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_DEV_HIFN_795X=m -CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_RAID6_PQ=m -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_FIND_LAST_BIT=y -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=m -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=m -CONFIG_AUDIT_GENERIC=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_LZO_COMPRESS=m -CONFIG_LZO_DECOMPRESS=m -# CONFIG_XZ_DEC is not set -# CONFIG_XZ_DEC_BCJ is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_CPU_RMAP=y -CONFIG_NLATTR=y -# CONFIG_AVERAGE is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 6f05f969b564..2b1fd31894f1 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig @@ -1,1162 +1,579 @@ -# -# Automatically generated make config: don't edit -# Linux/tile 2.6.39-rc5 Kernel Configuration -# Tue May 3 09:15:02 2011 -# -CONFIG_TILE=y -CONFIG_MMU=y -CONFIG_GENERIC_CSUM=y -CONFIG_SEMAPHORE_SLEEPERS=y -CONFIG_HAVE_ARCH_ALLOC_REMAP=y -CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_DEFAULT_MIGRATION_COST=10000000 -CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y -CONFIG_ARCH_PHYS_ADDR_T_64BIT=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_ARCH_DISCONTIGMEM_ENABLE=y -CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_STRICT_DEVMEM=y -CONFIG_SMP=y -# CONFIG_DEBUG_COPY_FROM_USER is not set -CONFIG_HVC_TILE=y -# CONFIG_TILEGX is not set -CONFIG_ARCH_DEFCONFIG="arch/tile/configs/tile_defconfig" -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y - -# -# General setup -# CONFIG_EXPERIMENTAL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_FHANDLE=y -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_PENDING_IRQ=y - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_PREEMPT_RCU is not set -# CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_RCU_FAST_NO_HZ is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_CGROUPS is not set -# CONFIG_NAMESPACES is not set -# CONFIG_SCHED_AUTOGROUP is not set -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_AUDIT=y +CONFIG_LOG_BUF_SHIFT=19 +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +CONFIG_NAMESPACES=y +CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="usr/contents.txt" -CONFIG_INITRAMFS_ROOT_UID=0 -CONFIG_INITRAMFS_ROOT_GID=0 -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_LZO is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y -# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EXPERT=y CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y CONFIG_EMBEDDED=y - -# -# Kernel Performance Events And Counters -# -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLUB_DEBUG=y # CONFIG_COMPAT_BRK is not set -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_USE_GENERIC_SMP_HELPERS=y - -# -# GCOV-based kernel profiling -# -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_INLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -CONFIG_MUTEX_SPIN_ON_OWNER=y - -# -# Tilera-specific configuration -# -CONFIG_NR_CPUS=64 -CONFIG_TICK_ONESHOT=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_SGI_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=100 -CONFIG_SCHED_HRTICK=y -# CONFIG_KEXEC is not set -CONFIG_HIGHMEM=y -CONFIG_NUMA=y -CONFIG_NODES_SHIFT=2 -# CONFIG_VMSPLIT_3_75G is not set -# CONFIG_VMSPLIT_3_5G is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2_75G is not set -# CONFIG_VMSPLIT_2_5G is not set -# CONFIG_VMSPLIT_2_25G is not set -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_DISCONTIGMEM_MANUAL=y -CONFIG_DISCONTIGMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_NEED_MULTIPLE_NODES=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_COMPACTION is not set -CONFIG_MIGRATION=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -# CONFIG_CMDLINE_BOOL is not set -CONFIG_VMALLOC_RESERVE=0x1000000 -CONFIG_HARDWALL=y -CONFIG_KERNEL_PL=1 - -# -# Bus options -# -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_NO_IOMEM is not set -# CONFIG_NO_IOPORT is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCI_IOV is not set -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_KCORE_ELF=y -CONFIG_BINFMT_ELF=y +CONFIG_PCI_DEBUG=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_MISC=y CONFIG_NET=y - -# -# Networking options -# CONFIG_PACKET=y CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set +CONFIG_XFRM_USER=y +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_NET_IPIP=m +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_L2TP is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set -# CONFIG_BATMAN_ADV is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_RDS=m +CONFIG_RDS_TCP=m +CONFIG_BRIDGE=m +CONFIG_NET_DSA=y +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_PHONET=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS_IND=y +CONFIG_DCB=y # CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_DEVTMPFS is not set -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_SENSORS_LIS3LV02D is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_PCH_PHUB is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_CB710_CORE is not set - -# -# Texas Instruments shared transport line discipline -# - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_CONNECTOR=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_ATA_OVER_ETH=m +CONFIG_RAID_ATTRS=m +CONFIG_SCSI_TGT=m CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_SCSI_CXGB4_ISCSI is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_SCSI_BNX2X_FCOE is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_PMCRAID is not set -# CONFIG_SCSI_PM8001 is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_BFA_FC is not set -# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_TARGET_CORE is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_FIREWIRE is not set -# CONFIG_FIREWIRE_NOSY is not set -# CONFIG_I2O is not set +CONFIG_ATA=y +CONFIG_SATA_SIL24=y +# CONFIG_ATA_SFF is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MULTICORE_RAID456=y +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_DEBUG=y +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +CONFIG_DM_UEVENT=y +CONFIG_FUSION=y +CONFIG_FUSION_SAS=y CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_IFB=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL_TRAP=y CONFIG_TUN=y -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -# CONFIG_MII is not set -# CONFIG_PHYLIB is not set -# CONFIG_NET_ETHERNET is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_IGBVF is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_CNIC is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -# CONFIG_ATL1C is not set -# CONFIG_JME is not set -# CONFIG_STMMAC_ETH is not set -# CONFIG_PCH_GBE is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set +CONFIG_VETH=m +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6123_61_65=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EXAR is not set +# CONFIG_NET_VENDOR_HP is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_PACKET_ENGINE is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VIA is not set # CONFIG_WLAN is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set - -# -# CAIF transport drivers -# -CONFIG_TILE_NET=y -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_VMXNET3 is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set -# CONFIG_INPUT_SPARSEKMAP is not set - -# -# Userland interfaces -# # CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# # CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# # CONFIG_VT is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set -# CONFIG_N_GSM is not set -CONFIG_DEVKMEM=y - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MFD_HSU is not set -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_PCH_UART is not set -# CONFIG_TTY_PRINTK is not set -CONFIG_HVC_DRIVER=y -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# PCMCIA character devices -# -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -# CONFIG_RAMOOPS is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_THERMAL is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +# CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_NOWAYOUT=y - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_ALIM7101_WDT is not set - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set -CONFIG_MFD_SUPPORT=y -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_LPC_SCH is not set -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_VX855 is not set -# CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set - -# -# Graphics support -# -CONFIG_VGA_ARB=y -CONFIG_VGA_ARB_MAX_GPUS=16 -# CONFIG_DRM is not set -# CONFIG_STUB_POULSBO is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_SOUND is not set +# CONFIG_VGA_ARB is not set # CONFIG_HID_SUPPORT is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set - -# -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_NFC_DEVICES is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set +# CONFIG_USB_SUPPORT is not set CONFIG_EDAC=y - -# -# Reporting subsystems -# -# CONFIG_EDAC_DEBUG is not set CONFIG_EDAC_MM_EDAC=y -CONFIG_EDAC_TILE=y -CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -# CONFIG_RTC_INTF_SYSFS is not set -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# CONFIG_RTC_DRV_TILE=y -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4_FS is not set -CONFIG_JBD=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -# CONFIG_FS_POSIX_ACL is not set -CONFIG_EXPORTFS=y -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_FANOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_QUOTACTL is not set -# CONFIG_AUTOFS4_FS is not set +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_XFS_FS=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y +CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=y -# CONFIG_CUSE is not set - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_CUSE=m +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +CONFIG_CACHEFILES=m +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_PROC_KCORE=y CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_LOGFS is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_ECRYPT_FS=m +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m CONFIG_NFS_FS=m CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_FSCACHE=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_FSCACHE=y CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_DLM_DEBUG=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y -# CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_LOCKUP_DETECTOR is not set -# CONFIG_HARDLOCKUP_DETECTOR is not set -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_STRIP_ASM_SYMS=y +CONFIG_DEBUG_FS=y +CONFIG_HEADERS_CHECK=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set +CONFIG_DEBUG_INFO_REDUCED=y CONFIG_DEBUG_VM=y -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_SAMPLES is not set -# CONFIG_TEST_KSTRTOX is not set -CONFIG_EARLY_PRINTK=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_CREDENTIALS=y +CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_ASYNC_RAID6_TEST=m CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_EXTRA_FLAGS="-femit-struct-debug-baseonly" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_ALGAPI2=m -CONFIG_CRYPTO_RNG=m -CONFIG_CRYPTO_RNG2=m -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_MANAGER2 is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_PCRYPT is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_GHASH is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -CONFIG_CRYPTO_ANSI_CPRNG=m -# CONFIG_CRYPTO_USER_API_HASH is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_FIND_LAST_BIT=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -# CONFIG_XZ_DEC is not set -# CONFIG_XZ_DEC_BCJ is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_CPU_RMAP=y -CONFIG_NLATTR=y -# CONFIG_AVERAGE is not set -CONFIG_HAVE_KVM=y -# CONFIG_VIRTUALIZATION is not set +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRC_CCITT=m +CONFIG_CRC7=m diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index a7869ad62776..77763ccd5a7d 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c @@ -303,10 +303,7 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index bedaf4e9f3a7..f79d4b88c747 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c @@ -97,10 +97,7 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -286,13 +283,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info, * the work_pending path in the return-to-user code, and * either way we can re-enable interrupts unconditionally. */ - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, - ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + block_sigmask(ka, sig); } return ret; diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c index f862b005eb73..71ae728e9d0b 100644 --- a/arch/tile/kernel/sysfs.c +++ b/arch/tile/kernel/sysfs.c @@ -163,7 +163,7 @@ static int __init create_sysfs_entries(void) #define create_hv_attr(name) \ if (!err) \ - err = sysfs_create_file(hypervisor_kobj, &dev_attr_##name); + err = sysfs_create_file(hypervisor_kobj, &dev_attr_##name.attr); create_hv_attr(type); create_hv_attr(version); create_hv_attr(config_version); diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c index cb0999fb64b4..b16ac49a968e 100644 --- a/arch/tile/lib/spinlock_32.c +++ b/arch/tile/lib/spinlock_32.c @@ -144,7 +144,7 @@ void arch_read_unlock(arch_rwlock_t *rwlock) for (;;) { __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 1); val = __insn_tns((int *)&rwlock->lock); - if (likely(val & 1) == 0) { + if (likely((val & 1) == 0)) { rwlock->lock = val - (1 << _RD_COUNT_SHIFT); __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); break; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 3bd37bdf1b8e..61d4f79a550e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -385,14 +385,15 @@ static __initconst const u64 westmere_hw_cache_event_ids #define NHM_LOCAL_DRAM (1 << 14) #define NHM_NON_DRAM (1 << 15) -#define NHM_ALL_DRAM (NHM_REMOTE_DRAM|NHM_LOCAL_DRAM) +#define NHM_LOCAL (NHM_LOCAL_DRAM|NHM_REMOTE_CACHE_FWD) +#define NHM_REMOTE (NHM_REMOTE_DRAM) #define NHM_DMND_READ (NHM_DMND_DATA_RD) #define NHM_DMND_WRITE (NHM_DMND_RFO|NHM_DMND_WB) #define NHM_DMND_PREFETCH (NHM_PF_DATA_RD|NHM_PF_DATA_RFO) #define NHM_L3_HIT (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM) -#define NHM_L3_MISS (NHM_NON_DRAM|NHM_ALL_DRAM|NHM_REMOTE_CACHE_FWD) +#define NHM_L3_MISS (NHM_NON_DRAM|NHM_LOCAL_DRAM|NHM_REMOTE_DRAM|NHM_REMOTE_CACHE_FWD) #define NHM_L3_ACCESS (NHM_L3_HIT|NHM_L3_MISS) static __initconst const u64 nehalem_hw_cache_extra_regs @@ -416,16 +417,16 @@ static __initconst const u64 nehalem_hw_cache_extra_regs }, [ C(NODE) ] = { [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_ALL_DRAM, - [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_REMOTE_DRAM, + [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_LOCAL|NHM_REMOTE, + [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_REMOTE, }, [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_ALL_DRAM, - [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_REMOTE_DRAM, + [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_LOCAL|NHM_REMOTE, + [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_REMOTE, }, [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_ALL_DRAM, - [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_REMOTE_DRAM, + [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_LOCAL|NHM_REMOTE, + [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_REMOTE, }, }, }; diff --git a/block/blk-ioc.c b/block/blk-ioc.c index 8b782a63c297..fb95dd2f889a 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -36,11 +36,23 @@ static void icq_free_icq_rcu(struct rcu_head *head) kmem_cache_free(icq->__rcu_icq_cache, icq); } -/* - * Exit and free an icq. Called with both ioc and q locked. - */ +/* Exit an icq. Called with both ioc and q locked. */ static void ioc_exit_icq(struct io_cq *icq) { + struct elevator_type *et = icq->q->elevator->type; + + if (icq->flags & ICQ_EXITED) + return; + + if (et->ops.elevator_exit_icq_fn) + et->ops.elevator_exit_icq_fn(icq); + + icq->flags |= ICQ_EXITED; +} + +/* Release an icq. Called with both ioc and q locked. */ +static void ioc_destroy_icq(struct io_cq *icq) +{ struct io_context *ioc = icq->ioc; struct request_queue *q = icq->q; struct elevator_type *et = q->elevator->type; @@ -60,8 +72,7 @@ static void ioc_exit_icq(struct io_cq *icq) if (rcu_dereference_raw(ioc->icq_hint) == icq) rcu_assign_pointer(ioc->icq_hint, NULL); - if (et->ops.elevator_exit_icq_fn) - et->ops.elevator_exit_icq_fn(icq); + ioc_exit_icq(icq); /* * @icq->q might have gone away by the time RCU callback runs @@ -79,7 +90,6 @@ static void ioc_release_fn(struct work_struct *work) { struct io_context *ioc = container_of(work, struct io_context, release_work); - struct request_queue *last_q = NULL; unsigned long flags; /* @@ -93,44 +103,19 @@ static void ioc_release_fn(struct work_struct *work) while (!hlist_empty(&ioc->icq_list)) { struct io_cq *icq = hlist_entry(ioc->icq_list.first, struct io_cq, ioc_node); - struct request_queue *this_q = icq->q; - - if (this_q != last_q) { - /* - * Need to switch to @this_q. Once we release - * @ioc->lock, it can go away along with @cic. - * Hold on to it. - */ - __blk_get_queue(this_q); - - /* - * blk_put_queue() might sleep thanks to kobject - * idiocy. Always release both locks, put and - * restart. - */ - if (last_q) { - spin_unlock(last_q->queue_lock); - spin_unlock_irqrestore(&ioc->lock, flags); - blk_put_queue(last_q); - } else { - spin_unlock_irqrestore(&ioc->lock, flags); - } - - last_q = this_q; - spin_lock_irqsave(this_q->queue_lock, flags); - spin_lock_nested(&ioc->lock, 1); - continue; + struct request_queue *q = icq->q; + + if (spin_trylock(q->queue_lock)) { + ioc_destroy_icq(icq); + spin_unlock(q->queue_lock); + } else { + spin_unlock_irqrestore(&ioc->lock, flags); + cpu_relax(); + spin_lock_irqsave_nested(&ioc->lock, flags, 1); } - ioc_exit_icq(icq); } - if (last_q) { - spin_unlock(last_q->queue_lock); - spin_unlock_irqrestore(&ioc->lock, flags); - blk_put_queue(last_q); - } else { - spin_unlock_irqrestore(&ioc->lock, flags); - } + spin_unlock_irqrestore(&ioc->lock, flags); kmem_cache_free(iocontext_cachep, ioc); } @@ -145,6 +130,7 @@ static void ioc_release_fn(struct work_struct *work) void put_io_context(struct io_context *ioc) { unsigned long flags; + bool free_ioc = false; if (ioc == NULL) return; @@ -159,8 +145,13 @@ void put_io_context(struct io_context *ioc) spin_lock_irqsave(&ioc->lock, flags); if (!hlist_empty(&ioc->icq_list)) schedule_work(&ioc->release_work); + else + free_ioc = true; spin_unlock_irqrestore(&ioc->lock, flags); } + + if (free_ioc) + kmem_cache_free(iocontext_cachep, ioc); } EXPORT_SYMBOL(put_io_context); @@ -168,13 +159,41 @@ EXPORT_SYMBOL(put_io_context); void exit_io_context(struct task_struct *task) { struct io_context *ioc; + struct io_cq *icq; + struct hlist_node *n; + unsigned long flags; task_lock(task); ioc = task->io_context; task->io_context = NULL; task_unlock(task); - atomic_dec(&ioc->nr_tasks); + if (!atomic_dec_and_test(&ioc->nr_tasks)) { + put_io_context(ioc); + return; + } + + /* + * Need ioc lock to walk icq_list and q lock to exit icq. Perform + * reverse double locking. Read comment in ioc_release_fn() for + * explanation on the nested locking annotation. + */ +retry: + spin_lock_irqsave_nested(&ioc->lock, flags, 1); + hlist_for_each_entry(icq, n, &ioc->icq_list, ioc_node) { + if (icq->flags & ICQ_EXITED) + continue; + if (spin_trylock(icq->q->queue_lock)) { + ioc_exit_icq(icq); + spin_unlock(icq->q->queue_lock); + } else { + spin_unlock_irqrestore(&ioc->lock, flags); + cpu_relax(); + goto retry; + } + } + spin_unlock_irqrestore(&ioc->lock, flags); + put_io_context(ioc); } @@ -194,7 +213,7 @@ void ioc_clear_queue(struct request_queue *q) struct io_context *ioc = icq->ioc; spin_lock(&ioc->lock); - ioc_exit_icq(icq); + ioc_destroy_icq(icq); spin_unlock(&ioc->lock); } } @@ -363,13 +382,13 @@ struct io_cq *ioc_create_icq(struct request_queue *q, gfp_t gfp_mask) return icq; } -void ioc_set_changed(struct io_context *ioc, int which) +void ioc_set_icq_flags(struct io_context *ioc, unsigned int flags) { struct io_cq *icq; struct hlist_node *n; hlist_for_each_entry(icq, n, &ioc->icq_list, ioc_node) - set_bit(which, &icq->changed); + icq->flags |= flags; } /** @@ -387,7 +406,7 @@ void ioc_ioprio_changed(struct io_context *ioc, int ioprio) spin_lock_irqsave(&ioc->lock, flags); ioc->ioprio = ioprio; - ioc_set_changed(ioc, ICQ_IOPRIO_CHANGED); + ioc_set_icq_flags(ioc, ICQ_IOPRIO_CHANGED); spin_unlock_irqrestore(&ioc->lock, flags); } @@ -404,11 +423,33 @@ void ioc_cgroup_changed(struct io_context *ioc) unsigned long flags; spin_lock_irqsave(&ioc->lock, flags); - ioc_set_changed(ioc, ICQ_CGROUP_CHANGED); + ioc_set_icq_flags(ioc, ICQ_CGROUP_CHANGED); spin_unlock_irqrestore(&ioc->lock, flags); } EXPORT_SYMBOL(ioc_cgroup_changed); +/** + * icq_get_changed - fetch and clear icq changed mask + * @icq: icq of interest + * + * Fetch and clear ICQ_*_CHANGED bits from @icq. Grabs and releases + * @icq->ioc->lock. + */ +unsigned icq_get_changed(struct io_cq *icq) +{ + unsigned int changed = 0; + unsigned long flags; + + if (unlikely(icq->flags & ICQ_CHANGED_MASK)) { + spin_lock_irqsave(&icq->ioc->lock, flags); + changed = icq->flags & ICQ_CHANGED_MASK; + icq->flags &= ~ICQ_CHANGED_MASK; + spin_unlock_irqrestore(&icq->ioc->lock, flags); + } + return changed; +} +EXPORT_SYMBOL(icq_get_changed); + static int __init blk_ioc_init(void) { iocontext_cachep = kmem_cache_create("blkdev_ioc", diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index d0ba50533668..457295253566 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3470,20 +3470,20 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) const int rw = rq_data_dir(rq); const bool is_sync = rq_is_sync(rq); struct cfq_queue *cfqq; + unsigned int changed; might_sleep_if(gfp_mask & __GFP_WAIT); spin_lock_irq(q->queue_lock); /* handle changed notifications */ - if (unlikely(cic->icq.changed)) { - if (test_and_clear_bit(ICQ_IOPRIO_CHANGED, &cic->icq.changed)) - changed_ioprio(cic); + changed = icq_get_changed(&cic->icq); + if (unlikely(changed & ICQ_IOPRIO_CHANGED)) + changed_ioprio(cic); #ifdef CONFIG_CFQ_GROUP_IOSCHED - if (test_and_clear_bit(ICQ_CGROUP_CHANGED, &cic->icq.changed)) - changed_cgroup(cic); + if (unlikely(changed & ICQ_CGROUP_CHANGED)) + changed_cgroup(cic); #endif - } new_queue: cfqq = cic_to_cfqq(cic, is_sync); diff --git a/block/genhd.c b/block/genhd.c index 23b4f7063322..df9816ede75b 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -35,6 +35,7 @@ static DEFINE_IDR(ext_devt_idr); static struct device_type disk_type; +static void disk_alloc_events(struct gendisk *disk); static void disk_add_events(struct gendisk *disk); static void disk_del_events(struct gendisk *disk); static void disk_release_events(struct gendisk *disk); @@ -601,6 +602,8 @@ void add_disk(struct gendisk *disk) disk->major = MAJOR(devt); disk->first_minor = MINOR(devt); + disk_alloc_events(disk); + /* Register BDI before referencing it from bdev */ bdi = &disk->queue->backing_dev_info; bdi_register_dev(bdi, disk_devt(disk)); @@ -1475,9 +1478,9 @@ static void __disk_unblock_events(struct gendisk *disk, bool check_now) intv = disk_events_poll_jiffies(disk); set_timer_slack(&ev->dwork.timer, intv / 4); if (check_now) - queue_delayed_work(system_nrt_wq, &ev->dwork, 0); + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); else if (intv) - queue_delayed_work(system_nrt_wq, &ev->dwork, intv); + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, intv); out_unlock: spin_unlock_irqrestore(&ev->lock, flags); } @@ -1521,7 +1524,7 @@ void disk_flush_events(struct gendisk *disk, unsigned int mask) ev->clearing |= mask; if (!ev->block) { cancel_delayed_work(&ev->dwork); - queue_delayed_work(system_nrt_wq, &ev->dwork, 0); + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); } spin_unlock_irq(&ev->lock); } @@ -1558,7 +1561,7 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask) /* uncondtionally schedule event check and wait for it to finish */ disk_block_events(disk); - queue_delayed_work(system_nrt_wq, &ev->dwork, 0); + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, 0); flush_delayed_work(&ev->dwork); __disk_unblock_events(disk, false); @@ -1595,7 +1598,7 @@ static void disk_events_workfn(struct work_struct *work) intv = disk_events_poll_jiffies(disk); if (!ev->block && intv) - queue_delayed_work(system_nrt_wq, &ev->dwork, intv); + queue_delayed_work(system_nrt_freezable_wq, &ev->dwork, intv); spin_unlock_irq(&ev->lock); @@ -1733,9 +1736,9 @@ module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops, &disk_events_dfl_poll_msecs, 0644); /* - * disk_{add|del|release}_events - initialize and destroy disk_events. + * disk_{alloc|add|del|release}_events - initialize and destroy disk_events. */ -static void disk_add_events(struct gendisk *disk) +static void disk_alloc_events(struct gendisk *disk) { struct disk_events *ev; @@ -1748,16 +1751,6 @@ static void disk_add_events(struct gendisk *disk) return; } - if (sysfs_create_files(&disk_to_dev(disk)->kobj, - disk_events_attrs) < 0) { - pr_warn("%s: failed to create sysfs files for events\n", - disk->disk_name); - kfree(ev); - return; - } - - disk->ev = ev; - INIT_LIST_HEAD(&ev->node); ev->disk = disk; spin_lock_init(&ev->lock); @@ -1766,8 +1759,21 @@ static void disk_add_events(struct gendisk *disk) ev->poll_msecs = -1; INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); + disk->ev = ev; +} + +static void disk_add_events(struct gendisk *disk) +{ + if (!disk->ev) + return; + + /* FIXME: error handling */ + if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0) + pr_warn("%s: failed to create sysfs files for events\n", + disk->disk_name); + mutex_lock(&disk_events_mutex); - list_add_tail(&ev->node, &disk_events); + list_add_tail(&disk->ev->node, &disk_events); mutex_unlock(&disk_events_mutex); /* diff --git a/block/partition-generic.c b/block/partition-generic.c index d06ec1c829c2..6df5d6928a44 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -389,17 +389,11 @@ static bool disk_unlock_native_capacity(struct gendisk *disk) } } -int rescan_partitions(struct gendisk *disk, struct block_device *bdev) +static int drop_partitions(struct gendisk *disk, struct block_device *bdev) { - struct parsed_partitions *state = NULL; struct disk_part_iter piter; struct hd_struct *part; - int p, highest, res; -rescan: - if (state && !IS_ERR(state)) { - kfree(state); - state = NULL; - } + int res; if (bdev->bd_part_count) return -EBUSY; @@ -412,6 +406,24 @@ rescan: delete_partition(disk, part->partno); disk_part_iter_exit(&piter); + return 0; +} + +int rescan_partitions(struct gendisk *disk, struct block_device *bdev) +{ + struct parsed_partitions *state = NULL; + struct hd_struct *part; + int p, highest, res; +rescan: + if (state && !IS_ERR(state)) { + kfree(state); + state = NULL; + } + + res = drop_partitions(disk, bdev); + if (res) + return res; + if (disk->fops->revalidate_disk) disk->fops->revalidate_disk(disk); check_disk_size_change(disk, bdev); @@ -515,6 +527,26 @@ rescan: return 0; } +int invalidate_partitions(struct gendisk *disk, struct block_device *bdev) +{ + int res; + + if (!bdev->bd_invalidated) + return 0; + + res = drop_partitions(disk, bdev); + if (res) + return res; + + set_capacity(disk, 0); + check_disk_size_change(disk, bdev); + bdev->bd_invalidated = 0; + /* tell userspace that the media / partition table may have changed */ + kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); + + return 0; +} + unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) { struct address_space *mapping = bdev->bd_inode->i_mapping; diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 485a11a6de96..6ff612d099c3 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -156,9 +156,6 @@ static int tx_complete = 0,dma_complete = 0,queued = 0,requeued = 0, static struct atm_dev *eni_boards = NULL; -static u32 *cpu_zeroes = NULL; /* aligned "magic" zeroes */ -static dma_addr_t zeroes; - /* Read/write registers on card */ #define eni_in(r) readl(eni_dev->reg+(r)*4) #define eni_out(v,r) writel((v),eni_dev->reg+(r)*4) @@ -1138,8 +1135,10 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */ skb_shinfo(skb)->frags[i].page_offset, skb_frag_size(&skb_shinfo(skb)->frags[i])); } - if (skb->len & 3) - put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3)); + if (skb->len & 3) { + put_dma(tx->index, eni_dev->dma, &j, eni_dev->zero.dma, + 4 - (skb->len & 3)); + } /* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */ eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) << MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) | @@ -1728,6 +1727,7 @@ static int __devinit eni_do_init(struct atm_dev *dev) "mapping\n",dev->number); return error; } + eni_dev->ioaddr = base; eni_dev->base_diff = real_base - (unsigned long) base; /* id may not be present in ASIC Tonga boards - check this @@@ */ if (!eni_dev->asic) { @@ -1789,6 +1789,14 @@ unmap: goto out; } +static void eni_do_release(struct atm_dev *dev) +{ + struct eni_dev *ed = ENI_DEV(dev); + + dev->phy->stop(dev); + dev->phy = NULL; + iounmap(ed->ioaddr); +} static int __devinit eni_start(struct atm_dev *dev) { @@ -2220,48 +2228,60 @@ static const struct atmdev_ops ops = { static int __devinit eni_init_one(struct pci_dev *pci_dev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { struct atm_dev *dev; struct eni_dev *eni_dev; - int error = -ENOMEM; + struct eni_zero *zero; + int rc; + + rc = pci_enable_device(pci_dev); + if (rc < 0) + goto out; - DPRINTK("eni_init_one\n"); + rc = -ENOMEM; + eni_dev = kmalloc(sizeof(struct eni_dev), GFP_KERNEL); + if (!eni_dev) + goto err_disable; - if (pci_enable_device(pci_dev)) { - error = -EIO; - goto out0; - } + zero = &eni_dev->zero; + zero->addr = pci_alloc_consistent(pci_dev, ENI_ZEROES_SIZE, &zero->dma); + if (!zero->addr) + goto err_kfree; - eni_dev = kmalloc(sizeof(struct eni_dev),GFP_KERNEL); - if (!eni_dev) goto out0; - if (!cpu_zeroes) { - cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE, - &zeroes); - if (!cpu_zeroes) goto out1; - } dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); - if (!dev) goto out2; + if (!dev) + goto err_free_consistent; + + dev->dev_data = eni_dev; pci_set_drvdata(pci_dev, dev); eni_dev->pci_dev = pci_dev; - dev->dev_data = eni_dev; eni_dev->asic = ent->driver_data; - error = eni_do_init(dev); - if (error) goto out3; - error = eni_start(dev); - if (error) goto out3; + + rc = eni_do_init(dev); + if (rc < 0) + goto err_unregister; + + rc = eni_start(dev); + if (rc < 0) + goto err_eni_release; + eni_dev->more = eni_boards; eni_boards = dev; - return 0; -out3: +out: + return rc; + +err_eni_release: + eni_do_release(dev); +err_unregister: atm_dev_deregister(dev); -out2: - pci_free_consistent(eni_dev->pci_dev,ENI_ZEROES_SIZE,cpu_zeroes,zeroes); - cpu_zeroes = NULL; -out1: +err_free_consistent: + pci_free_consistent(pci_dev, ENI_ZEROES_SIZE, zero->addr, zero->dma); +err_kfree: kfree(eni_dev); -out0: - return error; +err_disable: + pci_disable_device(pci_dev); + goto out; } @@ -2273,9 +2293,17 @@ static struct pci_device_id eni_pci_tbl[] = { MODULE_DEVICE_TABLE(pci,eni_pci_tbl); -static void __devexit eni_remove_one(struct pci_dev *pci_dev) +static void __devexit eni_remove_one(struct pci_dev *pdev) { - /* grrr */ + struct atm_dev *dev = pci_get_drvdata(pdev); + struct eni_dev *ed = ENI_DEV(dev); + struct eni_zero *zero = &ed->zero; + + eni_do_release(dev); + atm_dev_deregister(dev); + pci_free_consistent(pdev, ENI_ZEROES_SIZE, zero->addr, zero->dma); + kfree(ed); + pci_disable_device(pdev); } diff --git a/drivers/atm/eni.h b/drivers/atm/eni.h index dc9a62cc2605..565e53a5cb78 100644 --- a/drivers/atm/eni.h +++ b/drivers/atm/eni.h @@ -72,6 +72,7 @@ struct eni_dev { u32 events; /* pending events */ /*-------------------------------- base pointers into Midway address space */ + void __iomem *ioaddr; void __iomem *phy; /* PHY interface chip registers */ void __iomem *reg; /* register base */ void __iomem *ram; /* RAM base */ @@ -86,6 +87,10 @@ struct eni_dev { wait_queue_head_t tx_wait; /* for close */ int tx_bw; /* remaining bandwidth */ u32 dma[TX_DMA_BUF*2]; /* DMA request scratch area */ + struct eni_zero { /* aligned "magic" zeroes */ + u32 *addr; + dma_addr_t dma; + } zero; int tx_mult; /* buffer size multiplier (percent) */ /*-------------------------------- RX part */ u32 serv_read; /* host service read index */ diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index e086fbbbe853..8db9089127c5 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -1177,7 +1177,8 @@ static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T int TimeoutCounter; int i; - + memset(&CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T)); + if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32))) return DAC960_Failure(Controller, "DMA mask out of range"); Controller->BounceBufferLimit = DMA_BIT_MASK(32); @@ -4627,7 +4628,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) DAC960_Controller_T *Controller = Command->Controller; DAC960_CommandType_T CommandType = Command->CommandType; DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; - DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode; + DAC960_V2_IOCTL_Opcode_T IOCTLOpcode = CommandMailbox->Common.IOCTL_Opcode; + DAC960_V2_CommandOpcode_T CommandOpcode = CommandMailbox->SCSI_10.CommandOpcode; DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus; if (CommandType == DAC960_ReadCommand || @@ -4699,7 +4701,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) { if (Controller->ShutdownMonitoringTimer) return; - if (CommandOpcode == DAC960_V2_GetControllerInfo) + if (IOCTLOpcode == DAC960_V2_GetControllerInfo) { DAC960_V2_ControllerInfo_T *NewControllerInfo = Controller->V2.NewControllerInformation; @@ -4719,14 +4721,14 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) memcpy(ControllerInfo, NewControllerInfo, sizeof(DAC960_V2_ControllerInfo_T)); } - else if (CommandOpcode == DAC960_V2_GetEvent) + else if (IOCTLOpcode == DAC960_V2_GetEvent) { if (CommandStatus == DAC960_V2_NormalCompletion) { DAC960_V2_ReportEvent(Controller, Controller->V2.Event); } Controller->V2.NextEventSequenceNumber++; } - else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && + else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && CommandStatus == DAC960_V2_NormalCompletion) { DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo = @@ -4915,7 +4917,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) NewPhysicalDeviceInfo->LogicalUnit++; Controller->V2.PhysicalDeviceIndex++; } - else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) + else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) { unsigned int DeviceIndex; for (DeviceIndex = Controller->V2.PhysicalDeviceIndex; @@ -4938,7 +4940,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) } Controller->V2.NeedPhysicalDeviceInformation = false; } - else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid && + else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid && CommandStatus == DAC960_V2_NormalCompletion) { DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo = @@ -5065,7 +5067,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) [LogicalDeviceNumber] = true; NewLogicalDeviceInfo->LogicalDeviceNumber++; } - else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid) + else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid) { int LogicalDriveNumber; for (LogicalDriveNumber = 0; diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index e7472f567c9d..3fb6ab4c8b4e 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -1120,7 +1120,7 @@ static inline void carm_handle_resp(struct carm_host *host, break; case MISC_GET_FW_VER: { struct carm_fw_ver *ver = (struct carm_fw_ver *) - mem + sizeof(struct carm_msg_get_fw_ver); + (mem + sizeof(struct carm_msg_get_fw_ver)); if (!error) { host->fw_ver = le32_to_cpu(ver->version); host->flags |= (ver->features & FL_FW_VER_MASK); diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index 618bd4d87d28..99d5527b2ca6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -54,14 +54,14 @@ convert_to_display_mode(struct drm_display_mode *mode, mode->vrefresh = timing->refresh; mode->hdisplay = timing->xres; - mode->hsync_start = mode->hdisplay + timing->left_margin; + mode->hsync_start = mode->hdisplay + timing->right_margin; mode->hsync_end = mode->hsync_start + timing->hsync_len; - mode->htotal = mode->hsync_end + timing->right_margin; + mode->htotal = mode->hsync_end + timing->left_margin; mode->vdisplay = timing->yres; - mode->vsync_start = mode->vdisplay + timing->upper_margin; + mode->vsync_start = mode->vdisplay + timing->lower_margin; mode->vsync_end = mode->vsync_start + timing->vsync_len; - mode->vtotal = mode->vsync_end + timing->lower_margin; + mode->vtotal = mode->vsync_end + timing->upper_margin; mode->width_mm = panel->width_mm; mode->height_mm = panel->height_mm; @@ -85,14 +85,14 @@ convert_to_video_timing(struct fb_videomode *timing, timing->refresh = drm_mode_vrefresh(mode); timing->xres = mode->hdisplay; - timing->left_margin = mode->hsync_start - mode->hdisplay; + timing->right_margin = mode->hsync_start - mode->hdisplay; timing->hsync_len = mode->hsync_end - mode->hsync_start; - timing->right_margin = mode->htotal - mode->hsync_end; + timing->left_margin = mode->htotal - mode->hsync_end; timing->yres = mode->vdisplay; - timing->upper_margin = mode->vsync_start - mode->vdisplay; + timing->lower_margin = mode->vsync_start - mode->vdisplay; timing->vsync_len = mode->vsync_end - mode->vsync_start; - timing->lower_margin = mode->vtotal - mode->vsync_end; + timing->upper_margin = mode->vtotal - mode->vsync_end; if (mode->flags & DRM_MODE_FLAG_INTERLACE) timing->vmode = FB_VMODE_INTERLACED; diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 58820ebd3558..09cc13f791b3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -246,7 +246,7 @@ static struct platform_driver exynos_drm_platform_driver = { .remove = __devexit_p(exynos_drm_platform_remove), .driver = { .owner = THIS_MODULE, - .name = DRIVER_NAME, + .name = "exynos-drm", }, }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 3508700e529b..54f8f074822f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -46,39 +46,13 @@ struct exynos_drm_fbdev { struct exynos_drm_gem_obj *exynos_gem_obj; }; -static int exynos_drm_fbdev_set_par(struct fb_info *info) -{ - struct fb_var_screeninfo *var = &info->var; - - switch (var->bits_per_pixel) { - case 32: - case 24: - case 18: - case 16: - case 12: - info->fix.visual = FB_VISUAL_TRUECOLOR; - break; - case 1: - info->fix.visual = FB_VISUAL_MONO01; - break; - default: - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - break; - } - - info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; - - return drm_fb_helper_set_par(info); -} - - static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = exynos_drm_fbdev_set_par, + .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_pan_display = drm_fb_helper_pan_display, .fb_setcmap = drm_fb_helper_setcmap, diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 360adf2bba04..56458eea0501 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -817,8 +817,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) goto err_clk_get; } - clk_enable(ctx->bus_clk); - ctx->lcd_clk = clk_get(dev, "sclk_fimd"); if (IS_ERR(ctx->lcd_clk)) { dev_err(dev, "failed to get lcd clock\n"); @@ -826,8 +824,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) goto err_bus_clk; } - clk_enable(ctx->lcd_clk); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "failed to find registers\n"); @@ -864,17 +860,11 @@ static int __devinit fimd_probe(struct platform_device *pdev) goto err_req_irq; } - ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); ctx->vidcon0 = pdata->vidcon0; ctx->vidcon1 = pdata->vidcon1; ctx->default_win = pdata->default_win; ctx->panel = panel; - panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; - - DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", - panel->timing.pixclock, ctx->clkdiv); - subdrv = &ctx->subdrv; subdrv->probe = fimd_subdrv_probe; @@ -889,10 +879,15 @@ static int __devinit fimd_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); - pm_runtime_set_active(dev); pm_runtime_enable(dev); pm_runtime_get_sync(dev); + ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); + panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; + + DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", + panel->timing.pixclock, ctx->clkdiv); + for (win = 0; win < WINDOWS_NR; win++) fimd_clear_win(ctx, win); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 03c53fcf8653..558ac716a328 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2689,7 +2689,7 @@ #define DVS_FORMAT_RGBX888 (2<<25) #define DVS_FORMAT_RGBX161616 (3<<25) #define DVS_SOURCE_KEY (1<<22) -#define DVS_RGB_ORDER_RGBX (1<<20) +#define DVS_RGB_ORDER_XBGR (1<<20) #define DVS_YUV_BYTE_ORDER_MASK (3<<16) #define DVS_YUV_ORDER_YUYV (0<<16) #define DVS_YUV_ORDER_UYVY (1<<16) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f851db7be2cc..397087cf689e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7828,6 +7828,7 @@ int intel_framebuffer_init(struct drm_device *dev, case DRM_FORMAT_RGB332: case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ARGB8888: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_ARGB2101010: diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 2288abf88cce..a0835040c86b 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -225,16 +225,16 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, /* Mask out pixel format bits in case we change it */ dvscntr &= ~DVS_PIXFORMAT_MASK; - dvscntr &= ~DVS_RGB_ORDER_RGBX; + dvscntr &= ~DVS_RGB_ORDER_XBGR; dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; switch (fb->pixel_format) { case DRM_FORMAT_XBGR8888: - dvscntr |= DVS_FORMAT_RGBX888; + dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; pixel_size = 4; break; case DRM_FORMAT_XRGB8888: - dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX; + dvscntr |= DVS_FORMAT_RGBX888; pixel_size = 4; break; case DRM_FORMAT_YUYV: diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c index 880b90cf4d32..e3e8420b7b81 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c @@ -200,17 +200,11 @@ static int zl6100_probe(struct i2c_client *client, data->id = mid->driver_data; /* - * ZL2005, ZL2008, ZL2105, and ZL6100 are known to require a wait time - * between I2C accesses. ZL2004 and ZL6105 are known to be safe. - * Other chips have not yet been tested. - * - * Only clear the wait time for chips known to be safe. The wait time - * can be cleared later for additional chips if tests show that it - * is not needed (in other words, better be safe than sorry). + * According to information from the chip vendor, all currently + * supported chips are known to require a wait time between I2C + * accesses. */ data->delay = delay; - if (data->id == zl2004 || data->id == zl6105) - data->delay = 0; /* * Since there was a direct I2C device access above, wait before diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 5276d1933dbc..a658d62c5e10 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -39,7 +39,7 @@ 0x8860 0xa1 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 - w83627uhg 8 2 2 2 0xa230 0xc1 0x5ca3 + w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 @@ -1607,7 +1607,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ val = step_time_to_reg(val, data->pwm_mode[nr]); \ mutex_lock(&data->update_lock); \ data->reg[nr] = val; \ - w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ + w83627ehf_write_value(data, data->REG_##REG[nr], val); \ mutex_unlock(&data->update_lock); \ return count; \ } \ @@ -2004,7 +2004,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) goto exit; } - data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct w83627ehf_data), + GFP_KERNEL); if (!data) { err = -ENOMEM; goto exit_release; @@ -2157,16 +2158,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) w83627ehf_set_temp_reg_ehf(data, 3); /* - * Temperature sources for temp1 and temp2 are selected with + * Temperature sources for temp2 and temp3 are selected with * bank 0, registers 0x49 and 0x4a. */ data->temp_src[0] = 0; /* SYSTIN */ reg = w83627ehf_read_value(data, 0x49) & 0x07; /* Adjust to have the same mapping as other source registers */ if (reg == 0) - data->temp_src[1]++; + data->temp_src[1] = 1; else if (reg >= 2 && reg <= 5) - data->temp_src[1] += 2; + data->temp_src[1] = reg + 2; else /* should never happen */ data->have_temp &= ~(1 << 1); reg = w83627ehf_read_value(data, 0x4a); @@ -2493,9 +2494,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) exit_remove: w83627ehf_device_remove_files(dev); - kfree(data); - platform_set_drvdata(pdev, NULL); exit_release: + platform_set_drvdata(pdev, NULL); release_region(res->start, IOREGION_LENGTH); exit: return err; @@ -2509,7 +2509,6 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev) w83627ehf_device_remove_files(&pdev->dev); release_region(data->addr, IOREGION_LENGTH); platform_set_drvdata(pdev, NULL); - kfree(data); return 0; } diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 525c7345fa0b..24f94f4ae395 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -103,8 +103,14 @@ static int sclhi(struct i2c_algo_bit_data *adap) * chips may hold it low ("clock stretching") while they * are processing data internally. */ - if (time_after(jiffies, start + adap->timeout)) + if (time_after(jiffies, start + adap->timeout)) { + /* Test one last time, as we may have been preempted + * between last check and timeout test. + */ + if (getscl(adap)) + break; return -ETIMEDOUT; + } cond_resched(); } #ifdef DEBUG diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 1e5606185b4f..e9c18939eda7 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1386,8 +1386,10 @@ int i2c_master_send(const struct i2c_client *client, const char *buf, int count) ret = i2c_transfer(adap, &msg, 1); - /* If everything went ok (i.e. 1 msg transmitted), return #bytes - transmitted, else error code. */ + /* + * If everything went ok (i.e. 1 msg transmitted), return #bytes + * transmitted, else error code. + */ return (ret == 1) ? count : ret; } EXPORT_SYMBOL(i2c_master_send); @@ -1414,8 +1416,10 @@ int i2c_master_recv(const struct i2c_client *client, char *buf, int count) ret = i2c_transfer(adap, &msg, 1); - /* If everything went ok (i.e. 1 msg transmitted), return #bytes - transmitted, else error code. */ + /* + * If everything went ok (i.e. 1 msg received), return #bytes received, + * else error code. + */ return (ret == 1) ? count : ret; } EXPORT_SYMBOL(i2c_master_recv); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 654685c9303e..aa77e54a8fae 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -49,9 +49,6 @@ struct smsdvb_client_t { struct completion tune_done; - /* todo: save freq/band instead whole struct */ - struct dtv_frontend_properties fe_params; - struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; int event_fe_state; int event_unc_state; @@ -744,12 +741,124 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe) struct dtv_frontend_properties *fep = &fe->dtv_property_cache; struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); + struct smscore_device_t *coredev = client->coredev; + struct TRANSMISSION_STATISTICS_S *td = + &client->sms_stat_dvb.TransmissionData; - sms_debug(""); + switch (smscore_get_device_mode(coredev)) { + case DEVICE_MODE_DVBT: + case DEVICE_MODE_DVBT_BDA: + fep->frequency = td->Frequency; + + switch (td->Bandwidth) { + case 6: + fep->bandwidth_hz = 6000000; + break; + case 7: + fep->bandwidth_hz = 7000000; + break; + case 8: + fep->bandwidth_hz = 8000000; + break; + } + + switch (td->TransmissionMode) { + case 2: + fep->transmission_mode = TRANSMISSION_MODE_2K; + break; + case 8: + fep->transmission_mode = TRANSMISSION_MODE_8K; + } + + switch (td->GuardInterval) { + case 0: + fep->guard_interval = GUARD_INTERVAL_1_32; + break; + case 1: + fep->guard_interval = GUARD_INTERVAL_1_16; + break; + case 2: + fep->guard_interval = GUARD_INTERVAL_1_8; + break; + case 3: + fep->guard_interval = GUARD_INTERVAL_1_4; + break; + } + + switch (td->CodeRate) { + case 0: + fep->code_rate_HP = FEC_1_2; + break; + case 1: + fep->code_rate_HP = FEC_2_3; + break; + case 2: + fep->code_rate_HP = FEC_3_4; + break; + case 3: + fep->code_rate_HP = FEC_5_6; + break; + case 4: + fep->code_rate_HP = FEC_7_8; + break; + } + + switch (td->LPCodeRate) { + case 0: + fep->code_rate_LP = FEC_1_2; + break; + case 1: + fep->code_rate_LP = FEC_2_3; + break; + case 2: + fep->code_rate_LP = FEC_3_4; + break; + case 3: + fep->code_rate_LP = FEC_5_6; + break; + case 4: + fep->code_rate_LP = FEC_7_8; + break; + } + + switch (td->Constellation) { + case 0: + fep->modulation = QPSK; + break; + case 1: + fep->modulation = QAM_16; + break; + case 2: + fep->modulation = QAM_64; + break; + } + + switch (td->Hierarchy) { + case 0: + fep->hierarchy = HIERARCHY_NONE; + break; + case 1: + fep->hierarchy = HIERARCHY_1; + break; + case 2: + fep->hierarchy = HIERARCHY_2; + break; + case 3: + fep->hierarchy = HIERARCHY_4; + break; + } - /* todo: */ - memcpy(fep, &client->fe_params, - sizeof(struct dtv_frontend_properties)); + fep->inversion = INVERSION_AUTO; + break; + case DEVICE_MODE_ISDBT: + case DEVICE_MODE_ISDBT_BDA: + fep->frequency = td->Frequency; + fep->bandwidth_hz = 6000000; + /* todo: retrive the other parameters */ + break; + default: + return -EINVAL; + } return 0; } @@ -872,11 +981,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, switch (smscore_get_device_mode(coredev)) { case DEVICE_MODE_DVBT: case DEVICE_MODE_DVBT_BDA: - smsdvb_fe_ops.delsys[0] = SYS_DVBT; + client->frontend.ops.delsys[0] = SYS_DVBT; break; case DEVICE_MODE_ISDBT: case DEVICE_MODE_ISDBT_BDA: - smsdvb_fe_ops.delsys[0] = SYS_ISDBT; + client->frontend.ops.delsys[0] = SYS_ISDBT; break; } diff --git a/drivers/media/video/davinci/isif.c b/drivers/media/video/davinci/isif.c index 1e63852374be..5278fe7d6d0c 100644 --- a/drivers/media/video/davinci/isif.c +++ b/drivers/media/video/davinci/isif.c @@ -34,6 +34,7 @@ #include <linux/videodev2.h> #include <linux/clk.h> #include <linux/err.h> +#include <linux/module.h> #include <mach/mux.h> diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index c7e69b8f81c9..4a44f9a1bae0 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -611,9 +611,11 @@ void uvc_video_clock_update(struct uvc_streaming *stream, delta_stc = buf->pts - (1UL << 31); x1 = first->dev_stc - delta_stc; x2 = last->dev_stc - delta_stc; + if (x1 == x2) + goto done; + y1 = (first->dev_sof + 2048) << 16; y2 = (last->dev_sof + 2048) << 16; - if (y2 < y1) y2 += 2048 << 16; @@ -631,14 +633,16 @@ void uvc_video_clock_update(struct uvc_streaming *stream, x1, x2, y1, y2, clock->sof_offset); /* Second step, SOF to host clock conversion. */ - ts = timespec_sub(last->host_ts, first->host_ts); x1 = (uvc_video_clock_host_sof(first) + 2048) << 16; x2 = (uvc_video_clock_host_sof(last) + 2048) << 16; - y1 = NSEC_PER_SEC; - y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec; - if (x2 < x1) x2 += 2048 << 16; + if (x1 == x2) + goto done; + + ts = timespec_sub(last->host_ts, first->host_ts); + y1 = NSEC_PER_SEC; + y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec; /* Interpolated and host SOF timestamps can wrap around at slightly * different times. Handle this by adding or removing 2048 to or from diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 8a7982e18e4e..86f26a1ede4c 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -741,16 +741,14 @@ static int pcan_usb_encode_msg(struct peak_usb_device *dev, struct sk_buff *skb, /* can id */ if (cf->can_id & CAN_EFF_FLAG) { - __le32 tmp32 = cpu_to_le32(cf->can_id & CAN_ERR_MASK); + __le32 tmp32 = cpu_to_le32((cf->can_id & CAN_ERR_MASK) << 3); - tmp32 <<= 3; *pc |= PCAN_USB_STATUSLEN_EXT_ID; memcpy(++pc, &tmp32, 4); pc += 4; } else { - __le16 tmp16 = cpu_to_le32(cf->can_id & CAN_ERR_MASK); + __le16 tmp16 = cpu_to_le16((cf->can_id & CAN_ERR_MASK) << 5); - tmp16 <<= 5; memcpy(++pc, &tmp16, 2); pc += 2; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index c11e50d328c4..b814f4eaed19 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1992,7 +1992,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } if (bp->port.pmf) - bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); + bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0); else bnx2x__link_status_update(bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index cc02ae51a30d..5904b1b1dad4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -1181,10 +1181,16 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, */ static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp) { - if (!CHIP_IS_E1x(fp->bp)) + struct bnx2x *bp = fp->bp; + if (!CHIP_IS_E1x(bp)) { +#ifdef BCM_CNIC + /* there are special statistics counters for FCoE 136..140 */ + if (IS_FCOE_FP(fp)) + return bp->cnic_base_cl_id + (bp->pf_num >> 1); +#endif return fp->cl_id; - else - return fp->cl_id + BP_PORT(fp->bp) * FP_SB_MAX_E1x; + } + return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x; } static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 9a4ed05bb30a..4446a42e8bdc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c @@ -735,7 +735,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) bp->dcbx_error); /* mark DCBX result for PMF migration */ - bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 1); + bnx2x_update_drv_flags(bp, + 1 << DRV_FLAGS_DCB_CONFIGURED, + 1); #ifdef BCM_DCBNL /* * Add new app tlvs to dcbnl @@ -1020,7 +1022,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp) DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", dcbx_lldp_params_offset); - bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); + bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0); if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { bnx2x_dcbx_admin_mib_updated_params(bp, @@ -1857,7 +1859,7 @@ void bnx2x_dcbx_pmf_update(struct bnx2x *bp) * read it from shmem and update bp and netdev accordingly */ if (SHMEM2_HAS(bp, drv_flags) && - GET_FLAGS(SHMEM2_RD(bp, drv_flags), DRV_FLAGS_DCB_CONFIGURED)) { + GET_FLAGS(SHMEM2_RD(bp, drv_flags), 1 << DRV_FLAGS_DCB_CONFIGURED)) { /* Read neg results if dcbx is in the FW */ if (bnx2x_dcbx_read_shmem_neg_results(bp)) return; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index bf14a08f0796..a743a5fcb22c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10907,38 +10907,36 @@ do { \ int bnx2x_init_firmware(struct bnx2x *bp) { + const char *fw_file_name; struct bnx2x_fw_file_hdr *fw_hdr; int rc; + if (bp->firmware) + return 0; - if (!bp->firmware) { - const char *fw_file_name; - - if (CHIP_IS_E1(bp)) - fw_file_name = FW_FILE_NAME_E1; - else if (CHIP_IS_E1H(bp)) - fw_file_name = FW_FILE_NAME_E1H; - else if (!CHIP_IS_E1x(bp)) - fw_file_name = FW_FILE_NAME_E2; - else { - BNX2X_ERR("Unsupported chip revision\n"); - return -EINVAL; - } - BNX2X_DEV_INFO("Loading %s\n", fw_file_name); + if (CHIP_IS_E1(bp)) + fw_file_name = FW_FILE_NAME_E1; + else if (CHIP_IS_E1H(bp)) + fw_file_name = FW_FILE_NAME_E1H; + else if (!CHIP_IS_E1x(bp)) + fw_file_name = FW_FILE_NAME_E2; + else { + BNX2X_ERR("Unsupported chip revision\n"); + return -EINVAL; + } + BNX2X_DEV_INFO("Loading %s\n", fw_file_name); - rc = request_firmware(&bp->firmware, fw_file_name, - &bp->pdev->dev); - if (rc) { - BNX2X_ERR("Can't load firmware file %s\n", - fw_file_name); - goto request_firmware_exit; - } + rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); + if (rc) { + BNX2X_ERR("Can't load firmware file %s\n", + fw_file_name); + goto request_firmware_exit; + } - rc = bnx2x_check_firmware(bp); - if (rc) { - BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); - goto request_firmware_exit; - } + rc = bnx2x_check_firmware(bp); + if (rc) { + BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); + goto request_firmware_exit; } fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; @@ -10984,6 +10982,7 @@ init_ops_alloc_err: kfree(bp->init_data); request_firmware_exit: release_firmware(bp->firmware); + bp->firmware = NULL; return rc; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 1999fa58704d..484498f6bf1e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -5591,7 +5591,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, /* Fill the ramrod data with provided parameters */ rdata->function_mode = cpu_to_le16(start_params->mf_mode); - rdata->sd_vlan_tag = start_params->sd_vlan_tag; + rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); rdata->path_id = BP_PATH(bp); rdata->network_cos_mode = start_params->network_cos_mode; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 14c961beaadb..4cd4f127fe79 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -554,23 +554,11 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl); /* collect PFC stats */ - DIFF_64(diff.hi, new->tx_stat_gtpp_hi, - pstats->pfc_frames_tx_hi, - diff.lo, new->tx_stat_gtpp_lo, - pstats->pfc_frames_tx_lo); pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi; pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo; - ADD_64(pstats->pfc_frames_tx_hi, diff.hi, - pstats->pfc_frames_tx_lo, diff.lo); - DIFF_64(diff.hi, new->rx_stat_grpp_hi, - pstats->pfc_frames_rx_hi, - diff.lo, new->rx_stat_grpp_lo, - pstats->pfc_frames_rx_lo); pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi; pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo; - ADD_64(pstats->pfc_frames_rx_hi, diff.hi, - pstats->pfc_frames_rx_lo, diff.lo); } estats->pause_frames_received_hi = diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index 83e0ed757e33..5fd620bec15c 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c @@ -564,6 +564,6 @@ static struct platform_driver gianfar_ptp_driver = { module_platform_driver(gianfar_ptp_driver); -MODULE_AUTHOR("Richard Cochran <[email protected]>"); +MODULE_AUTHOR("Richard Cochran <[email protected]>"); MODULE_DESCRIPTION("PTP clock using the eTSEC"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index aed217449f0d..89eb1f85b9fa 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h @@ -134,6 +134,8 @@ #define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ #define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ #define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ +#define E1000_RCTL_DPF 0x00400000 /* Discard Pause Frames */ +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ #define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ /* diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index e96cef89f121..c4902411d749 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1769,10 +1769,21 @@ static int igb_set_features(struct net_device *netdev, netdev_features_t features) { netdev_features_t changed = netdev->features ^ features; + struct igb_adapter *adapter = netdev_priv(netdev); if (changed & NETIF_F_HW_VLAN_RX) igb_vlan_mode(netdev, features); + if (!(changed & NETIF_F_RXALL)) + return 0; + + netdev->features = features; + + if (netif_running(netdev)) + igb_reinit_locked(adapter); + else + igb_reset(adapter); + return 0; } @@ -1954,6 +1965,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, /* copy netdev features into list of user selectable features */ netdev->hw_features |= netdev->features; + netdev->hw_features |= NETIF_F_RXALL; /* set this bit last since it cannot be part of hw_features */ netdev->features |= NETIF_F_HW_VLAN_FILTER; @@ -1964,6 +1976,8 @@ static int __devinit igb_probe(struct pci_dev *pdev, NETIF_F_IPV6_CSUM | NETIF_F_SG; + netdev->priv_flags |= IFF_SUPP_NOFCS; + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; netdev->vlan_features |= NETIF_F_HIGHDMA; @@ -3003,6 +3017,22 @@ void igb_setup_rctl(struct igb_adapter *adapter) wr32(E1000_QDE, ALL_QUEUES); } + /* This is useful for sniffing bad packets. */ + if (adapter->netdev->features & NETIF_F_RXALL) { + /* UPE and MPE will be handled by normal PROMISC logic + * in e1000e_set_rx_mode */ + rctl |= (E1000_RCTL_SBP | /* Receive bad packets */ + E1000_RCTL_BAM | /* RX All Bcast Pkts */ + E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */ + + rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */ + E1000_RCTL_DPF | /* Allow filtered pause */ + E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */ + /* Do not mess with E1000_CTRL_VME, it affects transmit as well, + * and that breaks VLANs. + */ + } + wr32(E1000_RCTL, rctl); } @@ -4293,6 +4323,8 @@ static void igb_tx_map(struct igb_ring *tx_ring, /* write last descriptor with RS and EOP bits */ cmd_type |= cpu_to_le32(size) | cpu_to_le32(IGB_TXD_DCMD); + if (unlikely(skb->no_fcs)) + cmd_type &= ~(cpu_to_le32(E1000_ADVTXD_DCMD_IFCS)); tx_desc->read.cmd_type_len = cmd_type; /* set the timestamp */ @@ -6098,8 +6130,9 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget) goto next_desc; } - if (igb_test_staterr(rx_desc, - E1000_RXDEXT_ERR_FRAME_ERR_MASK)) { + if (unlikely((igb_test_staterr(rx_desc, + E1000_RXDEXT_ERR_FRAME_ERR_MASK)) + && !(rx_ring->netdev->features & NETIF_F_RXALL))) { dev_kfree_skb_any(skb); goto next_desc; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index f069c1b10753..e0d809d0ed75 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -72,12 +72,6 @@ /* Supported Rx Buffer Sizes */ #define IXGBE_RXBUFFER_512 512 /* Used for packet split */ -#define IXGBE_RXBUFFER_2K 2048 -#define IXGBE_RXBUFFER_3K 3072 -#define IXGBE_RXBUFFER_4K 4096 -#define IXGBE_RXBUFFER_7K 7168 -#define IXGBE_RXBUFFER_8K 8192 -#define IXGBE_RXBUFFER_15K 15360 #define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */ /* @@ -102,7 +96,6 @@ #define IXGBE_TX_FLAGS_FCOE (u32)(1 << 5) #define IXGBE_TX_FLAGS_FSO (u32)(1 << 6) #define IXGBE_TX_FLAGS_TXSW (u32)(1 << 7) -#define IXGBE_TX_FLAGS_MAPPED_AS_PAGE (u32)(1 << 8) #define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000 #define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT 29 @@ -156,19 +149,18 @@ struct vf_macvlans { struct ixgbe_tx_buffer { union ixgbe_adv_tx_desc *next_to_watch; unsigned long time_stamp; - dma_addr_t dma; - u32 length; - u32 tx_flags; struct sk_buff *skb; - u32 bytecount; - u16 gso_segs; + unsigned int bytecount; + unsigned short gso_segs; + DEFINE_DMA_UNMAP_ADDR(dma); + DEFINE_DMA_UNMAP_LEN(len); + u32 tx_flags; }; struct ixgbe_rx_buffer { struct sk_buff *skb; dma_addr_t dma; struct page *page; - dma_addr_t page_dma; unsigned int page_offset; }; @@ -180,7 +172,6 @@ struct ixgbe_queue_stats { struct ixgbe_tx_queue_stats { u64 restart_queue; u64 tx_busy; - u64 completed; u64 tx_done_old; }; @@ -193,21 +184,15 @@ struct ixgbe_rx_queue_stats { u64 csum_err; }; -enum ixbge_ring_state_t { +enum ixgbe_ring_state_t { __IXGBE_TX_FDIR_INIT_DONE, __IXGBE_TX_DETECT_HANG, __IXGBE_HANG_CHECK_ARMED, - __IXGBE_RX_PS_ENABLED, __IXGBE_RX_RSC_ENABLED, __IXGBE_RX_CSUM_UDP_ZERO_ERR, + __IXGBE_RX_FCOE_BUFSZ, }; -#define ring_is_ps_enabled(ring) \ - test_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) -#define set_ring_ps_enabled(ring) \ - set_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) -#define clear_ring_ps_enabled(ring) \ - clear_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) #define check_for_tx_hang(ring) \ test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) #define set_check_for_tx_hang(ring) \ @@ -233,7 +218,6 @@ struct ixgbe_ring { u8 __iomem *tail; u16 count; /* amount of descriptors */ - u16 rx_buf_len; u8 queue_index; /* needed for multiqueue queue management */ u8 reg_idx; /* holds the special value that gets @@ -241,8 +225,13 @@ struct ixgbe_ring { * associated with this ring, which is * different for DCB and RSS modes */ - u8 atr_sample_rate; - u8 atr_count; + union { + struct { + u8 atr_sample_rate; + u8 atr_count; + }; + u16 next_to_alloc; + }; u16 next_to_use; u16 next_to_clean; @@ -287,6 +276,22 @@ struct ixgbe_ring_feature { int mask; } ____cacheline_internodealigned_in_smp; +/* + * FCoE requires that all Rx buffers be over 2200 bytes in length. Since + * this is twice the size of a half page we need to double the page order + * for FCoE enabled Rx queues. + */ +#if defined(IXGBE_FCOE) && (PAGE_SIZE < 8192) +static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring *ring) +{ + return test_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state) ? 1 : 0; +} +#else +#define ixgbe_rx_pg_order(_ring) 0 +#endif +#define ixgbe_rx_pg_size(_ring) (PAGE_SIZE << ixgbe_rx_pg_order(_ring)) +#define ixgbe_rx_bufsz(_ring) ((PAGE_SIZE / 2) << ixgbe_rx_pg_order(_ring)) + struct ixgbe_ring_container { struct ixgbe_ring *ring; /* pointer to linked list of rings */ unsigned int total_bytes; /* total bytes processed this int */ @@ -554,7 +559,7 @@ struct ixgbe_cb { }; dma_addr_t dma; u16 append_cnt; - bool delay_unmap; + bool page_released; }; #define IXGBE_CB(skb) ((struct ixgbe_cb *)(skb)->cb) @@ -625,7 +630,8 @@ extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32); extern void ixgbe_do_reset(struct net_device *netdev); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); -extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, +extern int ixgbe_fso(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first, u32 tx_flags, u8 *hdr_len); extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 24f7291dbe57..b09e67cc9d6e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -35,6 +35,7 @@ #include <linux/netdevice.h> #include <linux/ethtool.h> #include <linux/vmalloc.h> +#include <linux/highmem.h> #include <linux/uaccess.h> #include "ixgbe.h" @@ -1615,7 +1616,6 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) rx_ring->dev = &adapter->pdev->dev; rx_ring->netdev = adapter->netdev; rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx; - rx_ring->rx_buf_len = IXGBE_RXBUFFER_2K; err = ixgbe_setup_rx_resources(rx_ring); if (err) { @@ -1718,13 +1718,15 @@ static bool ixgbe_check_lbtest_frame(struct ixgbe_rx_buffer *rx_buffer, frame_size >>= 1; - data = rx_buffer->skb->data; + data = kmap(rx_buffer->page) + rx_buffer->page_offset; if (data[3] != 0xFF || data[frame_size + 10] != 0xBE || data[frame_size + 12] != 0xAF) match = false; + kunmap(rx_buffer->page); + return match; } @@ -1746,17 +1748,22 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, /* check Rx buffer */ rx_buffer = &rx_ring->rx_buffer_info[rx_ntc]; - /* unmap Rx buffer, will be remapped by alloc_rx_buffers */ - dma_unmap_single(rx_ring->dev, - rx_buffer->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - rx_buffer->dma = 0; + /* sync Rx buffer for CPU read */ + dma_sync_single_for_cpu(rx_ring->dev, + rx_buffer->dma, + ixgbe_rx_bufsz(rx_ring), + DMA_FROM_DEVICE); /* verify contents of skb */ if (ixgbe_check_lbtest_frame(rx_buffer, size)) count++; + /* sync Rx buffer for device write */ + dma_sync_single_for_device(rx_ring->dev, + rx_buffer->dma, + ixgbe_rx_bufsz(rx_ring), + DMA_FROM_DEVICE); + /* unmap buffer on Tx side */ tx_buffer = &tx_ring->tx_buffer_info[tx_ntc]; ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index da7da752b6b4..5f943d3f85c4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -447,7 +447,7 @@ ddp_out: /** * ixgbe_fso - ixgbe FCoE Sequence Offload (FSO) * @tx_ring: tx desc ring - * @skb: associated skb + * @first: first tx_buffer structure containing skb, tx_flags, and protocol * @tx_flags: tx flags * @hdr_len: hdr_len to be returned * @@ -455,9 +455,11 @@ ddp_out: * * Returns : 0 indicates no FSO, > 0 for FSO, < 0 for error */ -int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, +int ixgbe_fso(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first, u32 tx_flags, u8 *hdr_len) { + struct sk_buff *skb = first->skb; struct fc_frame_header *fh; u32 vlan_macip_lens; u32 fcoe_sof_eof = 0; @@ -530,9 +532,14 @@ int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, *hdr_len = sizeof(struct fcoe_crc_eof); /* hdr_len includes fc_hdr if FCoE LSO is enabled */ - if (skb_is_gso(skb)) - *hdr_len += (skb_transport_offset(skb) + - sizeof(struct fc_frame_header)); + if (skb_is_gso(skb)) { + *hdr_len += skb_transport_offset(skb) + + sizeof(struct fc_frame_header); + /* update gso_segs and bytecount */ + first->gso_segs = DIV_ROUND_UP(skb->len - *hdr_len, + skb_shinfo(skb)->gso_size); + first->bytecount += (first->gso_segs - 1) * *hdr_len; + } /* mss_l4len_id: use 1 for FSO as TSO, no need for L4LEN */ mss_l4len_idx = skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 167e898fbba6..1d8f9f83f8ed 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -289,7 +289,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) struct ixgbe_reg_info *reginfo; int n = 0; struct ixgbe_ring *tx_ring; - struct ixgbe_tx_buffer *tx_buffer_info; + struct ixgbe_tx_buffer *tx_buffer; union ixgbe_adv_tx_desc *tx_desc; struct my_u0 { u64 a; u64 b; } *u0; struct ixgbe_ring *rx_ring; @@ -329,14 +329,13 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); for (n = 0; n < adapter->num_tx_queues; n++) { tx_ring = adapter->tx_ring[n]; - tx_buffer_info = - &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; + tx_buffer = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; pr_info(" %5d %5X %5X %016llX %04X %p %016llX\n", n, tx_ring->next_to_use, tx_ring->next_to_clean, - (u64)tx_buffer_info->dma, - tx_buffer_info->length, - tx_buffer_info->next_to_watch, - (u64)tx_buffer_info->time_stamp); + (u64)dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + tx_buffer->next_to_watch, + (u64)tx_buffer->time_stamp); } /* Print TX Rings */ @@ -367,17 +366,17 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { tx_desc = IXGBE_TX_DESC(tx_ring, i); - tx_buffer_info = &tx_ring->tx_buffer_info[i]; + tx_buffer = &tx_ring->tx_buffer_info[i]; u0 = (struct my_u0 *)tx_desc; pr_info("T [0x%03X] %016llX %016llX %016llX" " %04X %p %016llX %p", i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), - (u64)tx_buffer_info->dma, - tx_buffer_info->length, - tx_buffer_info->next_to_watch, - (u64)tx_buffer_info->time_stamp, - tx_buffer_info->skb); + (u64)dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + tx_buffer->next_to_watch, + (u64)tx_buffer->time_stamp, + tx_buffer->skb); if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) pr_cont(" NTC/U\n"); @@ -389,11 +388,13 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) pr_cont("\n"); if (netif_msg_pktdata(adapter) && - tx_buffer_info->dma != 0) + dma_unmap_len(tx_buffer, len) != 0) print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, - phys_to_virt(tx_buffer_info->dma), - tx_buffer_info->length, true); + phys_to_virt(dma_unmap_addr(tx_buffer, + dma)), + dma_unmap_len(tx_buffer, len), + true); } } @@ -469,17 +470,7 @@ rx_ring_summary: print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 1, phys_to_virt(rx_buffer_info->dma), - rx_ring->rx_buf_len, true); - - if (rx_ring->rx_buf_len - < IXGBE_RXBUFFER_2K) - print_hex_dump(KERN_INFO, "", - DUMP_PREFIX_ADDRESS, 16, 1, - phys_to_virt( - rx_buffer_info->page_dma + - rx_buffer_info->page_offset - ), - PAGE_SIZE/2, true); + ixgbe_rx_bufsz(rx_ring), true); } } @@ -589,32 +580,26 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, } } -static inline void ixgbe_unmap_tx_resource(struct ixgbe_ring *ring, - struct ixgbe_tx_buffer *tx_buffer) +void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *ring, + struct ixgbe_tx_buffer *tx_buffer) { - if (tx_buffer->dma) { - if (tx_buffer->tx_flags & IXGBE_TX_FLAGS_MAPPED_AS_PAGE) - dma_unmap_page(ring->dev, - tx_buffer->dma, - tx_buffer->length, - DMA_TO_DEVICE); - else + if (tx_buffer->skb) { + dev_kfree_skb_any(tx_buffer->skb); + if (dma_unmap_len(tx_buffer, len)) dma_unmap_single(ring->dev, - tx_buffer->dma, - tx_buffer->length, - DMA_TO_DEVICE); + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + } else if (dma_unmap_len(tx_buffer, len)) { + dma_unmap_page(ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); } - tx_buffer->dma = 0; -} - -void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, - struct ixgbe_tx_buffer *tx_buffer_info) -{ - ixgbe_unmap_tx_resource(tx_ring, tx_buffer_info); - if (tx_buffer_info->skb) - dev_kfree_skb_any(tx_buffer_info->skb); - tx_buffer_info->skb = NULL; - /* tx_buffer_info must be completely set up in the transmit path */ + tx_buffer->next_to_watch = NULL; + tx_buffer->skb = NULL; + dma_unmap_len_set(tx_buffer, len, 0); + /* tx_buffer must be completely set up in the transmit path */ } static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) @@ -671,7 +656,7 @@ static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) static u64 ixgbe_get_tx_completed(struct ixgbe_ring *ring) { - return ring->tx_stats.completed; + return ring->stats.packets; } static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring) @@ -751,12 +736,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, union ixgbe_adv_tx_desc *tx_desc; unsigned int total_bytes = 0, total_packets = 0; unsigned int budget = q_vector->tx.work_limit; - u16 i = tx_ring->next_to_clean; + unsigned int i = tx_ring->next_to_clean; + + if (test_bit(__IXGBE_DOWN, &adapter->state)) + return true; tx_buffer = &tx_ring->tx_buffer_info[i]; tx_desc = IXGBE_TX_DESC(tx_ring, i); + i -= tx_ring->count; - for (; budget; budget--) { + do { union ixgbe_adv_tx_desc *eop_desc = tx_buffer->next_to_watch; /* if next_to_watch is not set then there is no work pending */ @@ -770,36 +759,65 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD))) break; - /* count the packet as being completed */ - tx_ring->tx_stats.completed++; - /* clear next_to_watch to prevent false hangs */ tx_buffer->next_to_watch = NULL; - do { - ixgbe_unmap_tx_resource(tx_ring, tx_buffer); - if (likely(tx_desc == eop_desc)) { - eop_desc = NULL; - dev_kfree_skb_any(tx_buffer->skb); - tx_buffer->skb = NULL; + /* update the statistics for this packet */ + total_bytes += tx_buffer->bytecount; + total_packets += tx_buffer->gso_segs; - total_bytes += tx_buffer->bytecount; - total_packets += tx_buffer->gso_segs; - } + /* free the skb */ + dev_kfree_skb_any(tx_buffer->skb); + + /* unmap skb header data */ + dma_unmap_single(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + /* clear tx_buffer data */ + tx_buffer->skb = NULL; + dma_unmap_len_set(tx_buffer, len, 0); + + /* unmap remaining buffers */ + while (tx_desc != eop_desc) { tx_buffer++; tx_desc++; i++; - if (unlikely(i == tx_ring->count)) { - i = 0; - + if (unlikely(!i)) { + i -= tx_ring->count; tx_buffer = tx_ring->tx_buffer_info; tx_desc = IXGBE_TX_DESC(tx_ring, 0); } - } while (eop_desc); - } + /* unmap any remaining paged data */ + if (dma_unmap_len(tx_buffer, len)) { + dma_unmap_page(tx_ring->dev, + dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + DMA_TO_DEVICE); + dma_unmap_len_set(tx_buffer, len, 0); + } + } + + /* move us one more past the eop_desc for start of next pkt */ + tx_buffer++; + tx_desc++; + i++; + if (unlikely(!i)) { + i -= tx_ring->count; + tx_buffer = tx_ring->tx_buffer_info; + tx_desc = IXGBE_TX_DESC(tx_ring, 0); + } + /* issue prefetch for next Tx descriptor */ + prefetch(tx_desc); + + /* update budget accounting */ + budget--; + } while (likely(budget)); + + i += tx_ring->count; tx_ring->next_to_clean = i; u64_stats_update_begin(&tx_ring->syncp); tx_ring->stats.bytes += total_bytes; @@ -811,7 +829,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) { /* schedule immediate reset if we believe we hung */ struct ixgbe_hw *hw = &adapter->hw; - tx_desc = IXGBE_TX_DESC(tx_ring, i); e_err(drv, "Detected Tx Unit Hang\n" " Tx Queue <%d>\n" " TDH, TDT <%x>, <%x>\n" @@ -849,9 +866,11 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, * sees the new next_to_clean. */ smp_mb(); - if (__netif_subqueue_stopped(tx_ring->netdev, tx_ring->queue_index) && - !test_bit(__IXGBE_DOWN, &adapter->state)) { - netif_wake_subqueue(tx_ring->netdev, tx_ring->queue_index); + if (__netif_subqueue_stopped(tx_ring->netdev, + tx_ring->queue_index) + && !test_bit(__IXGBE_DOWN, &adapter->state)) { + netif_wake_subqueue(tx_ring->netdev, + tx_ring->queue_index); ++tx_ring->tx_stats.restart_queue; } } @@ -1006,6 +1025,7 @@ static inline void ixgbe_rx_hash(struct ixgbe_ring *ring, skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); } +#ifdef IXGBE_FCOE /** * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type * @adapter: address of board private structure @@ -1024,6 +1044,7 @@ static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); } +#endif /* IXGBE_FCOE */ /** * ixgbe_rx_checksum - indicate in skb if hw indicated a good cksum * @ring: structure containing ring specific data @@ -1051,7 +1072,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring, return; if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) { - u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; /* * 82599 errata, UDP frames with a 0 checksum can be marked as @@ -1072,6 +1093,9 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring, static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) { rx_ring->next_to_use = val; + + /* update next to alloc since we have filled the ring */ + rx_ring->next_to_alloc = val; /* * Force memory writes to complete before letting h/w * know there are new descriptors to fetch. (Only @@ -1082,67 +1106,46 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) writel(val, rx_ring->tail); } -static bool ixgbe_alloc_mapped_skb(struct ixgbe_ring *rx_ring, - struct ixgbe_rx_buffer *bi) -{ - struct sk_buff *skb = bi->skb; - dma_addr_t dma = bi->dma; - - if (dma) - return true; - - if (likely(!skb)) { - skb = netdev_alloc_skb_ip_align(rx_ring->netdev, - rx_ring->rx_buf_len); - bi->skb = skb; - if (!skb) { - rx_ring->rx_stats.alloc_rx_buff_failed++; - return false; - } - } - - dma = dma_map_single(rx_ring->dev, skb->data, - rx_ring->rx_buf_len, DMA_FROM_DEVICE); - - if (dma_mapping_error(rx_ring->dev, dma)) { - rx_ring->rx_stats.alloc_rx_buff_failed++; - return false; - } - - bi->dma = dma; - return true; -} - static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, struct ixgbe_rx_buffer *bi) { struct page *page = bi->page; - dma_addr_t page_dma = bi->page_dma; - unsigned int page_offset = bi->page_offset ^ (PAGE_SIZE / 2); + dma_addr_t dma = bi->dma; - if (page_dma) + /* since we are recycling buffers we should seldom need to alloc */ + if (likely(dma)) return true; - if (!page) { - page = alloc_page(GFP_ATOMIC | __GFP_COLD); - bi->page = page; + /* alloc new page for storage */ + if (likely(!page)) { + page = alloc_pages(GFP_ATOMIC | __GFP_COLD, + ixgbe_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_rx_page_failed++; return false; } + bi->page = page; } - page_dma = dma_map_page(rx_ring->dev, page, - page_offset, PAGE_SIZE / 2, - DMA_FROM_DEVICE); + /* map page for use */ + dma = dma_map_page(rx_ring->dev, page, 0, + ixgbe_rx_pg_size(rx_ring), DMA_FROM_DEVICE); + + /* + * if mapping failed free memory back to system since + * there isn't much point in holding memory we can't use + */ + if (dma_mapping_error(rx_ring->dev, dma)) { + put_page(page); + bi->page = NULL; - if (dma_mapping_error(rx_ring->dev, page_dma)) { rx_ring->rx_stats.alloc_rx_page_failed++; return false; } - bi->page_dma = page_dma; - bi->page_offset = page_offset; + bi->dma = dma; + bi->page_offset ^= ixgbe_rx_bufsz(rx_ring); + return true; } @@ -1157,30 +1160,23 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) struct ixgbe_rx_buffer *bi; u16 i = rx_ring->next_to_use; - /* nothing to do or no valid netdev defined */ - if (!cleaned_count || !rx_ring->netdev) + /* nothing to do */ + if (!cleaned_count) return; rx_desc = IXGBE_RX_DESC(rx_ring, i); bi = &rx_ring->rx_buffer_info[i]; i -= rx_ring->count; - while (cleaned_count--) { - if (!ixgbe_alloc_mapped_skb(rx_ring, bi)) + do { + if (!ixgbe_alloc_mapped_page(rx_ring, bi)) break; - /* Refresh the desc even if buffer_addrs didn't change - * because each write-back erases this info. */ - if (ring_is_ps_enabled(rx_ring)) { - rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); - - if (!ixgbe_alloc_mapped_page(rx_ring, bi)) - break; - - rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma); - } else { - rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); - } + /* + * Refresh the desc even if buffer_addrs didn't change + * because each write-back erases this info. + */ + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset); rx_desc++; bi++; @@ -1193,7 +1189,9 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) /* clear the hdr_addr for the next_to_use descriptor */ rx_desc->read.hdr_addr = 0; - } + + cleaned_count--; + } while (cleaned_count); i += rx_ring->count; @@ -1201,90 +1199,6 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) ixgbe_release_rx_desc(rx_ring, i); } -static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc) -{ - /* HW will not DMA in data larger than the given buffer, even if it - * parses the (NFS, of course) header to be larger. In that case, it - * fills the header buffer and spills the rest into the page. - */ - u16 hdr_info = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info); - u16 hlen = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> - IXGBE_RXDADV_HDRBUFLEN_SHIFT; - if (hlen > IXGBE_RX_HDR_SIZE) - hlen = IXGBE_RX_HDR_SIZE; - return hlen; -} - -/** - * ixgbe_merge_active_tail - merge active tail into lro skb - * @tail: pointer to active tail in frag_list - * - * This function merges the length and data of an active tail into the - * skb containing the frag_list. It resets the tail's pointer to the head, - * but it leaves the heads pointer to tail intact. - **/ -static inline struct sk_buff *ixgbe_merge_active_tail(struct sk_buff *tail) -{ - struct sk_buff *head = IXGBE_CB(tail)->head; - - if (!head) - return tail; - - head->len += tail->len; - head->data_len += tail->len; - head->truesize += tail->len; - - IXGBE_CB(tail)->head = NULL; - - return head; -} - -/** - * ixgbe_add_active_tail - adds an active tail into the skb frag_list - * @head: pointer to the start of the skb - * @tail: pointer to active tail to add to frag_list - * - * This function adds an active tail to the end of the frag list. This tail - * will still be receiving data so we cannot yet ad it's stats to the main - * skb. That is done via ixgbe_merge_active_tail. - **/ -static inline void ixgbe_add_active_tail(struct sk_buff *head, - struct sk_buff *tail) -{ - struct sk_buff *old_tail = IXGBE_CB(head)->tail; - - if (old_tail) { - ixgbe_merge_active_tail(old_tail); - old_tail->next = tail; - } else { - skb_shinfo(head)->frag_list = tail; - } - - IXGBE_CB(tail)->head = head; - IXGBE_CB(head)->tail = tail; -} - -/** - * ixgbe_close_active_frag_list - cleanup pointers on a frag_list skb - * @head: pointer to head of an active frag list - * - * This function will clear the frag_tail_tracker pointer on an active - * frag_list and returns true if the pointer was actually set - **/ -static inline bool ixgbe_close_active_frag_list(struct sk_buff *head) -{ - struct sk_buff *tail = IXGBE_CB(head)->tail; - - if (!tail) - return false; - - ixgbe_merge_active_tail(tail); - - IXGBE_CB(head)->tail = NULL; - - return true; -} - /** * ixgbe_get_headlen - determine size of header for RSC/LRO/GRO/FCOE * @data: pointer to the start of the headers @@ -1346,7 +1260,7 @@ static unsigned int ixgbe_get_headlen(unsigned char *data, /* record next protocol */ nexthdr = hdr.ipv4->protocol; hdr.network += hlen; -#ifdef CONFIG_FCOE +#ifdef IXGBE_FCOE } else if (protocol == __constant_htons(ETH_P_FCOE)) { if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) return max_len; @@ -1409,7 +1323,7 @@ static void ixgbe_get_rsc_cnt(struct ixgbe_ring *rx_ring, static void ixgbe_set_rsc_gso_size(struct ixgbe_ring *ring, struct sk_buff *skb) { - u16 hdr_len = ixgbe_get_headlen(skb->data, skb_headlen(skb)); + u16 hdr_len = skb_headlen(skb); /* set gso_size to avoid messing up TCP MSS */ skb_shinfo(skb)->gso_size = DIV_ROUND_UP((skb->len - hdr_len), @@ -1473,149 +1387,346 @@ static void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector, netif_rx(skb); } +/** + * ixgbe_is_non_eop - process handling of non-EOP buffers + * @rx_ring: Rx ring being processed + * @rx_desc: Rx descriptor for current buffer + * @skb: Current socket buffer containing buffer in progress + * + * This function updates next to clean. If the buffer is an EOP buffer + * this function exits returning false, otherwise it will place the + * sk_buff in the next buffer to be chained and return true indicating + * that this is in fact a non-EOP buffer. + **/ +static bool ixgbe_is_non_eop(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + u32 ntc = rx_ring->next_to_clean + 1; + + /* fetch, update, and store next to clean */ + ntc = (ntc < rx_ring->count) ? ntc : 0; + rx_ring->next_to_clean = ntc; + + prefetch(IXGBE_RX_DESC(rx_ring, ntc)); + + if (likely(ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) + return false; + + /* append_cnt indicates packet is RSC, if so fetch nextp */ + if (IXGBE_CB(skb)->append_cnt) { + ntc = le32_to_cpu(rx_desc->wb.upper.status_error); + ntc &= IXGBE_RXDADV_NEXTP_MASK; + ntc >>= IXGBE_RXDADV_NEXTP_SHIFT; + } + + /* place skb in next buffer to be received */ + rx_ring->rx_buffer_info[ntc].skb = skb; + rx_ring->rx_stats.non_eop_descs++; + + return true; +} + +/** + * ixgbe_cleanup_headers - Correct corrupted or empty headers + * @rx_ring: rx descriptor ring packet is being transacted on + * @rx_desc: pointer to the EOP Rx descriptor + * @skb: pointer to current skb being fixed + * + * Check for corrupted packet headers caused by senders on the local L2 + * embedded NIC switch not setting up their Tx Descriptors right. These + * should be very rare. + * + * Also address the case where we are pulling data in on pages only + * and as such no data is present in the skb header. + * + * In addition if skb is not at least 60 bytes we need to pad it so that + * it is large enough to qualify as a valid Ethernet frame. + * + * Returns true if an error was encountered and skb was freed. + **/ +static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0]; + struct net_device *netdev = rx_ring->netdev; + unsigned char *va; + unsigned int pull_len; + + /* if the page was released unmap it, else just sync our portion */ + if (unlikely(IXGBE_CB(skb)->page_released)) { + dma_unmap_page(rx_ring->dev, IXGBE_CB(skb)->dma, + ixgbe_rx_pg_size(rx_ring), DMA_FROM_DEVICE); + IXGBE_CB(skb)->page_released = false; + } else { + dma_sync_single_range_for_cpu(rx_ring->dev, + IXGBE_CB(skb)->dma, + frag->page_offset, + ixgbe_rx_bufsz(rx_ring), + DMA_FROM_DEVICE); + } + IXGBE_CB(skb)->dma = 0; + + /* verify that the packet does not have any known errors */ + if (unlikely(ixgbe_test_staterr(rx_desc, + IXGBE_RXDADV_ERR_FRAME_ERR_MASK) && + !(netdev->features & NETIF_F_RXALL))) { + dev_kfree_skb_any(skb); + return true; + } + + /* + * it is valid to use page_address instead of kmap since we are + * working with pages allocated out of the lomem pool per + * alloc_page(GFP_ATOMIC) + */ + va = skb_frag_address(frag); + + /* + * we need the header to contain the greater of either ETH_HLEN or + * 60 bytes if the skb->len is less than 60 for skb_pad. + */ + pull_len = skb_frag_size(frag); + if (pull_len > 256) + pull_len = ixgbe_get_headlen(va, pull_len); + + /* align pull length to size of long to optimize memcpy performance */ + skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long))); + + /* update all of the pointers */ + skb_frag_size_sub(frag, pull_len); + frag->page_offset += pull_len; + skb->data_len -= pull_len; + skb->tail += pull_len; + + /* + * if we sucked the frag empty then we should free it, + * if there are other frags here something is screwed up in hardware + */ + if (skb_frag_size(frag) == 0) { + BUG_ON(skb_shinfo(skb)->nr_frags != 1); + skb_shinfo(skb)->nr_frags = 0; + __skb_frag_unref(frag); + skb->truesize -= ixgbe_rx_bufsz(rx_ring); + } + + /* if skb_pad returns an error the skb was freed */ + if (unlikely(skb->len < 60)) { + int pad_len = 60 - skb->len; + + if (skb_pad(skb, pad_len)) + return true; + __skb_put(skb, pad_len); + } + + return false; +} + +/** + * ixgbe_can_reuse_page - determine if we can reuse a page + * @rx_buffer: pointer to rx_buffer containing the page we want to reuse + * + * Returns true if page can be reused in another Rx buffer + **/ +static inline bool ixgbe_can_reuse_page(struct ixgbe_rx_buffer *rx_buffer) +{ + struct page *page = rx_buffer->page; + + /* if we are only owner of page and it is local we can reuse it */ + return likely(page_count(page) == 1) && + likely(page_to_nid(page) == numa_node_id()); +} + +/** + * ixgbe_reuse_rx_page - page flip buffer and store it back on the ring + * @rx_ring: rx descriptor ring to store buffers on + * @old_buff: donor buffer to have page reused + * + * Syncronizes page for reuse by the adapter + **/ +static void ixgbe_reuse_rx_page(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *old_buff) +{ + struct ixgbe_rx_buffer *new_buff; + u16 nta = rx_ring->next_to_alloc; + u16 bufsz = ixgbe_rx_bufsz(rx_ring); + + new_buff = &rx_ring->rx_buffer_info[nta]; + + /* update, and store next to alloc */ + nta++; + rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; + + /* transfer page from old buffer to new buffer */ + new_buff->page = old_buff->page; + new_buff->dma = old_buff->dma; + + /* flip page offset to other buffer and store to new_buff */ + new_buff->page_offset = old_buff->page_offset ^ bufsz; + + /* sync the buffer for use by the device */ + dma_sync_single_range_for_device(rx_ring->dev, new_buff->dma, + new_buff->page_offset, bufsz, + DMA_FROM_DEVICE); + + /* bump ref count on page before it is given to the stack */ + get_page(new_buff->page); +} + +/** + * ixgbe_add_rx_frag - Add contents of Rx buffer to sk_buff + * @rx_ring: rx descriptor ring to transact packets on + * @rx_buffer: buffer containing page to add + * @rx_desc: descriptor containing length of buffer written by hardware + * @skb: sk_buff to place the data into + * + * This function is based on skb_add_rx_frag. I would have used that + * function however it doesn't handle the truesize case correctly since we + * are allocating more memory than might be used for a single receive. + **/ +static void ixgbe_add_rx_frag(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *rx_buffer, + struct sk_buff *skb, int size) +{ + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, + rx_buffer->page, rx_buffer->page_offset, + size); + skb->len += size; + skb->data_len += size; + skb->truesize += ixgbe_rx_bufsz(rx_ring); +} + +/** + * ixgbe_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf + * @q_vector: structure containing interrupt and ring information + * @rx_ring: rx descriptor ring to transact packets on + * @budget: Total limit on number of packets to process + * + * This function provides a "bounce buffer" approach to Rx interrupt + * processing. The advantage to this is that on systems that have + * expensive overhead for IOMMU access this provides a means of avoiding + * it by maintaining the mapping of the page to the syste. + * + * Returns true if all work is completed without reaching budget + **/ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *rx_ring, int budget) { - union ixgbe_adv_rx_desc *rx_desc, *next_rxd; - struct ixgbe_rx_buffer *rx_buffer_info; - struct sk_buff *skb; unsigned int total_rx_bytes = 0, total_rx_packets = 0; - const int current_node = numa_node_id(); #ifdef IXGBE_FCOE struct ixgbe_adapter *adapter = q_vector->adapter; int ddp_bytes = 0; #endif /* IXGBE_FCOE */ - u16 i; - u16 cleaned_count = 0; + u16 cleaned_count = ixgbe_desc_unused(rx_ring); - i = rx_ring->next_to_clean; - rx_desc = IXGBE_RX_DESC(rx_ring, i); + do { + struct ixgbe_rx_buffer *rx_buffer; + union ixgbe_adv_rx_desc *rx_desc; + struct sk_buff *skb; + struct page *page; + u16 ntc; - while (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) { - u32 upper_len = 0; + /* return some buffers to hardware, one at a time is too slow */ + if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { + ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + cleaned_count = 0; + } - rmb(); /* read descriptor and rx_buffer_info after status DD */ + ntc = rx_ring->next_to_clean; + rx_desc = IXGBE_RX_DESC(rx_ring, ntc); + rx_buffer = &rx_ring->rx_buffer_info[ntc]; - rx_buffer_info = &rx_ring->rx_buffer_info[i]; + if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) + break; - skb = rx_buffer_info->skb; - rx_buffer_info->skb = NULL; - prefetch(skb->data); + /* + * This memory barrier is needed to keep us from reading + * any other fields out of the rx_desc until we know the + * RXD_STAT_DD bit is set + */ + rmb(); - /* linear means we are building an skb from multiple pages */ - if (!skb_is_nonlinear(skb)) { - u16 hlen; - if (ring_is_ps_enabled(rx_ring)) { - hlen = ixgbe_get_hlen(rx_desc); - upper_len = le16_to_cpu(rx_desc->wb.upper.length); - } else { - hlen = le16_to_cpu(rx_desc->wb.upper.length); + page = rx_buffer->page; + prefetchw(page); + + skb = rx_buffer->skb; + + if (likely(!skb)) { + void *page_addr = page_address(page) + + rx_buffer->page_offset; + + /* prefetch first cache line of first page */ + prefetch(page_addr); +#if L1_CACHE_BYTES < 128 + prefetch(page_addr + L1_CACHE_BYTES); +#endif + + /* allocate a skb to store the frags */ + skb = netdev_alloc_skb_ip_align(rx_ring->netdev, + IXGBE_RX_HDR_SIZE); + if (unlikely(!skb)) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + break; } - skb_put(skb, hlen); + /* + * we will be copying header into skb->data in + * pskb_may_pull so it is in our interest to prefetch + * it now to avoid a possible cache miss + */ + prefetchw(skb->data); /* * Delay unmapping of the first packet. It carries the * header information, HW may still access the header - * after writeback. Only unmap it when EOP is reached + * after the writeback. Only unmap it when EOP is + * reached */ - if (!IXGBE_CB(skb)->head) { - IXGBE_CB(skb)->delay_unmap = true; - IXGBE_CB(skb)->dma = rx_buffer_info->dma; - } else { - skb = ixgbe_merge_active_tail(skb); - dma_unmap_single(rx_ring->dev, - rx_buffer_info->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - } - rx_buffer_info->dma = 0; + IXGBE_CB(skb)->dma = rx_buffer->dma; } else { - /* assume packet split since header is unmapped */ - upper_len = le16_to_cpu(rx_desc->wb.upper.length); + /* we are reusing so sync this buffer for CPU use */ + dma_sync_single_range_for_cpu(rx_ring->dev, + rx_buffer->dma, + rx_buffer->page_offset, + ixgbe_rx_bufsz(rx_ring), + DMA_FROM_DEVICE); } - if (upper_len) { - dma_unmap_page(rx_ring->dev, - rx_buffer_info->page_dma, - PAGE_SIZE / 2, - DMA_FROM_DEVICE); - rx_buffer_info->page_dma = 0; - skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, - rx_buffer_info->page, - rx_buffer_info->page_offset, - upper_len); - - if ((page_count(rx_buffer_info->page) == 1) && - (page_to_nid(rx_buffer_info->page) == current_node)) - get_page(rx_buffer_info->page); - else - rx_buffer_info->page = NULL; + /* pull page into skb */ + ixgbe_add_rx_frag(rx_ring, rx_buffer, skb, + le16_to_cpu(rx_desc->wb.upper.length)); - skb->len += upper_len; - skb->data_len += upper_len; - skb->truesize += PAGE_SIZE / 2; + if (ixgbe_can_reuse_page(rx_buffer)) { + /* hand second half of page back to the ring */ + ixgbe_reuse_rx_page(rx_ring, rx_buffer); + } else if (IXGBE_CB(skb)->dma == rx_buffer->dma) { + /* the page has been released from the ring */ + IXGBE_CB(skb)->page_released = true; + } else { + /* we are not reusing the buffer so unmap it */ + dma_unmap_page(rx_ring->dev, rx_buffer->dma, + ixgbe_rx_pg_size(rx_ring), + DMA_FROM_DEVICE); } - ixgbe_get_rsc_cnt(rx_ring, rx_desc, skb); + /* clear contents of buffer_info */ + rx_buffer->skb = NULL; + rx_buffer->dma = 0; + rx_buffer->page = NULL; - i++; - if (i == rx_ring->count) - i = 0; + ixgbe_get_rsc_cnt(rx_ring, rx_desc, skb); - next_rxd = IXGBE_RX_DESC(rx_ring, i); - prefetch(next_rxd); cleaned_count++; - if ((!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) { - struct ixgbe_rx_buffer *next_buffer; - u32 nextp; - - if (IXGBE_CB(skb)->append_cnt) { - nextp = le32_to_cpu( - rx_desc->wb.upper.status_error); - nextp >>= IXGBE_RXDADV_NEXTP_SHIFT; - } else { - nextp = i; - } - - next_buffer = &rx_ring->rx_buffer_info[nextp]; - - if (ring_is_ps_enabled(rx_ring)) { - rx_buffer_info->skb = next_buffer->skb; - rx_buffer_info->dma = next_buffer->dma; - next_buffer->skb = skb; - next_buffer->dma = 0; - } else { - struct sk_buff *next_skb = next_buffer->skb; - ixgbe_add_active_tail(skb, next_skb); - IXGBE_CB(next_skb)->head = skb; - } - rx_ring->rx_stats.non_eop_descs++; - goto next_desc; - } - - dma_unmap_single(rx_ring->dev, - IXGBE_CB(skb)->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - IXGBE_CB(skb)->dma = 0; - IXGBE_CB(skb)->delay_unmap = false; - - if (ixgbe_close_active_frag_list(skb) && - !IXGBE_CB(skb)->append_cnt) { - /* if we got here without RSC the packet is invalid */ - dev_kfree_skb_any(skb); - goto next_desc; - } + /* place incomplete frames back on ring for completion */ + if (ixgbe_is_non_eop(rx_ring, rx_desc, skb)) + continue; - /* ERR_MASK will only have valid bits if EOP set */ - if (unlikely(ixgbe_test_staterr(rx_desc, - IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { - dev_kfree_skb_any(skb); - goto next_desc; - } + /* verify the packet layout is correct */ + if (ixgbe_cleanup_headers(rx_ring, rx_desc, skb)) + continue; /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; @@ -1630,32 +1741,16 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); if (!ddp_bytes) { dev_kfree_skb_any(skb); - goto next_desc; + continue; } } + #endif /* IXGBE_FCOE */ ixgbe_rx_skb(q_vector, skb); + /* update budget accounting */ budget--; -next_desc: - if (!budget) - break; - - /* return some buffers to hardware, one at a time is too slow */ - if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { - ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); - cleaned_count = 0; - } - - /* use prefetched values */ - rx_desc = next_rxd; - } - - rx_ring->next_to_clean = i; - cleaned_count = ixgbe_desc_unused(rx_ring); - - if (cleaned_count) - ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + } while (likely(budget)); #ifdef IXGBE_FCOE /* include DDPed FCoE data */ @@ -1670,8 +1765,8 @@ next_desc: total_rx_bytes += ddp_bytes; total_rx_packets += DIV_ROUND_UP(ddp_bytes, mss); } -#endif /* IXGBE_FCOE */ +#endif /* IXGBE_FCOE */ u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets += total_rx_packets; rx_ring->stats.bytes += total_rx_bytes; @@ -1679,6 +1774,9 @@ next_desc: q_vector->rx.total_packets += total_rx_packets; q_vector->rx.total_bytes += total_rx_bytes; + if (cleaned_count) + ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + return !!budget; } @@ -2634,18 +2732,12 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & IXGBE_SRRCTL_BSIZEHDR_MASK; - if (ring_is_ps_enabled(rx_ring)) { -#if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER - srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; +#if PAGE_SIZE > IXGBE_MAX_RXBUFFER + srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; #else - srrctl |= (PAGE_SIZE / 2) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + srrctl |= ixgbe_rx_bufsz(rx_ring) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; #endif - srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS; - } else { - srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >> - IXGBE_SRRCTL_BSIZEPKT_SHIFT; - srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; - } + srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(reg_idx), srrctl); } @@ -2728,13 +2820,11 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, { struct ixgbe_hw *hw = &adapter->hw; u32 rscctrl; - int rx_buf_len; u8 reg_idx = ring->reg_idx; if (!ring_is_rsc_enabled(ring)) return; - rx_buf_len = ring->rx_buf_len; rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); rscctrl |= IXGBE_RSCCTL_RSCEN; /* @@ -2742,24 +2832,13 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, * total size of max desc * buf_len is not greater * than 65536 */ - if (ring_is_ps_enabled(ring)) { -#if (PAGE_SIZE < 8192) - rscctrl |= IXGBE_RSCCTL_MAXDESC_16; -#elif (PAGE_SIZE < 16384) - rscctrl |= IXGBE_RSCCTL_MAXDESC_8; -#elif (PAGE_SIZE < 32768) - rscctrl |= IXGBE_RSCCTL_MAXDESC_4; +#if (PAGE_SIZE <= 8192) + rscctrl |= IXGBE_RSCCTL_MAXDESC_16; +#elif (PAGE_SIZE <= 16384) + rscctrl |= IXGBE_RSCCTL_MAXDESC_8; #else - rscctrl |= IXGBE_RSCCTL_MAXDESC_1; + rscctrl |= IXGBE_RSCCTL_MAXDESC_4; #endif - } else { - if (rx_buf_len <= IXGBE_RXBUFFER_4K) - rscctrl |= IXGBE_RSCCTL_MAXDESC_16; - else if (rx_buf_len <= IXGBE_RXBUFFER_8K) - rscctrl |= IXGBE_RSCCTL_MAXDESC_8; - else - rscctrl |= IXGBE_RSCCTL_MAXDESC_4; - } IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); } @@ -2976,23 +3055,10 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - int rx_buf_len; struct ixgbe_ring *rx_ring; int i; u32 mhadd, hlreg0; - /* Decide whether to use packet split mode or not */ - /* On by default */ - adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; - - /* Do not use packet split if we're in SR-IOV Mode */ - if (adapter->num_vfs) - adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; - - /* Disable packet split due to 82599 erratum #45 */ - if (hw->mac.type == ixgbe_mac_82599EB) - adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; - #ifdef IXGBE_FCOE /* adjust max frame to be able to do baby jumbo for FCoE */ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && @@ -3011,27 +3077,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) /* MHADD will allow an extra 4 bytes past for vlan tagged frames */ max_frame += VLAN_HLEN; - /* Set the RX buffer length according to the mode */ - if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { - rx_buf_len = IXGBE_RX_HDR_SIZE; - } else { - if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && - (netdev->mtu <= ETH_DATA_LEN)) - rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; - /* - * Make best use of allocation by using all but 1K of a - * power of 2 allocation that will be used for skb->head. - */ - else if (max_frame <= IXGBE_RXBUFFER_3K) - rx_buf_len = IXGBE_RXBUFFER_3K; - else if (max_frame <= IXGBE_RXBUFFER_7K) - rx_buf_len = IXGBE_RXBUFFER_7K; - else if (max_frame <= IXGBE_RXBUFFER_15K) - rx_buf_len = IXGBE_RXBUFFER_15K; - else - rx_buf_len = IXGBE_MAX_RXBUFFER; - } - hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); /* set jumbo enable since MHADD.MFS is keeping size locked at max_frame */ hlreg0 |= IXGBE_HLREG0_JUMBOEN; @@ -3043,32 +3088,16 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) */ for (i = 0; i < adapter->num_rx_queues; i++) { rx_ring = adapter->rx_ring[i]; - rx_ring->rx_buf_len = rx_buf_len; - - if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) - set_ring_ps_enabled(rx_ring); - else - clear_ring_ps_enabled(rx_ring); - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) set_ring_rsc_enabled(rx_ring); else clear_ring_rsc_enabled(rx_ring); - #ifdef IXGBE_FCOE if (netdev->features & NETIF_F_FCOE_MTU) { struct ixgbe_ring_feature *f; f = &adapter->ring_feature[RING_F_FCOE]; - if ((i >= f->mask) && (i < f->mask + f->indices)) { - clear_ring_ps_enabled(rx_ring); - if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) - rx_ring->rx_buf_len = - IXGBE_FCOE_JUMBO_FRAME_SIZE; - } else if (!ring_is_rsc_enabled(rx_ring) && - !ring_is_ps_enabled(rx_ring)) { - rx_ring->rx_buf_len = - IXGBE_FCOE_JUMBO_FRAME_SIZE; - } + if ((i >= f->mask) && (i < f->mask + f->indices)) + set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state); } #endif /* IXGBE_FCOE */ } @@ -3342,6 +3371,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev) fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); /* set all bits that we expect to always be set */ + fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */ fctrl |= IXGBE_FCTRL_BAM; fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */ fctrl |= IXGBE_FCTRL_PMCF; @@ -3390,6 +3420,18 @@ void ixgbe_set_rx_mode(struct net_device *netdev) IXGBE_WRITE_REG(hw, IXGBE_VMOLR(adapter->num_vfs), vmolr); } + /* This is useful for sniffing bad packets. */ + if (adapter->netdev->features & NETIF_F_RXALL) { + /* UPE and MPE will be handled by normal PROMISC logic + * in e1000e_set_rx_mode */ + fctrl |= (IXGBE_FCTRL_SBP | /* Receive bad packets */ + IXGBE_FCTRL_BAM | /* RX All Bcast Pkts */ + IXGBE_FCTRL_PMCF); /* RX All MAC Ctrl Pkts */ + + fctrl &= ~(IXGBE_FCTRL_DPF); + /* NOTE: VLAN filtering is disabled by setting PROMISC */ + } + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); if (netdev->features & NETIF_F_HW_VLAN_RX) @@ -3977,6 +4019,27 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) } /** + * ixgbe_init_rx_page_offset - initialize page offset values for Rx buffers + * @rx_ring: ring to setup + * + * On many IA platforms the L1 cache has a critical stride of 4K, this + * results in each receive buffer starting in the same cache set. To help + * reduce the pressure on this cache set we can interleave the offsets so + * that only every other buffer will be in the same cache set. + **/ +static void ixgbe_init_rx_page_offset(struct ixgbe_ring *rx_ring) +{ + struct ixgbe_rx_buffer *rx_buffer = rx_ring->rx_buffer_info; + u16 i; + + for (i = 0; i < rx_ring->count; i += 2) { + rx_buffer[0].page_offset = 0; + rx_buffer[1].page_offset = ixgbe_rx_bufsz(rx_ring); + rx_buffer = &rx_buffer[2]; + } +} + +/** * ixgbe_clean_rx_ring - Free Rx Buffers per Queue * @rx_ring: ring to free buffers from **/ @@ -3992,49 +4055,40 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) /* Free all the Rx ring sk_buffs */ for (i = 0; i < rx_ring->count; i++) { - struct ixgbe_rx_buffer *rx_buffer_info; - - rx_buffer_info = &rx_ring->rx_buffer_info[i]; - if (rx_buffer_info->dma) { - dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - rx_buffer_info->dma = 0; - } - if (rx_buffer_info->skb) { - struct sk_buff *skb = rx_buffer_info->skb; - rx_buffer_info->skb = NULL; - /* We need to clean up RSC frag lists */ - skb = ixgbe_merge_active_tail(skb); - ixgbe_close_active_frag_list(skb); - if (IXGBE_CB(skb)->delay_unmap) { - dma_unmap_single(dev, - IXGBE_CB(skb)->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - IXGBE_CB(skb)->dma = 0; - IXGBE_CB(skb)->delay_unmap = false; + struct ixgbe_rx_buffer *rx_buffer; + + rx_buffer = &rx_ring->rx_buffer_info[i]; + if (rx_buffer->skb) { + struct sk_buff *skb = rx_buffer->skb; + if (IXGBE_CB(skb)->page_released) { + dma_unmap_page(dev, + IXGBE_CB(skb)->dma, + ixgbe_rx_bufsz(rx_ring), + DMA_FROM_DEVICE); + IXGBE_CB(skb)->page_released = false; } dev_kfree_skb(skb); } - if (!rx_buffer_info->page) - continue; - if (rx_buffer_info->page_dma) { - dma_unmap_page(dev, rx_buffer_info->page_dma, - PAGE_SIZE / 2, DMA_FROM_DEVICE); - rx_buffer_info->page_dma = 0; - } - put_page(rx_buffer_info->page); - rx_buffer_info->page = NULL; - rx_buffer_info->page_offset = 0; + rx_buffer->skb = NULL; + if (rx_buffer->dma) + dma_unmap_page(dev, rx_buffer->dma, + ixgbe_rx_pg_size(rx_ring), + DMA_FROM_DEVICE); + rx_buffer->dma = 0; + if (rx_buffer->page) + put_page(rx_buffer->page); + rx_buffer->page = NULL; } size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; memset(rx_ring->rx_buffer_info, 0, size); + ixgbe_init_rx_page_offset(rx_ring); + /* Zero out the descriptor ring */ memset(rx_ring->desc, 0, rx_ring->size); + rx_ring->next_to_alloc = 0; rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; } @@ -5398,6 +5452,8 @@ int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring) rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; + ixgbe_init_rx_page_offset(rx_ring); + return 0; err: vfree(rx_ring->rx_buffer_info); @@ -5517,20 +5573,24 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* MTU < 68 is an error and causes problems on some kernels */ - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED && - hw->mac.type != ixgbe_mac_X540) { - if ((new_mtu < 68) || (max_frame > MAXIMUM_ETHERNET_VLAN_SIZE)) - return -EINVAL; - } else { - if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) + if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) + return -EINVAL; + + /* + * For 82599EB we cannot allow PF to change MTU greater than 1500 + * in SR-IOV mode as it may cause buffer overruns in guest VFs that + * don't allocate and chain buffers correctly. + */ + if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && + (adapter->hw.mac.type == ixgbe_mac_82599EB) && + (max_frame > MAXIMUM_ETHERNET_VLAN_SIZE)) return -EINVAL; - } e_info(probe, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); + /* must set new MTU before calling down or up */ netdev->mtu = new_mtu; @@ -6523,9 +6583,11 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens, context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); } -static int ixgbe_tso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, +static int ixgbe_tso(struct ixgbe_ring *tx_ring, + struct ixgbe_tx_buffer *first, u32 tx_flags, __be16 protocol, u8 *hdr_len) { + struct sk_buff *skb = first->skb; int err; u32 vlan_macip_lens, type_tucmd; u32 mss_l4len_idx, l4len; @@ -6559,9 +6621,14 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, 0, IPPROTO_TCP, 0); } + /* compute header lengths */ l4len = tcp_hdrlen(skb); *hdr_len = skb_transport_offset(skb) + l4len; + /* update gso size and bytecount with header size */ + first->gso_segs = skb_shinfo(skb)->gso_segs; + first->bytecount += (first->gso_segs - 1) * *hdr_len; + /* mss_l4len_id: use 1 as index for TSO */ mss_l4len_idx = l4len << IXGBE_ADVTXD_L4LEN_SHIFT; mss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT; @@ -6579,9 +6646,10 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, } static bool ixgbe_tx_csum(struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, - __be16 protocol) + struct ixgbe_tx_buffer *first, + u32 tx_flags, __be16 protocol) { + struct sk_buff *skb = first->skb; u32 vlan_macip_lens = 0; u32 mss_l4len_idx = 0; u32 type_tucmd = 0; @@ -6658,7 +6726,7 @@ static __le32 ixgbe_tx_cmd_type(u32 tx_flags) /* set segmentation enable bits for TSO/FSO */ #ifdef IXGBE_FCOE - if ((tx_flags & IXGBE_TX_FLAGS_TSO) || (tx_flags & IXGBE_TX_FLAGS_FSO)) + if (tx_flags & (IXGBE_TX_FLAGS_TSO | IXGBE_TX_FLAGS_FSO)) #else if (tx_flags & IXGBE_TX_FLAGS_TSO) #endif @@ -6667,201 +6735,193 @@ static __le32 ixgbe_tx_cmd_type(u32 tx_flags) return cmd_type; } -static __le32 ixgbe_tx_olinfo_status(u32 tx_flags, unsigned int paylen) +static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc, + u32 tx_flags, unsigned int paylen) { - __le32 olinfo_status = - cpu_to_le32(paylen << IXGBE_ADVTXD_PAYLEN_SHIFT); - - if (tx_flags & IXGBE_TX_FLAGS_TSO) { - olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_POPTS_TXSM | - (1 << IXGBE_ADVTXD_IDX_SHIFT)); - /* enble IPv4 checksum for TSO */ - if (tx_flags & IXGBE_TX_FLAGS_IPV4) - olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_POPTS_IXSM); - } + __le32 olinfo_status = cpu_to_le32(paylen << IXGBE_ADVTXD_PAYLEN_SHIFT); /* enable L4 checksum for TSO and TX checksum offload */ if (tx_flags & IXGBE_TX_FLAGS_CSUM) olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_POPTS_TXSM); -#ifdef IXGBE_FCOE - /* use index 1 context for FCOE/FSO */ - if (tx_flags & IXGBE_TX_FLAGS_FCOE) - olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_CC | - (1 << IXGBE_ADVTXD_IDX_SHIFT)); + /* enble IPv4 checksum for TSO */ + if (tx_flags & IXGBE_TX_FLAGS_IPV4) + olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_POPTS_IXSM); + /* use index 1 context for TSO/FSO/FCOE */ +#ifdef IXGBE_FCOE + if (tx_flags & (IXGBE_TX_FLAGS_TSO | IXGBE_TX_FLAGS_FCOE)) +#else + if (tx_flags & IXGBE_TX_FLAGS_TSO) #endif + olinfo_status |= cpu_to_le32(1 << IXGBE_ADVTXD_IDX_SHIFT); + /* * Check Context must be set if Tx switch is enabled, which it * always is for case where virtual functions are running */ +#ifdef IXGBE_FCOE + if (tx_flags & (IXGBE_TX_FLAGS_TXSW | IXGBE_TX_FLAGS_FCOE)) +#else if (tx_flags & IXGBE_TX_FLAGS_TXSW) +#endif olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_CC); - return olinfo_status; + tx_desc->read.olinfo_status = olinfo_status; } #define IXGBE_TXD_CMD (IXGBE_TXD_CMD_EOP | \ IXGBE_TXD_CMD_RS) static void ixgbe_tx_map(struct ixgbe_ring *tx_ring, - struct sk_buff *skb, struct ixgbe_tx_buffer *first, u32 tx_flags, const u8 hdr_len) { - struct device *dev = tx_ring->dev; - struct ixgbe_tx_buffer *tx_buffer_info; - union ixgbe_adv_tx_desc *tx_desc; dma_addr_t dma; - __le32 cmd_type, olinfo_status; - struct skb_frag_struct *frag; - unsigned int f = 0; + struct sk_buff *skb = first->skb; + struct ixgbe_tx_buffer *tx_buffer; + union ixgbe_adv_tx_desc *tx_desc; + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0]; unsigned int data_len = skb->data_len; unsigned int size = skb_headlen(skb); - u32 offset = 0; - u32 paylen = skb->len - hdr_len; + unsigned int paylen = skb->len - hdr_len; + __le32 cmd_type; u16 i = tx_ring->next_to_use; - u16 gso_segs; + + tx_desc = IXGBE_TX_DESC(tx_ring, i); + + ixgbe_tx_olinfo_status(tx_desc, tx_flags, paylen); + cmd_type = ixgbe_tx_cmd_type(tx_flags); #ifdef IXGBE_FCOE if (tx_flags & IXGBE_TX_FLAGS_FCOE) { - if (data_len >= sizeof(struct fcoe_crc_eof)) { - data_len -= sizeof(struct fcoe_crc_eof); - } else { + if (data_len < sizeof(struct fcoe_crc_eof)) { size -= sizeof(struct fcoe_crc_eof) - data_len; data_len = 0; + } else { + data_len -= sizeof(struct fcoe_crc_eof); } } #endif - dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE); - if (dma_mapping_error(dev, dma)) + dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE); + if (dma_mapping_error(tx_ring->dev, dma)) goto dma_error; - cmd_type = ixgbe_tx_cmd_type(tx_flags); - olinfo_status = ixgbe_tx_olinfo_status(tx_flags, paylen); + /* record length, and DMA address */ + dma_unmap_len_set(first, len, size); + dma_unmap_addr_set(first, dma, dma); + first->tx_flags = tx_flags; - tx_desc = IXGBE_TX_DESC(tx_ring, i); + tx_desc->read.buffer_addr = cpu_to_le64(dma); for (;;) { - while (size > IXGBE_MAX_DATA_PER_TXD) { - tx_desc->read.buffer_addr = cpu_to_le64(dma + offset); + while (unlikely(size > IXGBE_MAX_DATA_PER_TXD)) { tx_desc->read.cmd_type_len = cmd_type | cpu_to_le32(IXGBE_MAX_DATA_PER_TXD); - tx_desc->read.olinfo_status = olinfo_status; - - offset += IXGBE_MAX_DATA_PER_TXD; - size -= IXGBE_MAX_DATA_PER_TXD; - tx_desc++; i++; + tx_desc++; if (i == tx_ring->count) { tx_desc = IXGBE_TX_DESC(tx_ring, 0); i = 0; } + + dma += IXGBE_MAX_DATA_PER_TXD; + size -= IXGBE_MAX_DATA_PER_TXD; + + tx_desc->read.buffer_addr = cpu_to_le64(dma); + tx_desc->read.olinfo_status = 0; } - tx_buffer_info = &tx_ring->tx_buffer_info[i]; - tx_buffer_info->length = offset + size; - tx_buffer_info->tx_flags = tx_flags; - tx_buffer_info->dma = dma; + if (likely(!data_len)) + break; - tx_desc->read.buffer_addr = cpu_to_le64(dma + offset); + if (unlikely(skb->no_fcs)) + cmd_type &= ~(cpu_to_le32(IXGBE_ADVTXD_DCMD_IFCS)); tx_desc->read.cmd_type_len = cmd_type | cpu_to_le32(size); - tx_desc->read.olinfo_status = olinfo_status; - if (!data_len) - break; + i++; + tx_desc++; + if (i == tx_ring->count) { + tx_desc = IXGBE_TX_DESC(tx_ring, 0); + i = 0; + } - frag = &skb_shinfo(skb)->frags[f]; #ifdef IXGBE_FCOE size = min_t(unsigned int, data_len, skb_frag_size(frag)); #else size = skb_frag_size(frag); #endif data_len -= size; - f++; - offset = 0; - tx_flags |= IXGBE_TX_FLAGS_MAPPED_AS_PAGE; - - dma = skb_frag_dma_map(dev, frag, 0, size, DMA_TO_DEVICE); - if (dma_mapping_error(dev, dma)) + dma = skb_frag_dma_map(tx_ring->dev, frag, 0, size, + DMA_TO_DEVICE); + if (dma_mapping_error(tx_ring->dev, dma)) goto dma_error; - tx_desc++; - i++; - if (i == tx_ring->count) { - tx_desc = IXGBE_TX_DESC(tx_ring, 0); - i = 0; - } - } - - tx_desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD); - - i++; - if (i == tx_ring->count) - i = 0; + tx_buffer = &tx_ring->tx_buffer_info[i]; + dma_unmap_len_set(tx_buffer, len, size); + dma_unmap_addr_set(tx_buffer, dma, dma); - tx_ring->next_to_use = i; + tx_desc->read.buffer_addr = cpu_to_le64(dma); + tx_desc->read.olinfo_status = 0; - if (tx_flags & IXGBE_TX_FLAGS_TSO) - gso_segs = skb_shinfo(skb)->gso_segs; -#ifdef IXGBE_FCOE - /* adjust for FCoE Sequence Offload */ - else if (tx_flags & IXGBE_TX_FLAGS_FSO) - gso_segs = DIV_ROUND_UP(skb->len - hdr_len, - skb_shinfo(skb)->gso_size); -#endif /* IXGBE_FCOE */ - else - gso_segs = 1; + frag++; + } - /* multiply data chunks by size of headers */ - tx_buffer_info->bytecount = paylen + (gso_segs * hdr_len); - tx_buffer_info->gso_segs = gso_segs; - tx_buffer_info->skb = skb; + /* write last descriptor with RS and EOP bits */ + cmd_type |= cpu_to_le32(size) | cpu_to_le32(IXGBE_TXD_CMD); + tx_desc->read.cmd_type_len = cmd_type; - netdev_tx_sent_queue(txring_txq(tx_ring), tx_buffer_info->bytecount); + netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount); /* set the timestamp */ first->time_stamp = jiffies; /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). + * Force memory writes to complete before letting h/w know there + * are new descriptors to fetch. (Only applicable for weak-ordered + * memory model archs, such as IA-64). + * + * We also need this memory barrier to make certain all of the + * status bits have been updated before next_to_watch is written. */ wmb(); /* set next_to_watch value indicating a packet is present */ first->next_to_watch = tx_desc; + i++; + if (i == tx_ring->count) + i = 0; + + tx_ring->next_to_use = i; + /* notify HW of packet */ writel(i, tx_ring->tail); return; dma_error: - dev_err(dev, "TX DMA map failed\n"); + dev_err(tx_ring->dev, "TX DMA map failed\n"); /* clear dma mappings for failed tx_buffer_info map */ for (;;) { - tx_buffer_info = &tx_ring->tx_buffer_info[i]; - ixgbe_unmap_tx_resource(tx_ring, tx_buffer_info); - if (tx_buffer_info == first) + tx_buffer = &tx_ring->tx_buffer_info[i]; + ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer); + if (tx_buffer == first) break; if (i == 0) i = tx_ring->count; i--; } - dev_kfree_skb_any(skb); - tx_ring->next_to_use = i; } -static void ixgbe_atr(struct ixgbe_ring *ring, struct sk_buff *skb, +static void ixgbe_atr(struct ixgbe_ring *ring, + struct ixgbe_tx_buffer *first, u32 tx_flags, __be16 protocol) { struct ixgbe_q_vector *q_vector = ring->q_vector; @@ -6886,7 +6946,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring, struct sk_buff *skb, ring->atr_count++; /* snag network header to get L4 type and address */ - hdr.network = skb_network_header(skb); + hdr.network = skb_network_header(first->skb); /* Currently only IPv4/IPv6 with TCP is supported */ if ((protocol != __constant_htons(ETH_P_IPV6) || @@ -6895,7 +6955,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring, struct sk_buff *skb, hdr.ipv4->protocol != IPPROTO_TCP)) return; - th = tcp_hdr(skb); + th = tcp_hdr(first->skb); /* skip this packet since it is invalid or the socket is closing */ if (!th || th->fin) @@ -7033,6 +7093,12 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, return NETDEV_TX_BUSY; } + /* record the location of the first descriptor for this packet */ + first = &tx_ring->tx_buffer_info[tx_ring->next_to_use]; + first->skb = skb; + first->bytecount = skb->len; + first->gso_segs = 1; + /* if we have a HW VLAN tag being added default to the HW one */ if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT; @@ -7079,14 +7145,11 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, } } - /* record the location of the first descriptor for this packet */ - first = &tx_ring->tx_buffer_info[tx_ring->next_to_use]; - #ifdef IXGBE_FCOE /* setup tx offload for FCoE */ if ((protocol == __constant_htons(ETH_P_FCOE)) && (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) { - tso = ixgbe_fso(tx_ring, skb, tx_flags, &hdr_len); + tso = ixgbe_fso(tx_ring, first, tx_flags, &hdr_len); if (tso < 0) goto out_drop; else if (tso) @@ -7103,37 +7166,55 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, if (protocol == __constant_htons(ETH_P_IP)) tx_flags |= IXGBE_TX_FLAGS_IPV4; - tso = ixgbe_tso(tx_ring, skb, tx_flags, protocol, &hdr_len); + tso = ixgbe_tso(tx_ring, first, tx_flags, protocol, &hdr_len); if (tso < 0) goto out_drop; else if (tso) - tx_flags |= IXGBE_TX_FLAGS_TSO; - else if (ixgbe_tx_csum(tx_ring, skb, tx_flags, protocol)) + tx_flags |= IXGBE_TX_FLAGS_TSO | IXGBE_TX_FLAGS_CSUM; + else if (ixgbe_tx_csum(tx_ring, first, tx_flags, protocol)) tx_flags |= IXGBE_TX_FLAGS_CSUM; /* add the ATR filter if ATR is on */ if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state)) - ixgbe_atr(tx_ring, skb, tx_flags, protocol); + ixgbe_atr(tx_ring, first, tx_flags, protocol); #ifdef IXGBE_FCOE xmit_fcoe: #endif /* IXGBE_FCOE */ - ixgbe_tx_map(tx_ring, skb, first, tx_flags, hdr_len); + ixgbe_tx_map(tx_ring, first, tx_flags, hdr_len); ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED); return NETDEV_TX_OK; out_drop: - dev_kfree_skb_any(skb); + dev_kfree_skb_any(first->skb); + first->skb = NULL; + return NETDEV_TX_OK; } -static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, + struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_ring *tx_ring; + if (skb->len <= 0) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + /* + * The minimum packet size for olinfo paylen is 17 so pad the skb + * in order to meet this minimum size requirement. + */ + if (skb->len < 17) { + if (skb_padto(skb, 17)) + return NETDEV_TX_OK; + skb->len = 17; + } + tx_ring = adapter->tx_ring[skb->queue_mapping]; return ixgbe_xmit_frame_ring(skb, adapter, tx_ring); } @@ -7457,6 +7538,7 @@ static int ixgbe_set_features(struct net_device *netdev, netdev_features_t data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + netdev_features_t changed = netdev->features ^ data; bool need_reset = false; /* Make sure RSC matches LRO, reset if change */ @@ -7493,6 +7575,10 @@ static int ixgbe_set_features(struct net_device *netdev, need_reset = true; } + if (changed & NETIF_F_RXALL) + need_reset = true; + + netdev->features = data; if (need_reset) ixgbe_do_reset(netdev); @@ -7771,6 +7857,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, break; } + netdev->hw_features |= NETIF_F_RXALL; + netdev->vlan_features |= NETIF_F_TSO; netdev->vlan_features |= NETIF_F_TSO6; netdev->vlan_features |= NETIF_F_IP_CSUM; @@ -7778,6 +7866,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_SG; netdev->priv_flags |= IFF_UNICAST_FLT; + netdev->priv_flags |= IFF_SUPP_NOFCS; if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) adapter->flags &= ~(IXGBE_FLAG_RSS_ENABLED | diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 3a7df0593c68..45a6333588e6 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -220,7 +220,6 @@ struct pxa168_eth_private { u8 work_todo; int skb_size; - struct net_device_stats stats; /* Size of Tx Ring per queue */ int tx_ring_size; /* Number of tx descriptors in use */ diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index 2eeac32f7fdd..b5de8a7b90f1 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -954,7 +954,7 @@ typedef struct nx_mac_list_s { struct nx_vlan_ip_list { struct list_head list; - u32 ip_addr; + __be32 ip_addr; }; /* @@ -1780,7 +1780,7 @@ int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max); void netxen_p3_free_mac_list(struct netxen_adapter *adapter); int netxen_config_intr_coalesce(struct netxen_adapter *adapter); int netxen_config_rss(struct netxen_adapter *adapter, int enable); -int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd); +int netxen_config_ipaddr(struct netxen_adapter *adapter, __be32 ip, int cmd); int netxen_linkevent_request(struct netxen_adapter *adapter, int enable); void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); void netxen_pci_camqm_read_2M(struct netxen_adapter *, u64, u64 *); diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index 6f37470750f3..de96a948bb7f 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -909,7 +909,7 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable) return rv; } -int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd) +int netxen_config_ipaddr(struct netxen_adapter *adapter, __be32 ip, int cmd) { nx_nic_req_t req; u64 word; @@ -922,7 +922,7 @@ int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd) req.req_hdr = cpu_to_le64(word); req.words[0] = cpu_to_le64(cmd); - req.words[1] = cpu_to_le64(ip); + memcpy(&req.words[1], &ip, sizeof(u32)); rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); if (rv != 0) { @@ -1050,7 +1050,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac) if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1) return -1; - if (*mac == cpu_to_le64(~0ULL)) { + if (*mac == ~0ULL) { offset = NX_OLD_MAC_ADDR_OFFSET + (adapter->portnum * sizeof(u64)); @@ -1059,7 +1059,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac) offset, sizeof(u64), pmac) == -1) return -1; - if (*mac == cpu_to_le64(~0ULL)) + if (*mac == ~0ULL) return -1; } return 0; @@ -2155,7 +2155,7 @@ static u32 netxen_md_rd_crb(struct netxen_adapter *adapter, static u32 netxen_md_rdrom(struct netxen_adapter *adapter, struct netxen_minidump_entry_rdrom - *romEntry, u32 *data_buff) + *romEntry, __le32 *data_buff) { int i, count = 0; u32 size, lck_val; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 7648995ea720..65a718f9ccd3 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -805,12 +805,12 @@ netxen_check_options(struct netxen_adapter *adapter) char brd_name[NETXEN_MAX_SHORT_NAME]; char serial_num[32]; int i, offset, val, err; - int *ptr32; + __le32 *ptr32; struct pci_dev *pdev = adapter->pdev; adapter->driver_mismatch = 0; - ptr32 = (int *)&serial_num; + ptr32 = (__le32 *)&serial_num; offset = NX_FW_SERIAL_NUM_OFFSET; for (i = 0; i < 8; i++) { if (netxen_rom_fast_read(adapter, offset, &val) == -1) { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 3aad9810237c..116529a366b2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -24,8 +24,48 @@ #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_net.h> #include "stmmac.h" +#ifdef CONFIG_OF +static int __devinit stmmac_probe_config_dt(struct platform_device *pdev, + struct plat_stmmacenet_data *plat, + const char **mac) +{ + struct device_node *np = pdev->dev.of_node; + + if (!np) + return -ENODEV; + + *mac = of_get_mac_address(np); + plat->interface = of_get_phy_mode(np); + plat->mdio_bus_data = devm_kzalloc(&pdev->dev, + sizeof(struct stmmac_mdio_bus_data), + GFP_KERNEL); + + /* + * Currently only the properties needed on SPEAr600 + * are provided. All other properties should be added + * once needed on other platforms. + */ + if (of_device_is_compatible(np, "st,spear600-gmac")) { + plat->pbl = 8; + plat->has_gmac = 1; + plat->pmt = 1; + } + + return 0; +} +#else +static int __devinit stmmac_probe_config_dt(struct platform_device *pdev, + struct plat_stmmacenet_data *plat, + const char **mac) +{ + return -ENOSYS; +} +#endif /* CONFIG_OF */ + /** * stmmac_pltfr_probe * @pdev: platform device pointer @@ -39,7 +79,8 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) struct resource *res; void __iomem *addr = NULL; struct stmmac_priv *priv = NULL; - struct plat_stmmacenet_data *plat_dat; + struct plat_stmmacenet_data *plat_dat = NULL; + const char *mac = NULL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -58,7 +99,25 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) ret = -ENOMEM; goto out_release_region; } - plat_dat = pdev->dev.platform_data; + + if (pdev->dev.of_node) { + plat_dat = devm_kzalloc(&pdev->dev, + sizeof(struct plat_stmmacenet_data), + GFP_KERNEL); + if (!plat_dat) { + pr_err("%s: ERROR: no memory", __func__); + ret = -ENOMEM; + goto out_unmap; + } + + ret = stmmac_probe_config_dt(pdev, plat_dat, &mac); + if (ret) { + pr_err("%s: main dt probe failed", __func__); + goto out_unmap; + } + } else { + plat_dat = pdev->dev.platform_data; + } /* Custom initialisation (if needed)*/ if (plat_dat->init) { @@ -73,6 +132,10 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) goto out_unmap; } + /* Get MAC address if available (DT) */ + if (mac) + memcpy(priv->dev->dev_addr, mac, ETH_ALEN); + /* Get the MAC information */ priv->dev->irq = platform_get_irq_byname(pdev, "macirq"); if (priv->dev->irq == -ENXIO) { @@ -178,6 +241,12 @@ static const struct dev_pm_ops stmmac_pltfr_pm_ops = { static const struct dev_pm_ops stmmac_pltfr_pm_ops; #endif /* CONFIG_PM */ +static const struct of_device_id stmmac_dt_ids[] = { + { .compatible = "st,spear600-gmac", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, stmmac_dt_ids); + static struct platform_driver stmmac_driver = { .probe = stmmac_pltfr_probe, .remove = stmmac_pltfr_remove, @@ -185,6 +254,7 @@ static struct platform_driver stmmac_driver = { .name = STMMAC_RESOURCE_NAME, .owner = THIS_MODULE, .pm = &stmmac_pltfr_pm_ops, + .of_match_table = of_match_ptr(stmmac_dt_ids), }, }; diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 0f8e8344891b..2517d209d602 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -167,7 +167,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) dev_kfree_skb(skb); net->stats.tx_dropped++; - return NETDEV_TX_BUSY; + return NETDEV_TX_OK; } packet->vlan_tci = skb->vlan_tci; @@ -229,7 +229,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) dev_kfree_skb_any(skb); } - return ret ? NETDEV_TX_BUSY : NETDEV_TX_OK; + return NETDEV_TX_OK; } /* diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 81d5275a15e2..ff16daf33ae1 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -128,20 +128,20 @@ struct pxa_irda { static inline void pxa_irda_disable_clk(struct pxa_irda *si) { if (si->cur_clk) - clk_disable(si->cur_clk); + clk_disable_unprepare(si->cur_clk); si->cur_clk = NULL; } static inline void pxa_irda_enable_firclk(struct pxa_irda *si) { si->cur_clk = si->fir_clk; - clk_enable(si->fir_clk); + clk_prepare_enable(si->fir_clk); } static inline void pxa_irda_enable_sirclk(struct pxa_irda *si) { si->cur_clk = si->sir_clk; - clk_enable(si->sir_clk); + clk_prepare_enable(si->sir_clk); } diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index ba3c59147aa7..dd7ae19579d1 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -1243,7 +1243,7 @@ static void __exit dp83640_exit(void) } MODULE_DESCRIPTION("National Semiconductor DP83640 PHY driver"); -MODULE_AUTHOR("Richard Cochran <[email protected]>"); +MODULE_AUTHOR("Richard Cochran <[email protected]>"); MODULE_LICENSE("GPL"); module_init(dp83640_init); diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2c5d34957c57..74d7f76d14a3 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); - sock_put(tun->socket.sk); + sk_release_kernel(tun->socket.sk); } /* Net device open. */ @@ -980,10 +980,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, return ret; } +static int tun_release(struct socket *sock) +{ + if (sock->sk) + sock_put(sock->sk); + return 0; +} + /* Ops structure to mimic raw sockets with tun */ static const struct proto_ops tun_socket_ops = { .sendmsg = tun_sendmsg, .recvmsg = tun_recvmsg, + .release = tun_release, }; static struct proto tun_proto = { @@ -1110,10 +1118,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); err = -ENOMEM; - sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); + sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto); if (!sk) goto err_free_dev; + sk_change_net(sk, net); tun->socket.wq = &tun->wq; init_waitqueue_head(&tun->wq.wait); tun->socket.ops = &tun_socket_ops; @@ -1174,7 +1183,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) return 0; err_free_sk: - sock_put(sk); + tun_free_netdev(dev); err_free_dev: free_netdev(dev); failed: diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 8e84f5bdd6ca..5ee032cafade 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -305,88 +305,40 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) { - u8 *head; - u32 header; - char *packet; - struct sk_buff *ax_skb; - u16 size; + int offset = 0; - head = (u8 *) skb->data; - memcpy(&header, head, sizeof(header)); - le32_to_cpus(&header); - packet = head + sizeof(header); + while (offset + sizeof(u32) < skb->len) { + struct sk_buff *ax_skb; + u16 size; + u32 header = get_unaligned_le32(skb->data + offset); - skb_pull(skb, 4); - - while (skb->len > 0) { - if ((header & 0x07ff) != ((~header >> 16) & 0x07ff)) - netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); + offset += sizeof(u32); /* get the packet length */ - size = (u16) (header & 0x000007ff); - - if ((skb->len) - ((size + 1) & 0xfffe) == 0) { - u8 alignment = (unsigned long)skb->data & 0x3; - if (alignment != 0x2) { - /* - * not 16bit aligned so use the room provided by - * the 32 bit header to align the data - * - * note we want 16bit alignment as MAC header is - * 14bytes thus ip header will be aligned on - * 32bit boundary so accessing ipheader elements - * using a cast to struct ip header wont cause - * an unaligned accesses. - */ - u8 realignment = (alignment + 2) & 0x3; - memmove(skb->data - realignment, - skb->data, - size); - skb->data -= realignment; - skb_set_tail_pointer(skb, size); - } - return 2; + size = (u16) (header & 0x7ff); + if (size != ((~header >> 16) & 0x07ff)) { + netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); + return 0; } - if (size > dev->net->mtu + ETH_HLEN) { + if ((size > dev->net->mtu + ETH_HLEN) || + (size + offset > skb->len)) { netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", size); return 0; } - ax_skb = skb_clone(skb, GFP_ATOMIC); - if (ax_skb) { - u8 alignment = (unsigned long)packet & 0x3; - ax_skb->len = size; - - if (alignment != 0x2) { - /* - * not 16bit aligned use the room provided by - * the 32 bit header to align the data - */ - u8 realignment = (alignment + 2) & 0x3; - memmove(packet - realignment, packet, size); - packet -= realignment; - } - ax_skb->data = packet; - skb_set_tail_pointer(ax_skb, size); - usbnet_skb_return(dev, ax_skb); - } else { + ax_skb = netdev_alloc_skb_ip_align(dev->net, size); + if (!ax_skb) return 0; - } - skb_pull(skb, (size + 1) & 0xfffe); + skb_put(ax_skb, size); + memcpy(ax_skb->data, skb->data + offset, size); + usbnet_skb_return(dev, ax_skb); - if (skb->len < sizeof(header)) - break; - - head = (u8 *) skb->data; - memcpy(&header, head, sizeof(header)); - le32_to_cpus(&header); - packet = head + sizeof(header); - skb_pull(skb, 4); + offset += (size + 1) & 0xfffe; } - if (skb->len < 0) { + if (skb->len != offset) { netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n", skb->len); return 0; @@ -1541,7 +1493,7 @@ static const struct driver_info ax88772_info = { .status = asix_status, .link_reset = ax88772_link_reset, .reset = ax88772_reset, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, .rx_fixup = asix_rx_fixup, .tx_fixup = asix_tx_fixup, }; @@ -1599,6 +1551,10 @@ static const struct usb_device_id products [] = { USB_DEVICE (0x6189, 0x182d), .driver_info = (unsigned long) &ax8817x_info, }, { + // Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter" + USB_DEVICE (0x0df6, 0x0056), + .driver_info = (unsigned long) &ax88178_info, +}, { // corega FEther USB2-TX USB_DEVICE (0x07aa, 0x0017), .driver_info = (unsigned long) &ax8817x_info, diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 81f86b8ea551..7adc9f6b0ea1 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1,7 +1,7 @@ /* * cdc_ncm.c * - * Copyright (C) ST-Ericsson 2010-2011 + * Copyright (C) ST-Ericsson 2010-2012 * Contact: Alexey Orishko <[email protected]> * Original author: Hans Petter Selasky <[email protected]> * @@ -47,20 +47,19 @@ #include <linux/mii.h> #include <linux/crc32.h> #include <linux/usb.h> -#include <linux/timer.h> -#include <linux/spinlock.h> +#include <linux/hrtimer.h> #include <linux/atomic.h> #include <linux/usb/usbnet.h> #include <linux/usb/cdc.h> -#define DRIVER_VERSION "04-Aug-2011" +#define DRIVER_VERSION "14-Mar-2012" /* CDC NCM subclass 3.2.1 */ #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 /* Maximum NTB length */ -#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */ -#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */ +#define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */ +#define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* bytes */ /* Minimum value for MaxDatagramSize, ch. 6.2.9 */ #define CDC_NCM_MIN_DATAGRAM_SIZE 1514 /* bytes */ @@ -68,19 +67,18 @@ #define CDC_NCM_MIN_TX_PKT 512 /* bytes */ /* Default value for MaxDatagramSize */ -#define CDC_NCM_MAX_DATAGRAM_SIZE 2048 /* bytes */ +#define CDC_NCM_MAX_DATAGRAM_SIZE 8192 /* bytes */ /* * Maximum amount of datagrams in NCM Datagram Pointer Table, not counting - * the last NULL entry. Any additional datagrams in NTB would be discarded. + * the last NULL entry. */ -#define CDC_NCM_DPT_DATAGRAMS_MAX 32 - -/* Maximum amount of IN datagrams in NTB */ -#define CDC_NCM_DPT_DATAGRAMS_IN_MAX 0 /* unlimited */ +#define CDC_NCM_DPT_DATAGRAMS_MAX 40 /* Restart the timer, if amount of datagrams is less than given value */ #define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 +#define CDC_NCM_TIMER_PENDING_CNT 2 +#define CDC_NCM_TIMER_INTERVAL (400UL * NSEC_PER_USEC) /* The following macro defines the minimum header space */ #define CDC_NCM_MIN_HDR_SIZE \ @@ -94,10 +92,10 @@ struct cdc_ncm_data { }; struct cdc_ncm_ctx { - struct cdc_ncm_data rx_ncm; struct cdc_ncm_data tx_ncm; struct usb_cdc_ncm_ntb_parameters ncm_parm; - struct timer_list tx_timer; + struct hrtimer tx_timer; + struct tasklet_struct bh; const struct usb_cdc_ncm_desc *func_desc; const struct usb_cdc_header_desc *header_desc; @@ -117,6 +115,7 @@ struct cdc_ncm_ctx { struct sk_buff *tx_rem_skb; spinlock_t mtx; + atomic_t stop; u32 tx_timer_pending; u32 tx_curr_offset; @@ -132,10 +131,13 @@ struct cdc_ncm_ctx { u16 tx_modulus; u16 tx_ndp_modulus; u16 tx_seq; + u16 rx_seq; u16 connected; }; -static void cdc_ncm_tx_timeout(unsigned long arg); +static void cdc_ncm_txpath_bh(unsigned long param); +static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx); +static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); static const struct driver_info cdc_ncm_info; static struct usb_driver cdc_ncm_driver; static const struct ethtool_ops cdc_ncm_ethtool_ops; @@ -361,27 +363,25 @@ size_err: if (err < 0) { pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", CDC_NCM_MIN_DATAGRAM_SIZE); - kfree(max_datagram_size); } else { ctx->max_datagram_size = le16_to_cpu(*max_datagram_size); /* Check Eth descriptor value */ - if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) { - if (ctx->max_datagram_size > eth_max_sz) + if (ctx->max_datagram_size > eth_max_sz) ctx->max_datagram_size = eth_max_sz; - } else { - if (ctx->max_datagram_size > - CDC_NCM_MAX_DATAGRAM_SIZE) - ctx->max_datagram_size = + + if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE) + ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE; - } if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; /* if value changed, update device */ - err = usb_control_msg(ctx->udev, + if (ctx->max_datagram_size != + le16_to_cpu(*max_datagram_size)) { + err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), USB_CDC_SET_MAX_DATAGRAM_SIZE, USB_TYPE_CLASS | USB_DIR_OUT @@ -389,14 +389,14 @@ size_err: 0, iface_no, max_datagram_size, 2, 1000); - kfree(max_datagram_size); -max_dgram_err: - if (err < 0) - pr_debug("SET_MAX_DATAGRAM_SIZE failed\n"); + if (err < 0) + pr_debug("SET_MAX_DGRAM_SIZE failed\n"); + } } - + kfree(max_datagram_size); } +max_dgram_err: if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) ctx->netdev->mtu = ctx->max_datagram_size - ETH_HLEN; @@ -441,8 +441,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx) if (ctx == NULL) return; - del_timer_sync(&ctx->tx_timer); - if (ctx->tx_rem_skb != NULL) { dev_kfree_skb_any(ctx->tx_rem_skb); ctx->tx_rem_skb = NULL; @@ -469,7 +467,11 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) if (ctx == NULL) return -ENODEV; - init_timer(&ctx->tx_timer); + hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ctx->tx_timer.function = &cdc_ncm_tx_timer_cb; + ctx->bh.data = (unsigned long)ctx; + ctx->bh.func = cdc_ncm_txpath_bh; + atomic_set(&ctx->stop, 0); spin_lock_init(&ctx->mtx); ctx->netdev = dev->net; @@ -617,6 +619,13 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) if (ctx == NULL) return; /* no setup */ + atomic_set(&ctx->stop, 1); + + if (hrtimer_active(&ctx->tx_timer)) + hrtimer_cancel(&ctx->tx_timer); + + tasklet_kill(&ctx->bh); + /* disconnect master --> disconnect slave */ if (intf == ctx->control && ctx->data) { usb_set_intfdata(ctx->data, NULL); @@ -787,7 +796,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) ctx->tx_curr_last_offset = last_offset; /* set the pending count */ if (n < CDC_NCM_RESTART_TIMER_DATAGRAM_CNT) - ctx->tx_timer_pending = 2; + ctx->tx_timer_pending = CDC_NCM_TIMER_PENDING_CNT; goto exit_no_skb; } else { @@ -867,44 +876,49 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) /* return skb */ ctx->tx_curr_skb = NULL; + ctx->netdev->stats.tx_packets += ctx->tx_curr_frame_num; return skb_out; exit_no_skb: + /* Start timer, if there is a remaining skb */ + if (ctx->tx_curr_skb != NULL) + cdc_ncm_tx_timeout_start(ctx); return NULL; } static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx) { /* start timer, if not already started */ - if (timer_pending(&ctx->tx_timer) == 0) { - ctx->tx_timer.function = &cdc_ncm_tx_timeout; - ctx->tx_timer.data = (unsigned long)ctx; - ctx->tx_timer.expires = jiffies + ((HZ + 999) / 1000); - add_timer(&ctx->tx_timer); - } + if (!(hrtimer_active(&ctx->tx_timer) || atomic_read(&ctx->stop))) + hrtimer_start(&ctx->tx_timer, + ktime_set(0, CDC_NCM_TIMER_INTERVAL), + HRTIMER_MODE_REL); } -static void cdc_ncm_tx_timeout(unsigned long arg) +static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *timer) { - struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)arg; - u8 restart; + struct cdc_ncm_ctx *ctx = + container_of(timer, struct cdc_ncm_ctx, tx_timer); - spin_lock(&ctx->mtx); - if (ctx->tx_timer_pending != 0) { - ctx->tx_timer_pending--; - restart = 1; - } else { - restart = 0; - } + if (!atomic_read(&ctx->stop)) + tasklet_schedule(&ctx->bh); + return HRTIMER_NORESTART; +} - spin_unlock(&ctx->mtx); +static void cdc_ncm_txpath_bh(unsigned long param) +{ + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)param; - if (restart) { - spin_lock(&ctx->mtx); + spin_lock_bh(&ctx->mtx); + if (ctx->tx_timer_pending != 0) { + ctx->tx_timer_pending--; cdc_ncm_tx_timeout_start(ctx); - spin_unlock(&ctx->mtx); + spin_unlock_bh(&ctx->mtx); } else if (ctx->netdev != NULL) { + spin_unlock_bh(&ctx->mtx); + netif_tx_lock_bh(ctx->netdev); usbnet_start_xmit(NULL, ctx->netdev); + netif_tx_unlock_bh(ctx->netdev); } } @@ -913,7 +927,6 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) { struct sk_buff *skb_out; struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; - u8 need_timer = 0; /* * The Ethernet API we are using does not support transmitting @@ -925,19 +938,9 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) if (ctx == NULL) goto error; - spin_lock(&ctx->mtx); + spin_lock_bh(&ctx->mtx); skb_out = cdc_ncm_fill_tx_frame(ctx, skb); - if (ctx->tx_curr_skb != NULL) - need_timer = 1; - - /* Start timer, if there is a remaining skb */ - if (need_timer) - cdc_ncm_tx_timeout_start(ctx); - - if (skb_out) - dev->net->stats.tx_packets += ctx->tx_curr_frame_num; - - spin_unlock(&ctx->mtx); + spin_unlock_bh(&ctx->mtx); return skb_out; error: @@ -950,108 +953,103 @@ error: static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) { struct sk_buff *skb; - struct cdc_ncm_ctx *ctx; - int sumlen; - int actlen; - int temp; + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; + int len; int nframes; int x; int offset; + struct usb_cdc_ncm_nth16 *nth16; + struct usb_cdc_ncm_ndp16 *ndp16; + struct usb_cdc_ncm_dpe16 *dpe16; - ctx = (struct cdc_ncm_ctx *)dev->data[0]; if (ctx == NULL) goto error; - actlen = skb_in->len; - sumlen = CDC_NCM_NTB_MAX_SIZE_RX; - - if (actlen < (sizeof(ctx->rx_ncm.nth16) + sizeof(ctx->rx_ncm.ndp16))) { + if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth16) + + sizeof(struct usb_cdc_ncm_ndp16))) { pr_debug("frame too short\n"); goto error; } - memcpy(&(ctx->rx_ncm.nth16), ((u8 *)skb_in->data), - sizeof(ctx->rx_ncm.nth16)); + nth16 = (struct usb_cdc_ncm_nth16 *)skb_in->data; - if (le32_to_cpu(ctx->rx_ncm.nth16.dwSignature) != - USB_CDC_NCM_NTH16_SIGN) { + if (le32_to_cpu(nth16->dwSignature) != USB_CDC_NCM_NTH16_SIGN) { pr_debug("invalid NTH16 signature <%u>\n", - le32_to_cpu(ctx->rx_ncm.nth16.dwSignature)); + le32_to_cpu(nth16->dwSignature)); goto error; } - temp = le16_to_cpu(ctx->rx_ncm.nth16.wBlockLength); - if (temp > sumlen) { - pr_debug("unsupported NTB block length %u/%u\n", temp, sumlen); + len = le16_to_cpu(nth16->wBlockLength); + if (len > ctx->rx_max) { + pr_debug("unsupported NTB block length %u/%u\n", len, + ctx->rx_max); goto error; } - temp = le16_to_cpu(ctx->rx_ncm.nth16.wNdpIndex); - if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) { - pr_debug("invalid DPT16 index\n"); + if ((ctx->rx_seq + 1) != le16_to_cpu(nth16->wSequence) && + (ctx->rx_seq || le16_to_cpu(nth16->wSequence)) && + !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth16->wSequence))) { + pr_debug("sequence number glitch prev=%d curr=%d\n", + ctx->rx_seq, le16_to_cpu(nth16->wSequence)); + } + ctx->rx_seq = le16_to_cpu(nth16->wSequence); + + len = le16_to_cpu(nth16->wNdpIndex); + if ((len + sizeof(struct usb_cdc_ncm_ndp16)) > skb_in->len) { + pr_debug("invalid DPT16 index <%u>\n", + le16_to_cpu(nth16->wNdpIndex)); goto error; } - memcpy(&(ctx->rx_ncm.ndp16), ((u8 *)skb_in->data) + temp, - sizeof(ctx->rx_ncm.ndp16)); + ndp16 = (struct usb_cdc_ncm_ndp16 *)(((u8 *)skb_in->data) + len); - if (le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature) != - USB_CDC_NCM_NDP16_NOCRC_SIGN) { + if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) { pr_debug("invalid DPT16 signature <%u>\n", - le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature)); + le32_to_cpu(ndp16->dwSignature)); goto error; } - if (le16_to_cpu(ctx->rx_ncm.ndp16.wLength) < - USB_CDC_NCM_NDP16_LENGTH_MIN) { + if (le16_to_cpu(ndp16->wLength) < USB_CDC_NCM_NDP16_LENGTH_MIN) { pr_debug("invalid DPT16 length <%u>\n", - le32_to_cpu(ctx->rx_ncm.ndp16.dwSignature)); + le32_to_cpu(ndp16->dwSignature)); goto error; } - nframes = ((le16_to_cpu(ctx->rx_ncm.ndp16.wLength) - + nframes = ((le16_to_cpu(ndp16->wLength) - sizeof(struct usb_cdc_ncm_ndp16)) / sizeof(struct usb_cdc_ncm_dpe16)); nframes--; /* we process NDP entries except for the last one */ - pr_debug("nframes = %u\n", nframes); - - temp += sizeof(ctx->rx_ncm.ndp16); + len += sizeof(struct usb_cdc_ncm_ndp16); - if ((temp + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) > actlen) { + if ((len + nframes * (sizeof(struct usb_cdc_ncm_dpe16))) > + skb_in->len) { pr_debug("Invalid nframes = %d\n", nframes); goto error; } - if (nframes > CDC_NCM_DPT_DATAGRAMS_MAX) { - pr_debug("Truncating number of frames from %u to %u\n", - nframes, CDC_NCM_DPT_DATAGRAMS_MAX); - nframes = CDC_NCM_DPT_DATAGRAMS_MAX; - } - - memcpy(&(ctx->rx_ncm.dpe16), ((u8 *)skb_in->data) + temp, - nframes * (sizeof(struct usb_cdc_ncm_dpe16))); + dpe16 = (struct usb_cdc_ncm_dpe16 *)(((u8 *)skb_in->data) + len); - for (x = 0; x < nframes; x++) { - offset = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramIndex); - temp = le16_to_cpu(ctx->rx_ncm.dpe16[x].wDatagramLength); + for (x = 0; x < nframes; x++, dpe16++) { + offset = le16_to_cpu(dpe16->wDatagramIndex); + len = le16_to_cpu(dpe16->wDatagramLength); /* * CDC NCM ch. 3.7 * All entries after first NULL entry are to be ignored */ - if ((offset == 0) || (temp == 0)) { + if ((offset == 0) || (len == 0)) { if (!x) goto error; /* empty NTB */ break; } /* sanity checking */ - if (((offset + temp) > actlen) || - (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) { + if (((offset + len) > skb_in->len) || + (len > ctx->rx_max) || (len < ETH_HLEN)) { pr_debug("invalid frame detected (ignored)" "offset[%u]=%u, length=%u, skb=%p\n", - x, offset, temp, skb_in); + x, offset, len, skb_in); if (!x) goto error; break; @@ -1060,9 +1058,9 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) skb = skb_clone(skb_in, GFP_ATOMIC); if (!skb) goto error; - skb->len = temp; + skb->len = len; skb->data = ((u8 *)skb_in->data) + offset; - skb_set_tail_pointer(skb, temp); + skb_set_tail_pointer(skb, len); usbnet_skb_return(dev, skb); } } diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 83dcc530618e..4b8b52ca09d8 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -328,13 +328,13 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) unsigned long lockflags; size_t size = dev->rx_urb_size; - if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { + skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); + if (!skb) { netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); usbnet_defer_kevent (dev, EVENT_RX_MEMORY); usb_free_urb (urb); return -ENOMEM; } - skb_reserve (skb, NET_IP_ALIGN); entry = (struct skb_data *) skb->cb; entry->urb = urb; @@ -1535,7 +1535,7 @@ int usbnet_resume (struct usb_interface *intf) if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { if (!(dev->txq.qlen >= TX_QLEN(dev))) - netif_start_queue(dev->net); + netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); } } diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c index 64a110604ad3..63e4b709efa9 100644 --- a/drivers/net/wimax/i2400m/netdev.c +++ b/drivers/net/wimax/i2400m/netdev.c @@ -367,38 +367,28 @@ netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb, { struct i2400m *i2400m = net_dev_to_i2400m(net_dev); struct device *dev = i2400m_dev(i2400m); - int result; + int result = -1; d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); - if (skb_header_cloned(skb)) { - /* - * Make tcpdump/wireshark happy -- if they are - * running, the skb is cloned and we will overwrite - * the mac fields in i2400m_tx_prep_header. Expand - * seems to fix this... - */ - result = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); - if (result) { - result = NETDEV_TX_BUSY; - goto error_expand; - } - } + + if (skb_header_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto drop; if (i2400m->state == I2400M_SS_IDLE) result = i2400m_net_wake_tx(i2400m, net_dev, skb); else result = i2400m_net_tx(i2400m, net_dev, skb); - if (result < 0) + if (result < 0) { +drop: net_dev->stats.tx_dropped++; - else { + } else { net_dev->stats.tx_packets++; net_dev->stats.tx_bytes += skb->len; } - result = NETDEV_TX_OK; -error_expand: - kfree_skb(skb); + dev_kfree_skb(skb); d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result); - return result; + return NETDEV_TX_OK; } diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index efc01110dc34..c54b7d37bff1 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -174,28 +174,24 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); -extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...); - -#define _ath_printk(level, common, fmt, ...) \ -do { \ - __always_unused struct ath_common *unused = common; \ - ath_printk(level, fmt, ##__VA_ARGS__); \ -} while (0) +__printf(3, 4) +void ath_printk(const char *level, const struct ath_common *common, + const char *fmt, ...); #define ath_emerg(common, fmt, ...) \ - _ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) #define ath_alert(common, fmt, ...) \ - _ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) #define ath_crit(common, fmt, ...) \ - _ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) #define ath_err(common, fmt, ...) \ - _ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) #define ath_warn(common, fmt, ...) \ - _ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) #define ath_notice(common, fmt, ...) \ - _ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) #define ath_info(common, fmt, ...) \ - _ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) /** * enum ath_debug_level - atheros wireless debug level @@ -256,7 +252,7 @@ enum ATH_DEBUG { #define ath_dbg(common, dbg_mask, fmt, ...) \ do { \ if ((common)->debug_mask & ATH_DBG_##dbg_mask) \ - _ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ + ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ } while (0) #define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 9ba42fa04962..85746c3eb027 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -1,5 +1,6 @@ #------------------------------------------------------------------------------ -# Copyright (c) 2004-2010 Atheros Communications Inc. +# Copyright (c) 2004-2011 Atheros Communications Inc. +# Copyright (c) 2011-2012 Qualcomm Atheros, Inc. # All rights reserved. # # diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index aef00d5a1438..334dbd834b3a 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -105,7 +106,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, } ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n", - targ_info->version, targ_info->type); + targ_info->version, targ_info->type); return 0; } @@ -192,7 +193,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header); ath6kl_dbg(ATH6KL_DBG_BMI, - "bmi write memory: addr: 0x%x, len: %d\n", addr, len); + "bmi write memory: addr: 0x%x, len: %d\n", addr, len); len_remain = len; while (len_remain) { @@ -434,7 +435,7 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len) memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len)); offset += sizeof(tx_len); memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain], - tx_len); + tx_len); offset += tx_len; ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h index f1ca6812456d..18fdd69e1f71 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.h +++ b/drivers/net/wireless/ath/ath6kl/bmi.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -222,6 +223,29 @@ struct ath6kl_bmi_target_info { __le32 type; /* target type */ } __packed; +#define ath6kl_bmi_write_hi32(ar, item, val) \ + ({ \ + u32 addr; \ + __le32 v; \ + \ + addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ + v = cpu_to_le32(val); \ + ath6kl_bmi_write(ar, addr, (u8 *) &v, sizeof(v)); \ + }) + +#define ath6kl_bmi_read_hi32(ar, item, val) \ + ({ \ + u32 addr, *check_type = val; \ + __le32 tmp; \ + int ret; \ + \ + (void) (check_type == val); \ + addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ + ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \ + *val = le32_to_cpu(tmp); \ + ret; \ + }) + int ath6kl_bmi_init(struct ath6kl *ar); void ath6kl_bmi_cleanup(struct ath6kl *ar); void ath6kl_bmi_reset(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5370333883e4..00d38952b5fb 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -68,6 +69,10 @@ static struct ieee80211_rate ath6kl_rates[] = { #define ath6kl_g_rates (ath6kl_rates + 0) #define ath6kl_g_rates_size 12 +#define ath6kl_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ + IEEE80211_HT_CAP_SGI_20 | \ + IEEE80211_HT_CAP_SGI_40) + static struct ieee80211_channel ath6kl_2ghz_channels[] = { CHAN2G(1, 2412, 0), CHAN2G(2, 2417, 0), @@ -112,6 +117,8 @@ static struct ieee80211_supported_band ath6kl_band_2ghz = { .channels = ath6kl_2ghz_channels, .n_bitrates = ath6kl_g_rates_size, .bitrates = ath6kl_g_rates, + .ht_cap.cap = ath6kl_g_htcap, + .ht_cap.ht_supported = true, }; static struct ieee80211_supported_band ath6kl_band_5ghz = { @@ -119,6 +126,8 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = { .channels = ath6kl_5ghz_a_channels, .n_bitrates = ath6kl_a_rates_size, .bitrates = ath6kl_a_rates, + .ht_cap.cap = ath6kl_g_htcap, + .ht_cap.ht_supported = true, }; #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */ @@ -381,7 +390,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, return false; if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) && - ar->num_vif)) + ar->num_vif)) return false; if (type == NL80211_IFTYPE_STATION || @@ -407,6 +416,12 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, return false; } +static bool ath6kl_is_tx_pending(struct ath6kl *ar) +{ + return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0; +} + + static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { @@ -414,6 +429,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct ath6kl_vif *vif = netdev_priv(dev); int status; u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE; + u16 interval; ath6kl_cfg80211_sscan_disable(vif); @@ -450,8 +466,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, * sleep until the command queue drains */ wait_event_interruptible_timeout(ar->event_wq, - ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0, - WMI_TIMEOUT); + ath6kl_is_tx_pending(ar), + WMI_TIMEOUT); if (signal_pending(current)) { ath6kl_err("cmd queue drain timeout\n"); up(&ar->sem); @@ -546,7 +562,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if (!ar->usr_bss_filter) { clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - ALL_BSS_FILTER, 0) != 0) { + ALL_BSS_FILTER, 0) != 0) { ath6kl_err("couldn't set bss filtering\n"); up(&ar->sem); return -EIO; @@ -568,6 +584,20 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, vif->grp_crypto_len, vif->ch_hint); vif->reconnect_flag = 0; + + if (vif->nw_type == INFRA_NETWORK) { + interval = max_t(u16, vif->listen_intvl_t, + ATH6KL_MAX_WOW_LISTEN_INTL); + status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + interval, + 0); + if (status) { + ath6kl_err("couldn't set listen intervel\n"); + up(&ar->sem); + return status; + } + } + status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type, vif->dot11_auth_mode, vif->auth_mode, vif->prwise_crypto, @@ -590,8 +620,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) && - ((vif->auth_mode == WPA_PSK_AUTH) - || (vif->auth_mode == WPA2_PSK_AUTH))) { + ((vif->auth_mode == WPA_PSK_AUTH) || + (vif->auth_mode == WPA2_PSK_AUTH))) { mod_timer(&vif->disconnect_timer, jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL)); } @@ -824,13 +854,13 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, if (vif->sme_state == SME_CONNECTING) { cfg80211_connect_result(vif->ndev, - bssid, NULL, 0, - NULL, 0, - WLAN_STATUS_UNSPECIFIED_FAILURE, - GFP_KERNEL); + bssid, NULL, 0, + NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); } else if (vif->sme_state == SME_CONNECTED) { cfg80211_disconnected(vif->ndev, reason, - NULL, 0, GFP_KERNEL); + NULL, 0, GFP_KERNEL); } vif->sme_state = SME_DISCONNECTED; @@ -876,19 +906,14 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, request->ssids[i].ssid); } - /* - * FIXME: we should clear the IE in fw if it's not set so just - * remove the check altogether - */ - if (request->ie) { - ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_PROBE_REQ, - request->ie, request->ie_len); - if (ret) { - ath6kl_err("failed to set Probe Request appie for " - "scan"); - return ret; - } + /* this also clears IE in fw if it's not set */ + ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, + WMI_FRAME_PROBE_REQ, + request->ie, request->ie_len); + if (ret) { + ath6kl_err("failed to set Probe Request appie for " + "scan"); + return ret; } /* @@ -917,7 +942,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, force_fg_scan = 1; if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, - ar->fw_capabilities)) { + ar->fw_capabilities)) { /* * If capable of doing P2P mgmt operations using * station interface, send additional information like @@ -926,14 +951,17 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, */ ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN, force_fg_scan, - false, 0, 0, n_channels, - channels, request->no_cck, + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels, + request->no_cck, request->rates); } else { ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN, force_fg_scan, - false, 0, 0, n_channels, - channels); + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels); } if (ret) ath6kl_err("wmi_startscan_cmd failed\n"); @@ -1046,9 +1074,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, return -ENOTSUPP; } - if (((vif->auth_mode == WPA_PSK_AUTH) - || (vif->auth_mode == WPA2_PSK_AUTH)) - && (key_usage & GROUP_USAGE)) + if (((vif->auth_mode == WPA_PSK_AUTH) || + (vif->auth_mode == WPA2_PSK_AUTH)) && + (key_usage & GROUP_USAGE)) del_timer(&vif->disconnect_timer); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, @@ -1058,7 +1086,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, if (vif->nw_type == AP_NETWORK && !pairwise && (key_type == TKIP_CRYPT || key_type == AES_CRYPT || - key_type == WAPI_CRYPT) && params) { + key_type == WAPI_CRYPT)) { ar->ap_mode_bkey.valid = true; ar->ap_mode_bkey.key_index = key_index; ar->ap_mode_bkey.key_type = key_type; @@ -1263,7 +1291,6 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, { struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); struct ath6kl_vif *vif; - u8 ath6kl_dbm; int dbm = MBM_TO_DBM(mbm); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__, @@ -1280,7 +1307,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, case NL80211_TX_POWER_AUTOMATIC: return 0; case NL80211_TX_POWER_LIMITED: - ar->tx_pwr = ath6kl_dbm = dbm; + ar->tx_pwr = dbm; break; default: ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n", @@ -1288,7 +1315,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, return -EOPNOTSUPP; } - ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm); + ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm); return 0; } @@ -1349,7 +1376,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, } if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx, - mode.pwr_mode) != 0) { + mode.pwr_mode) != 0) { ath6kl_err("wmi_powermode_cmd failed\n"); return -EIO; } @@ -1904,7 +1931,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) struct ath6kl_vif *vif; int ret, left; u32 filter = 0; - u16 i; + u16 i, bmiss_time; u8 index = 0; __be32 ips[MAX_IP_ADDRS]; @@ -1941,6 +1968,34 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) if (ret) return ret; + netif_stop_queue(vif->ndev); + + if (vif->nw_type != AP_NETWORK) { + ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_MAX_WOW_LISTEN_INTL, + 0); + if (ret) + return ret; + + /* Set listen interval x 15 times as bmiss time */ + bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15; + if (bmiss_time > ATH6KL_MAX_BMISS_TIME) + bmiss_time = ATH6KL_MAX_BMISS_TIME; + + ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx, + bmiss_time, 0); + if (ret) + return ret; + + ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, + 0xFFFF, 0, 0xFFFF, 0, 0, 0, + 0, 0, 0, 0); + if (ret) + return ret; + } + + ar->state = ATH6KL_STATE_SUSPENDING; + /* Setup own IP addr for ARP agent. */ in_dev = __in_dev_get_rtnl(vif->ndev); if (!in_dev) @@ -2019,15 +2074,46 @@ static int ath6kl_wow_resume(struct ath6kl *ar) if (!vif) return -EIO; + ar->state = ATH6KL_STATE_RESUMING; + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_HOST_MODE_AWAKE); - return ret; + if (ret) { + ath6kl_warn("Failed to configure host sleep mode for " + "wow resume: %d\n", ret); + ar->state = ATH6KL_STATE_WOW; + return ret; + } + + if (vif->nw_type != AP_NETWORK) { + ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); + if (ret) + return ret; + + ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + vif->listen_intvl_t, 0); + if (ret) + return ret; + + ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx, + vif->bmiss_time_t, 0); + if (ret) + return ret; + } + + ar->state = ATH6KL_STATE_ON; + + netif_wake_queue(vif->ndev); + + return 0; } int ath6kl_cfg80211_suspend(struct ath6kl *ar, enum ath6kl_cfg_suspend_mode mode, struct cfg80211_wowlan *wow) { + enum ath6kl_state prev_state; int ret; switch (mode) { @@ -2038,11 +2124,14 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, /* Flush all non control pkts in TX path */ ath6kl_tx_data_cleanup(ar); + prev_state = ar->state; + ret = ath6kl_wow_suspend(ar, wow); if (ret) { - ath6kl_err("wow suspend failed: %d\n", ret); + ar->state = prev_state; return ret; } + ar->state = ATH6KL_STATE_WOW; break; @@ -2114,7 +2203,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) return ret; } - ar->state = ATH6KL_STATE_ON; break; case ATH6KL_STATE_DEEPSLEEP: @@ -2188,6 +2276,9 @@ static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) */ void ath6kl_check_wow_status(struct ath6kl *ar) { + if (ar->state == ATH6KL_STATE_SUSPENDING) + return; + if (ar->state == ATH6KL_STATE_WOW) ath6kl_cfg80211_resume(ar); } @@ -2275,30 +2366,27 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif, struct ath6kl *ar = vif->ar; int res; - if (info->beacon_ies) { - res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_BEACON, - info->beacon_ies, - info->beacon_ies_len); - if (res) - return res; - } + /* this also clears IE in fw if it's not set */ + res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, + WMI_FRAME_BEACON, + info->beacon_ies, + info->beacon_ies_len); + if (res) + return res; - if (info->proberesp_ies) { - res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies, - info->proberesp_ies_len); - if (res) - return res; - } + /* this also clears IE in fw if it's not set */ + res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies, + info->proberesp_ies_len); + if (res) + return res; - if (info->assocresp_ies) { - res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_ASSOC_RESP, - info->assocresp_ies, - info->assocresp_ies_len); - if (res) - return res; - } + /* this also clears IE in fw if it's not set */ + res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, + WMI_FRAME_ASSOC_RESP, + info->assocresp_ies, + info->assocresp_ies_len); + if (res) + return res; return 0; } @@ -2309,6 +2397,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); struct ieee80211_mgmt *mgmt; + bool hidden = false; u8 *ies; int ies_len; struct wmi_connect_cmd p; @@ -2345,7 +2434,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, memcpy(vif->ssid, info->ssid, info->ssid_len); vif->ssid_len = info->ssid_len; if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) - return -EOPNOTSUPP; /* TODO */ + hidden = true; + + res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden); + if (res) + return res; ret = ath6kl_set_auth_type(vif, info->auth_type); if (ret) @@ -2584,6 +2677,76 @@ static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif, return ret; } +static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif, + u32 id, + u32 freq, + u32 wait, + const u8 *buf, + size_t len, + bool *more_data, + bool no_cck) +{ + struct ieee80211_mgmt *mgmt; + struct ath6kl_sta *conn; + bool is_psq_empty = false; + struct ath6kl_mgmt_buff *mgmt_buf; + size_t mgmt_buf_size; + struct ath6kl *ar = vif->ar; + + mgmt = (struct ieee80211_mgmt *) buf; + if (is_multicast_ether_addr(mgmt->da)) + return false; + + conn = ath6kl_find_sta(vif, mgmt->da); + if (!conn) + return false; + + if (conn->sta_flags & STA_PS_SLEEP) { + if (!(conn->sta_flags & STA_PS_POLLED)) { + /* Queue the frames if the STA is sleeping */ + mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff); + mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL); + if (!mgmt_buf) + return false; + + INIT_LIST_HEAD(&mgmt_buf->list); + mgmt_buf->id = id; + mgmt_buf->freq = freq; + mgmt_buf->wait = wait; + mgmt_buf->len = len; + mgmt_buf->no_cck = no_cck; + memcpy(mgmt_buf->buf, buf, len); + spin_lock_bh(&conn->psq_lock); + is_psq_empty = skb_queue_empty(&conn->psq) && + (conn->mgmt_psq_len == 0); + list_add_tail(&mgmt_buf->list, &conn->mgmt_psq); + conn->mgmt_psq_len++; + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this + * STA. + */ + if (is_psq_empty) + ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, + conn->aid, 1); + return true; + } + + /* + * This tx is because of a PsPoll. + * Determine if MoreData bit has to be set. + */ + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0)) + *more_data = true; + spin_unlock_bh(&conn->psq_lock); + } + + return false; +} + static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, bool offchan, enum nl80211_channel_type channel_type, @@ -2595,6 +2758,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ath6kl_vif *vif = netdev_priv(dev); u32 id; const struct ieee80211_mgmt *mgmt; + bool more_data, queued; mgmt = (const struct ieee80211_mgmt *) buf; if (buf + len >= mgmt->u.probe_resp.variable && @@ -2620,22 +2784,19 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, *cookie = id; - if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, - ar->fw_capabilities)) { - /* - * If capable of doing P2P mgmt operations using - * station interface, send additional information like - * supported rates to advertise and xmit rates for - * probe requests - */ - return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, - chan->center_freq, wait, - buf, len, no_cck); - } else { - return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id, - chan->center_freq, wait, - buf, len); + /* AP mode Power saving processing */ + if (vif->nw_type == AP_NETWORK) { + queued = ath6kl_mgmt_powersave_ap(vif, + id, chan->center_freq, + wait, buf, + len, &more_data, no_cck); + if (queued) + return 0; } + + return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, + chan->center_freq, wait, + buf, len, no_cck); } static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, @@ -2929,7 +3090,10 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, vif->wdev.netdev = ndev; vif->wdev.iftype = type; vif->fw_vif_idx = fw_vif_idx; - vif->nw_type = vif->next_mode = nw_type; + vif->nw_type = nw_type; + vif->next_mode = nw_type; + vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; + vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); if (fw_vif_idx != 0) @@ -3009,18 +3173,36 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) wiphy->max_sched_scan_ssids = 10; + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | + WIPHY_FLAG_HAVE_AP_SME | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | + WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; + + if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + + ar->wiphy->probe_resp_offload = + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; + ret = wiphy_register(wiphy); if (ret < 0) { ath6kl_err("couldn't register wiphy device\n"); return ret; } + ar->wiphy_registered = true; + return 0; } void ath6kl_cfg80211_cleanup(struct ath6kl *ar) { wiphy_unregister(ar->wiphy); + + ar->wiphy_registered = false; } struct ath6kl *ath6kl_cfg80211_create(void) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 3c693b7c0efd..c5def436417f 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index f89f1e180da3..a60e78c0472f 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 722ca59b88ce..45e641f3a41b 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -26,12 +27,14 @@ unsigned int debug_mask; static unsigned int suspend_mode; +static unsigned int wow_mode; static unsigned int uart_debug; static unsigned int ath6kl_p2p; static unsigned int testmode; module_param(debug_mask, uint, 0644); module_param(suspend_mode, uint, 0644); +module_param(wow_mode, uint, 0644); module_param(uart_debug, uint, 0644); module_param(ath6kl_p2p, uint, 0644); module_param(testmode, uint, 0644); @@ -97,48 +100,12 @@ int ath6kl_core_init(struct ath6kl *ar) ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); - ret = ath6kl_cfg80211_init(ar); - if (ret) - goto err_node_cleanup; - - ret = ath6kl_debug_init(ar); - if (ret) { - wiphy_unregister(ar->wiphy); - goto err_node_cleanup; - } - - for (i = 0; i < ar->vif_max; i++) - ar->avail_idx_map |= BIT(i); - - rtnl_lock(); - - /* Add an initial station interface */ - ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, - INFRA_NETWORK); - - rtnl_unlock(); - - if (!ndev) { - ath6kl_err("Failed to instantiate a network device\n"); - ret = -ENOMEM; - wiphy_unregister(ar->wiphy); - goto err_debug_init; - } - - - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", - __func__, ndev->name, ndev, ar); - /* setup access class priority mappings */ ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ ar->ac_stream_pri_map[WMM_AC_BE] = 1; ar->ac_stream_pri_map[WMM_AC_VI] = 2; ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ - /* give our connected endpoints some buffers */ - ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); - ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); - /* allocate some buffers that handle larger AMSDU frames */ ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); @@ -148,32 +115,25 @@ int ath6kl_core_init(struct ath6kl *ar) ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; if (suspend_mode && - suspend_mode >= WLAN_POWER_STATE_CUT_PWR && - suspend_mode <= WLAN_POWER_STATE_WOW) + suspend_mode >= WLAN_POWER_STATE_CUT_PWR && + suspend_mode <= WLAN_POWER_STATE_WOW) ar->suspend_mode = suspend_mode; else ar->suspend_mode = 0; + if (suspend_mode == WLAN_POWER_STATE_WOW && + (wow_mode == WLAN_POWER_STATE_CUT_PWR || + wow_mode == WLAN_POWER_STATE_DEEP_SLEEP)) + ar->wow_suspend_mode = wow_mode; + else + ar->wow_suspend_mode = 0; + if (uart_debug) ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | - WIPHY_FLAG_HAVE_AP_SME | - WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - - if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; - - ar->wiphy->probe_resp_offload = - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; - set_bit(FIRST_BOOT, &ar->flag); - ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + ath6kl_debug_init(ar); ret = ath6kl_init_hw_start(ar); if (ret) { @@ -181,24 +141,47 @@ int ath6kl_core_init(struct ath6kl *ar) goto err_rxbuf_cleanup; } - /* - * Set mac address which is received in ready event - * FIXME: Move to ath6kl_interface_add() - */ - memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); + /* give our connected endpoints some buffers */ + ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); + ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); + + ret = ath6kl_cfg80211_init(ar); + if (ret) + goto err_rxbuf_cleanup; + + ret = ath6kl_debug_init_fs(ar); + if (ret) { + wiphy_unregister(ar->wiphy); + goto err_rxbuf_cleanup; + } + + for (i = 0; i < ar->vif_max; i++) + ar->avail_idx_map |= BIT(i); + + rtnl_lock(); + + /* Add an initial station interface */ + ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, + INFRA_NETWORK); + + rtnl_unlock(); + + if (!ndev) { + ath6kl_err("Failed to instantiate a network device\n"); + ret = -ENOMEM; + wiphy_unregister(ar->wiphy); + goto err_rxbuf_cleanup; + } + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", + __func__, ndev->name, ndev, ar); return ret; err_rxbuf_cleanup: + ath6kl_debug_cleanup(ar); ath6kl_htc_flush_rx_buf(ar->htc_target); ath6kl_cleanup_amsdu_rxbufs(ar); - rtnl_lock(); - ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); - rtnl_unlock(); - wiphy_unregister(ar->wiphy); -err_debug_init: - ath6kl_debug_cleanup(ar); -err_node_cleanup: ath6kl_wmi_shutdown(ar->wmi); clear_bit(WMI_ENABLED, &ar->flag); ar->wmi = NULL; @@ -245,9 +228,7 @@ struct ath6kl *ath6kl_core_create(struct device *dev) clear_bit(SKIP_SCAN, &ar->flag); clear_bit(DESTROY_IN_PROGRESS, &ar->flag); - ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; ar->tx_pwr = 0; - ar->intra_bss = 1; ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; @@ -261,6 +242,8 @@ struct ath6kl *ath6kl_core_create(struct device *dev) spin_lock_init(&ar->sta_list[ctr].psq_lock); skb_queue_head_init(&ar->sta_list[ctr].psq); skb_queue_head_init(&ar->sta_list[ctr].apsdq); + ar->sta_list[ctr].mgmt_psq_len = 0; + INIT_LIST_HEAD(&ar->sta_list[ctr].mgmt_psq); ar->sta_list[ctr].aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); if (!ar->sta_list[ctr].aggr_conn) { diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c4d66e066dc9..f1dd8906be45 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -59,8 +60,9 @@ #define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) #define DISCON_TIMER_INTVAL 10000 /* in msec */ -#define A_DEFAULT_LISTEN_INTERVAL 1 /* beacon intervals */ -#define A_MAX_WOW_LISTEN_INTERVAL 1000 + +/* Channel dwell time in fg scan */ +#define ATH6KL_FG_SCAN_INTERVAL 50 /* in ms */ /* includes also the null byte */ #define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL" @@ -183,6 +185,11 @@ struct ath6kl_fw_ie { #define MBOX_YIELD_LIMIT 99 +#define ATH6KL_DEFAULT_LISTEN_INTVAL 100 /* in TUs */ +#define ATH6KL_DEFAULT_BMISS_TIME 1500 +#define ATH6KL_MAX_WOW_LISTEN_INTL 300 /* in TUs */ +#define ATH6KL_MAX_BMISS_TIME 5000 + /* configuration lags */ /* * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in @@ -226,6 +233,12 @@ struct rxtid { u32 hold_q_sz; struct skb_hold_q *hold_q; struct sk_buff_head q; + + /* + * FIXME: No clue what this should protect. Apparently it should + * protect some of the fields above but they are also accessed + * without taking the lock. + */ spinlock_t lock; }; @@ -285,6 +298,16 @@ struct ath6kl_cookie { struct ath6kl_cookie *arc_list_next; }; +struct ath6kl_mgmt_buff { + struct list_head list; + u32 freq; + u32 wait; + u32 id; + bool no_cck; + size_t len; + u8 buf[0]; +}; + struct ath6kl_sta { u16 sta_flags; u8 mac[ETH_ALEN]; @@ -294,7 +317,12 @@ struct ath6kl_sta { u8 auth; u8 wpa_ie[ATH6KL_MAX_IE]; struct sk_buff_head psq; + + /* protects psq, mgmt_psq, apsdq, and mgmt_psq_len fields */ spinlock_t psq_lock; + + struct list_head mgmt_psq; + size_t mgmt_psq_len; u8 apsd_info; struct sk_buff_head apsdq; struct aggr_info_conn *aggr_conn; @@ -494,6 +522,8 @@ struct ath6kl_vif { bool probe_req_report; u16 next_chan; u16 assoc_bss_beacon_int; + u16 listen_intvl_t; + u16 bmiss_time_t; u8 assoc_bss_dtim_period; struct net_device_stats net_stats; struct target_stats target_stats; @@ -521,6 +551,8 @@ enum ath6kl_dev_state { enum ath6kl_state { ATH6KL_STATE_OFF, ATH6KL_STATE_ON, + ATH6KL_STATE_SUSPENDING, + ATH6KL_STATE_RESUMING, ATH6KL_STATE_DEEPSLEEP, ATH6KL_STATE_CUTPOWER, ATH6KL_STATE_WOW, @@ -549,9 +581,14 @@ struct ath6kl { unsigned int vif_max; u8 max_norm_iface; u8 avail_idx_map; + + /* + * Protects at least amsdu_rx_buffer_queue, ath6kl_alloc_cookie() + * calls, tx_pending and total_tx_data_pend. + */ spinlock_t lock; + struct semaphore sem; - u16 listen_intvl_b; u8 lrssi_roam_threshold; struct ath6kl_version version; u32 target_type; @@ -577,7 +614,13 @@ struct ath6kl { u8 sta_list_index; struct ath6kl_req_key ap_mode_bkey; struct sk_buff_head mcastpsq; + + /* + * FIXME: protects access to mcastpsq but is actually useless as + * all skbe_queue_*() functions provide serialisation themselves + */ spinlock_t mcastpsq_lock; + u8 intra_bss; struct wmi_ap_mode_stat ap_stats; u8 ap_country_code[3]; @@ -620,6 +663,7 @@ struct ath6kl { u16 conf_flags; u16 suspend_mode; + u16 wow_suspend_mode; wait_queue_head_t event_wq; struct ath6kl_mbox_info mbox_info; @@ -650,12 +694,16 @@ struct ath6kl { bool p2p; + bool wiphy_registered; + #ifdef CONFIG_ATH6KL_DEBUG struct { - struct circ_buf fwlog_buf; - spinlock_t fwlog_lock; - void *fwlog_tmp; + struct sk_buff_head fwlog_queue; + struct completion fwlog_completion; + bool fwlog_open; + u32 fwlog_mask; + unsigned int dbgfs_diag_reg; u32 diag_reg_addr_wr; u32 diag_reg_val_wr; @@ -727,10 +775,10 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target, void aggr_module_destroy(struct aggr_info *aggr_info); void aggr_reset_state(struct aggr_info_conn *aggr_conn); -struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); +struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr); struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); -void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver); +void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver); int ath6kl_control_tx(void *devt, struct sk_buff *skb, enum htc_endpoint_id eid); void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index d832058816fe..552adb3f80d0 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +17,7 @@ #include "core.h" -#include <linux/circ_buf.h> +#include <linux/skbuff.h> #include <linux/fs.h> #include <linux/vmalloc.h> #include <linux/export.h> @@ -32,9 +33,8 @@ struct ath6kl_fwlog_slot { u8 payload[0]; }; -#define ATH6KL_FWLOG_SIZE 32768 -#define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \ - ATH6KL_FWLOG_PAYLOAD_SIZE) +#define ATH6KL_FWLOG_MAX_ENTRIES 20 + #define ATH6KL_FWLOG_VALID_MASK 0x1ffff int ath6kl_printk(const char *level, const char *fmt, ...) @@ -119,29 +119,29 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, if (irq_proc_reg != NULL) { ath6kl_dbg(ATH6KL_DBG_IRQ, - "Host Int status: 0x%x\n", - irq_proc_reg->host_int_status); + "Host Int status: 0x%x\n", + irq_proc_reg->host_int_status); ath6kl_dbg(ATH6KL_DBG_IRQ, "CPU Int status: 0x%x\n", - irq_proc_reg->cpu_int_status); + irq_proc_reg->cpu_int_status); ath6kl_dbg(ATH6KL_DBG_IRQ, "Error Int status: 0x%x\n", - irq_proc_reg->error_int_status); + irq_proc_reg->error_int_status); ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status: 0x%x\n", - irq_proc_reg->counter_int_status); + irq_proc_reg->counter_int_status); ath6kl_dbg(ATH6KL_DBG_IRQ, "Mbox Frame: 0x%x\n", - irq_proc_reg->mbox_frame); + irq_proc_reg->mbox_frame); ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead Valid: 0x%x\n", - irq_proc_reg->rx_lkahd_valid); + irq_proc_reg->rx_lkahd_valid); ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 0: 0x%x\n", - irq_proc_reg->rx_lkahd[0]); + irq_proc_reg->rx_lkahd[0]); ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 1: 0x%x\n", - irq_proc_reg->rx_lkahd[1]); + irq_proc_reg->rx_lkahd[1]); if (dev->ar->mbox_info.gmbox_addr != 0) { /* @@ -149,27 +149,27 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, * additional state. */ ath6kl_dbg(ATH6KL_DBG_IRQ, - "GMBOX Host Int status 2: 0x%x\n", - irq_proc_reg->host_int_status2); + "GMBOX Host Int status 2: 0x%x\n", + irq_proc_reg->host_int_status2); ath6kl_dbg(ATH6KL_DBG_IRQ, - "GMBOX RX Avail: 0x%x\n", - irq_proc_reg->gmbox_rx_avail); + "GMBOX RX Avail: 0x%x\n", + irq_proc_reg->gmbox_rx_avail); ath6kl_dbg(ATH6KL_DBG_IRQ, - "GMBOX lookahead alias 0: 0x%x\n", - irq_proc_reg->rx_gmbox_lkahd_alias[0]); + "GMBOX lookahead alias 0: 0x%x\n", + irq_proc_reg->rx_gmbox_lkahd_alias[0]); ath6kl_dbg(ATH6KL_DBG_IRQ, - "GMBOX lookahead alias 1: 0x%x\n", - irq_proc_reg->rx_gmbox_lkahd_alias[1]); + "GMBOX lookahead alias 1: 0x%x\n", + irq_proc_reg->rx_gmbox_lkahd_alias[1]); } } if (irq_enable_reg != NULL) { ath6kl_dbg(ATH6KL_DBG_IRQ, - "Int status Enable: 0x%x\n", - irq_enable_reg->int_status_en); + "Int status Enable: 0x%x\n", + irq_enable_reg->int_status_en); ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n", - irq_enable_reg->cntr_int_status_en); + irq_enable_reg->cntr_int_status_en); } ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n"); } @@ -268,105 +268,103 @@ static const struct file_operations fops_war_stats = { .llseek = default_llseek, }; -static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf, - size_t buf_len) +void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) { - struct circ_buf *fwlog = &ar->debug.fwlog_buf; - size_t space; - int i; + struct ath6kl_fwlog_slot *slot; + struct sk_buff *skb; + size_t slot_len; - /* entries must all be equal size */ - if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE)) + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) return; - space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE); - if (space < buf_len) - /* discard oldest slot */ - fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) & - (ATH6KL_FWLOG_SIZE - 1); + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE; - for (i = 0; i < buf_len; i += space) { - space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail, - ATH6KL_FWLOG_SIZE); + skb = alloc_skb(slot_len, GFP_KERNEL); + if (!skb) + return; - if ((size_t) space > buf_len - i) - space = buf_len - i; + slot = (struct ath6kl_fwlog_slot *) skb_put(skb, slot_len); + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(len); + memcpy(slot->payload, buf, len); - memcpy(&fwlog->buf[fwlog->head], buf, space); - fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1); - } + /* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */ + memset(slot->payload + len, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - len); -} + spin_lock(&ar->debug.fwlog_queue.lock); -void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) -{ - struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp; - size_t slot_len; + __skb_queue_tail(&ar->debug.fwlog_queue, skb); + complete(&ar->debug.fwlog_completion); - if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) - return; + /* drop oldest entries */ + while (skb_queue_len(&ar->debug.fwlog_queue) > + ATH6KL_FWLOG_MAX_ENTRIES) { + skb = __skb_dequeue(&ar->debug.fwlog_queue); + kfree_skb(skb); + } - spin_lock_bh(&ar->debug.fwlog_lock); + spin_unlock(&ar->debug.fwlog_queue.lock); - slot->timestamp = cpu_to_le32(jiffies); - slot->length = cpu_to_le32(len); - memcpy(slot->payload, buf, len); + return; +} - slot_len = sizeof(*slot) + len; +static int ath6kl_fwlog_open(struct inode *inode, struct file *file) +{ + struct ath6kl *ar = inode->i_private; - if (slot_len < ATH6KL_FWLOG_SLOT_SIZE) - memset(slot->payload + len, 0, - ATH6KL_FWLOG_SLOT_SIZE - slot_len); + if (ar->debug.fwlog_open) + return -EBUSY; - ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE); + ar->debug.fwlog_open = true; - spin_unlock_bh(&ar->debug.fwlog_lock); + file->private_data = inode->i_private; + return 0; } -static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar) +static int ath6kl_fwlog_release(struct inode *inode, struct file *file) { - return CIRC_CNT(ar->debug.fwlog_buf.head, - ar->debug.fwlog_buf.tail, - ATH6KL_FWLOG_SLOT_SIZE) == 0; + struct ath6kl *ar = inode->i_private; + + ar->debug.fwlog_open = false; + + return 0; } static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - struct circ_buf *fwlog = &ar->debug.fwlog_buf; - size_t len = 0, buf_len = count; + struct sk_buff *skb; ssize_t ret_cnt; + size_t len = 0; char *buf; - int ccnt; - buf = vmalloc(buf_len); + buf = vmalloc(count); if (!buf) return -ENOMEM; /* read undelivered logs from firmware */ ath6kl_read_fwlogs(ar); - spin_lock_bh(&ar->debug.fwlog_lock); + spin_lock(&ar->debug.fwlog_queue.lock); - while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) { - ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail, - ATH6KL_FWLOG_SIZE); + while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&ar->debug.fwlog_queue, skb); + break; + } - if ((size_t) ccnt > buf_len - len) - ccnt = buf_len - len; - memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt); - len += ccnt; + memcpy(buf + len, skb->data, skb->len); + len += skb->len; - fwlog->tail = (fwlog->tail + ccnt) & - (ATH6KL_FWLOG_SIZE - 1); + kfree_skb(skb); } - spin_unlock_bh(&ar->debug.fwlog_lock); + spin_unlock(&ar->debug.fwlog_queue.lock); - if (WARN_ON(len > buf_len)) - len = buf_len; + /* FIXME: what to do if len == 0? */ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); @@ -376,12 +374,87 @@ static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, } static const struct file_operations fops_fwlog = { - .open = ath6kl_debugfs_open, + .open = ath6kl_fwlog_open, + .release = ath6kl_fwlog_release, .read = ath6kl_fwlog_read, .owner = THIS_MODULE, .llseek = default_llseek, }; +static ssize_t ath6kl_fwlog_block_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct ath6kl *ar = file->private_data; + struct sk_buff *skb; + ssize_t ret_cnt; + size_t len = 0, not_copied; + char *buf; + int ret; + + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + + spin_lock(&ar->debug.fwlog_queue.lock); + + if (skb_queue_len(&ar->debug.fwlog_queue) == 0) { + /* we must init under queue lock */ + init_completion(&ar->debug.fwlog_completion); + + spin_unlock(&ar->debug.fwlog_queue.lock); + + ret = wait_for_completion_interruptible( + &ar->debug.fwlog_completion); + if (ret == -ERESTARTSYS) + return ret; + + spin_lock(&ar->debug.fwlog_queue.lock); + } + + while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&ar->debug.fwlog_queue, skb); + break; + } + + + memcpy(buf + len, skb->data, skb->len); + len += skb->len; + + kfree_skb(skb); + } + + spin_unlock(&ar->debug.fwlog_queue.lock); + + /* FIXME: what to do if len == 0? */ + + not_copied = copy_to_user(user_buf, buf, len); + if (not_copied != 0) { + ret_cnt = -EFAULT; + goto out; + } + + *ppos = *ppos + len; + + ret_cnt = len; + +out: + vfree(buf); + + return ret_cnt; +} + +static const struct file_operations fops_fwlog_block = { + .open = ath6kl_fwlog_open, + .release = ath6kl_fwlog_release, + .read = ath6kl_fwlog_block_read, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -667,9 +740,13 @@ static ssize_t ath6kl_endpoint_stats_read(struct file *file, return -ENOMEM; #define EPSTAT(name) \ - len = print_endpoint_stat(target, buf, buf_len, len, \ - offsetof(struct htc_endpoint_stats, name), \ - #name) + do { \ + len = print_endpoint_stat(target, buf, buf_len, len, \ + offsetof(struct htc_endpoint_stats, \ + name), \ + #name); \ + } while (0) + EPSTAT(cred_low_indicate); EPSTAT(tx_issued); EPSTAT(tx_pkt_bundled); @@ -779,17 +856,9 @@ static ssize_t ath6kl_regread_write(struct file *file, size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - u8 buf[50]; - unsigned int len; unsigned long reg_addr; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - - buf[len] = '\0'; - - if (strict_strtoul(buf, 0, ®_addr)) + if (kstrtoul_from_user(user_buf, count, 0, ®_addr)) return -EINVAL; if ((reg_addr % 4) != 0) @@ -903,15 +972,8 @@ static ssize_t ath6kl_lrssi_roam_write(struct file *file, { struct ath6kl *ar = file->private_data; unsigned long lrssi_roam_threshold; - char buf[32]; - ssize_t len; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - - buf[len] = '\0'; - if (strict_strtoul(buf, 0, &lrssi_roam_threshold)) + if (kstrtoul_from_user(user_buf, count, 0, &lrssi_roam_threshold)) return -EINVAL; ar->lrssi_roam_threshold = lrssi_roam_threshold; @@ -1558,12 +1620,12 @@ static ssize_t ath6kl_listen_int_write(struct file *file, if (kstrtou16(buf, 0, &listen_interval)) return -EINVAL; - if ((listen_interval < 1) || (listen_interval > 50)) + if ((listen_interval < 15) || (listen_interval > 3000)) return -EINVAL; - ar->listen_intvl_b = listen_interval; - ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0, - ar->listen_intvl_b); + vif->listen_intvl_t = listen_interval; + ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + vif->listen_intvl_t, 0); return count; } @@ -1573,10 +1635,15 @@ static ssize_t ath6kl_listen_int_read(struct file *file, size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; + struct ath6kl_vif *vif; char buf[32]; int len; - len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b); + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + len = scnprintf(buf, sizeof(buf), "%u\n", vif->listen_intvl_t); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1649,33 +1716,29 @@ static const struct file_operations fops_power_params = { .llseek = default_llseek, }; -int ath6kl_debug_init(struct ath6kl *ar) +void ath6kl_debug_init(struct ath6kl *ar) { - ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); - if (ar->debug.fwlog_buf.buf == NULL) - return -ENOMEM; - - ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL); - if (ar->debug.fwlog_tmp == NULL) { - vfree(ar->debug.fwlog_buf.buf); - return -ENOMEM; - } - - spin_lock_init(&ar->debug.fwlog_lock); + skb_queue_head_init(&ar->debug.fwlog_queue); + init_completion(&ar->debug.fwlog_completion); /* * Actually we are lying here but don't know how to read the mask * value from the firmware. */ ar->debug.fwlog_mask = 0; +} +/* + * Initialisation needs to happen in two stages as fwlog events can come + * before cfg80211 is initialised, and debugfs depends on cfg80211 + * initialisation. + */ +int ath6kl_debug_init_fs(struct ath6kl *ar) +{ ar->debugfs_phy = debugfs_create_dir("ath6kl", ar->wiphy->debugfsdir); - if (!ar->debugfs_phy) { - vfree(ar->debug.fwlog_buf.buf); - kfree(ar->debug.fwlog_tmp); + if (!ar->debugfs_phy) return -ENOMEM; - } debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, &fops_tgt_stats); @@ -1689,6 +1752,9 @@ int ath6kl_debug_init(struct ath6kl *ar) debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, &fops_fwlog); + debugfs_create_file("fwlog_block", S_IRUSR, ar->debugfs_phy, ar, + &fops_fwlog_block); + debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, &fops_fwlog_mask); @@ -1723,27 +1789,26 @@ int ath6kl_debug_init(struct ath6kl *ar) ar->debugfs_phy, ar, &fops_disconnect_timeout); debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar, - &fops_create_qos); + &fops_create_qos); debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar, - &fops_delete_qos); + &fops_delete_qos); debugfs_create_file("bgscan_interval", S_IWUSR, - ar->debugfs_phy, ar, &fops_bgscan_int); + ar->debugfs_phy, ar, &fops_bgscan_int); debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, &fops_listen_int); debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, - &fops_power_params); + &fops_power_params); return 0; } void ath6kl_debug_cleanup(struct ath6kl *ar) { - vfree(ar->debug.fwlog_buf.buf); - kfree(ar->debug.fwlog_tmp); + skb_queue_purge(&ar->debug.fwlog_queue); kfree(ar->debug.roam_tbl); } diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index c4be6e50996b..1803a0baae82 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -77,7 +78,8 @@ int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf, size_t len); void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive); void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout); -int ath6kl_debug_init(struct ath6kl *ar); +void ath6kl_debug_init(struct ath6kl *ar); +int ath6kl_debug_init_fs(struct ath6kl *ar); void ath6kl_debug_cleanup(struct ath6kl *ar); #else @@ -127,7 +129,11 @@ static inline void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, { } -static inline int ath6kl_debug_init(struct ath6kl *ar) +static inline void ath6kl_debug_init(struct ath6kl *ar) +{ +} + +static inline int ath6kl_debug_init_fs(struct ath6kl *ar) { return 0; } diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h index 2fe1dadfc77a..fd84086638e3 100644 --- a/drivers/net/wireless/ath/ath6kl/hif-ops.h +++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index e911737ab345..68ed6c2665b7 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -89,7 +90,7 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) } ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n", - regdump_addr); + regdump_addr); regdump_addr = TARG_VTOP(ar->target_type, regdump_addr); /* fetch register dump data */ @@ -106,9 +107,9 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); - for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) { + for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) { ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", - 4 * i, + i, le32_to_cpu(regdump_val[i]), le32_to_cpu(regdump_val[i + 1]), le32_to_cpu(regdump_val[i + 2]), @@ -134,6 +135,7 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) ath6kl_warn("Failed to clear debug interrupt: %d\n", ret); ath6kl_hif_dump_fw_crash(dev->ar); + ath6kl_read_fwlogs(dev->ar); return ret; } @@ -283,7 +285,7 @@ static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev) dev->irq_en_reg.cntr_int_status_en; ath6kl_dbg(ATH6KL_DBG_IRQ, - "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", + "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", counter_int_status); /* @@ -358,7 +360,7 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev) } ath6kl_dbg(ATH6KL_DBG_IRQ, - "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", + "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", cpu_int_status); /* Clear the interrupt */ diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h index 699a036f3a44..20ed6b73517b 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.h +++ b/drivers/net/wireless/ath/ath6kl/hif.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -197,6 +198,8 @@ struct hif_scatter_req { u8 *virt_dma_buf; struct hif_scatter_item scat_list[1]; + + u32 scat_q_depth; }; struct ath6kl_irq_proc_registers { @@ -220,6 +223,7 @@ struct ath6kl_irq_enable_reg { } __packed; struct ath6kl_device { + /* protects irq_proc_reg and irq_en_reg below */ spinlock_t lock; struct ath6kl_irq_proc_registers irq_proc_reg; struct ath6kl_irq_enable_reg irq_en_reg; diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index 2d721903640b..4849d99cce77 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,6 +23,9 @@ #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) +/* threshold to re-enable Tx bundling for an AC*/ +#define TX_RESUME_BUNDLE_THRESHOLD 1500 + /* Functions for Tx credit handling */ static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, struct htc_endpoint_credit_dist *ep_dist, @@ -168,31 +172,29 @@ static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info, static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info, struct list_head *epdist_list) { - struct htc_endpoint_credit_dist *cur_dist_list; + struct htc_endpoint_credit_dist *cur_list; - list_for_each_entry(cur_dist_list, epdist_list, list) { - if (cur_dist_list->endpoint == ENDPOINT_0) + list_for_each_entry(cur_list, epdist_list, list) { + if (cur_list->endpoint == ENDPOINT_0) continue; - if (cur_dist_list->cred_to_dist > 0) { - cur_dist_list->credits += - cur_dist_list->cred_to_dist; - cur_dist_list->cred_to_dist = 0; - if (cur_dist_list->credits > - cur_dist_list->cred_assngd) + if (cur_list->cred_to_dist > 0) { + cur_list->credits += cur_list->cred_to_dist; + cur_list->cred_to_dist = 0; + + if (cur_list->credits > cur_list->cred_assngd) ath6kl_credit_reduce(cred_info, - cur_dist_list, - cur_dist_list->cred_assngd); + cur_list, + cur_list->cred_assngd); - if (cur_dist_list->credits > - cur_dist_list->cred_norm) - ath6kl_credit_reduce(cred_info, cur_dist_list, - cur_dist_list->cred_norm); + if (cur_list->credits > cur_list->cred_norm) + ath6kl_credit_reduce(cred_info, cur_list, + cur_list->cred_norm); - if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) { - if (cur_dist_list->txq_depth == 0) + if (!(cur_list->dist_flags & HTC_EP_ACTIVE)) { + if (cur_list->txq_depth == 0) ath6kl_credit_reduce(cred_info, - cur_dist_list, 0); + cur_list, 0); } } } @@ -460,8 +462,8 @@ static void htc_async_tx_scat_complete(struct htc_target *target, INIT_LIST_HEAD(&tx_compq); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx scat complete len %d entries %d\n", - scat_req->len, scat_req->scat_entries); + "htc tx scat complete len %d entries %d\n", + scat_req->len, scat_req->scat_entries); if (scat_req->status) ath6kl_err("send scatter req failed: %d\n", scat_req->status); @@ -599,8 +601,8 @@ static void ath6kl_htc_tx_pkts_get(struct htc_target *target, list); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx got packet 0x%p queue depth %d\n", - packet, get_queue_depth(&endpoint->txq)); + "htc tx got packet 0x%p queue depth %d\n", + packet, get_queue_depth(&endpoint->txq)); len = CALC_TXRX_PADDED_LEN(target, packet->act_len + HTC_HDR_LENGTH); @@ -670,6 +672,7 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target, struct htc_packet *packet; int i, len, rem_scat, cred_pad; int status = 0; + u8 flags; rem_scat = target->max_tx_bndl_sz; @@ -696,9 +699,9 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target, scat_req->scat_list[i].packet = packet; /* prepare packet and flag message as part of a send bundle */ - ath6kl_htc_tx_prep_pkt(packet, - packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE, - cred_pad, packet->info.tx.seqno); + flags = packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE; + ath6kl_htc_tx_prep_pkt(packet, flags, + cred_pad, packet->info.tx.seqno); /* Make sure the buffer is 4-byte aligned */ ath6kl_htc_tx_buf_align(&packet->buf, packet->act_len + HTC_HDR_LENGTH); @@ -744,6 +747,12 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, struct hif_scatter_req *scat_req = NULL; int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; int status; + u32 txb_mask; + u8 ac = WMM_NUM_AC; + + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || + (WMI_CONTROL_SVC != endpoint->svc_id)) + ac = target->dev->ar->ep2ac_map[endpoint->eid]; while (true) { status = 0; @@ -759,10 +768,35 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, if (!scat_req) { /* no scatter resources */ ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx no more scatter resources\n"); + "htc tx no more scatter resources\n"); break; } + if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) { + if (WMM_AC_BE == ac) + /* + * BE, BK have priorities and bit + * positions reversed + */ + txb_mask = (1 << WMM_AC_BK); + else + /* + * any AC with priority lower than + * itself + */ + txb_mask = ((1 << ac) - 1); + /* + * when the scatter request resources drop below a + * certain threshold, disable Tx bundling for all + * AC's with priority lower than the current requesting + * AC. Otherwise re-enable Tx bundling for them + */ + if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) + target->tx_bndl_mask &= ~txb_mask; + else + target->tx_bndl_mask |= txb_mask; + } + ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", n_scat); @@ -806,6 +840,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, struct htc_packet *packet; int bundle_sent; int n_pkts_bundle; + u8 ac = WMM_NUM_AC; spin_lock_bh(&target->tx_lock); @@ -823,6 +858,10 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, */ INIT_LIST_HEAD(&txq); + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || + (WMI_CONTROL_SVC != endpoint->svc_id)) + ac = target->dev->ar->ep2ac_map[endpoint->eid]; + while (true) { if (list_empty(&endpoint->txq)) @@ -840,15 +879,18 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, while (true) { /* try to send a bundle on each pass */ - if ((target->tx_bndl_enable) && + if ((target->tx_bndl_mask) && (get_queue_depth(&txq) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) { int temp1 = 0, temp2 = 0; - ath6kl_htc_tx_bundle(endpoint, &txq, - &temp1, &temp2); - bundle_sent += temp1; - n_pkts_bundle += temp2; + /* check if bundling is enabled for an AC */ + if (target->tx_bndl_mask & (1 << ac)) { + ath6kl_htc_tx_bundle(endpoint, &txq, + &temp1, &temp2); + bundle_sent += temp1; + n_pkts_bundle += temp2; + } } if (list_empty(&txq)) @@ -867,6 +909,26 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, endpoint->ep_st.tx_bundles += bundle_sent; endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; + + /* + * if an AC has bundling disabled and no tx bundling + * has occured continously for a certain number of TX, + * enable tx bundling for this AC + */ + if (!bundle_sent) { + if (!(target->tx_bndl_mask & (1 << ac)) && + (ac < WMM_NUM_AC)) { + if (++target->ac_tx_count[ac] >= + TX_RESUME_BUNDLE_THRESHOLD) { + target->ac_tx_count[ac] = 0; + target->tx_bndl_mask |= (1 << ac); + } + } + } else { + /* tx bundling will reset the counter */ + if (ac < WMM_NUM_AC) + target->ac_tx_count[ac] = 0; + } } endpoint->tx_proc_cnt = 0; @@ -979,8 +1041,8 @@ static int htc_setup_tx_complete(struct htc_target *target) memcpy(&setup_comp_ext->flags, &flags, sizeof(setup_comp_ext->flags)); set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext, - sizeof(struct htc_setup_comp_ext_msg), - ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); + sizeof(struct htc_setup_comp_ext_msg), + ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); } else { struct htc_setup_comp_msg *setup_comp; @@ -988,8 +1050,8 @@ static int htc_setup_tx_complete(struct htc_target *target) memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg)); setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID); set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp, - sizeof(struct htc_setup_comp_msg), - ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); + sizeof(struct htc_setup_comp_msg), + ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); } /* we want synchronous operation */ @@ -1088,9 +1150,9 @@ void ath6kl_htc_flush_txep(struct htc_target *target, packet->status = -ECANCELED; list_del(&packet->list); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", - packet, packet->act_len, - packet->endpoint, packet->info.tx.tag); + "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", + packet, packet->act_len, + packet->endpoint, packet->info.tx.tag); INIT_LIST_HEAD(&container); list_add_tail(&packet->list, &container); @@ -1490,7 +1552,7 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets) if (packets->act_len > 0) { ath6kl_err("htc_ctrl_rx, got message with len:%zu\n", - packets->act_len + HTC_HDR_LENGTH); + packets->act_len + HTC_HDR_LENGTH); ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx unexpected endpoint 0 message", "", @@ -1609,8 +1671,8 @@ static int htc_parse_trailer(struct htc_target *target, } lk_ahd = (struct htc_lookahead_report *) record_buf; - if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) - && next_lk_ahds) { + if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) && + next_lk_ahds) { ath6kl_dbg(ATH6KL_DBG_HTC, "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n", @@ -2038,13 +2100,13 @@ fail_rx: list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) { list_del(&packet->list); htc_reclaim_rxbuf(target, packet, - &target->endpoint[packet->endpoint]); + &target->endpoint[packet->endpoint]); } list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) { list_del(&packet->list); htc_reclaim_rxbuf(target, packet, - &target->endpoint[packet->endpoint]); + &target->endpoint[packet->endpoint]); } return status; @@ -2176,11 +2238,11 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target) u32 look_ahead; if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead, - HTC_TARGET_RESPONSE_TIMEOUT)) + HTC_TARGET_RESPONSE_TIMEOUT)) return NULL; ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); + "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); htc_hdr = (struct htc_frame_hdr *)&look_ahead; @@ -2245,7 +2307,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, depth = get_queue_depth(pkt_queue); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx add multiple ep id %d cnt %d len %d\n", + "htc rx add multiple ep id %d cnt %d len %d\n", first_pkt->endpoint, depth, first_pkt->buf_len); endpoint = &target->endpoint[first_pkt->endpoint]; @@ -2271,8 +2333,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { if (target->ep_waiting == first_pkt->endpoint) { ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx blocked on ep %d, unblocking\n", - target->ep_waiting); + "htc rx blocked on ep %d, unblocking\n", + target->ep_waiting); target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS; target->ep_waiting = ENDPOINT_MAX; rx_unblock = true; @@ -2309,7 +2371,21 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target) "htc rx flush pkt 0x%p len %d ep %d\n", packet, packet->buf_len, packet->endpoint); - dev_kfree_skb(packet->pkt_cntxt); + /* + * packets in rx_bufq of endpoint 0 have originally + * been queued from target->free_ctrl_rxbuf where + * packet and packet->buf_start are allocated + * separately using kmalloc(). For other endpoint + * rx_bufq, it is allocated as skb where packet is + * skb->head. Take care of this difference while freeing + * the memory. + */ + if (packet->endpoint == ENDPOINT_0) { + kfree(packet->buf_start); + kfree(packet); + } else { + dev_kfree_skb(packet->pkt_cntxt); + } spin_lock_bh(&target->rx_lock); } spin_unlock_bh(&target->rx_lock); @@ -2328,6 +2404,7 @@ int ath6kl_htc_conn_service(struct htc_target *target, enum htc_endpoint_id assigned_ep = ENDPOINT_MAX; unsigned int max_msg_sz = 0; int status = 0; + u16 msg_id; ath6kl_dbg(ATH6KL_DBG_HTC, "htc connect service target 0x%p service id 0x%x\n", @@ -2371,9 +2448,10 @@ int ath6kl_htc_conn_service(struct htc_target *target, } resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf; + msg_id = le16_to_cpu(resp_msg->msg_id); - if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID) - || (rx_pkt->act_len < sizeof(*resp_msg))) { + if ((msg_id != HTC_MSG_CONN_SVC_RESP_ID) || + (rx_pkt->act_len < sizeof(*resp_msg))) { status = -ENOMEM; goto fail_tx; } @@ -2420,6 +2498,15 @@ int ath6kl_htc_conn_service(struct htc_target *target, endpoint->cred_dist.endpoint = assigned_ep; endpoint->cred_dist.cred_sz = target->tgt_cred_sz; + switch (endpoint->svc_id) { + case WMI_DATA_BK_SVC: + endpoint->tx_drop_packet_threshold = MAX_DEF_COOKIE_NUM / 3; + break; + default: + endpoint->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM; + break; + } + if (conn_req->max_rxmsg_sz) { /* * Override cred_per_msg calculation, this optimizes @@ -2517,7 +2604,8 @@ static void htc_setup_msg_bndl(struct htc_target *target) target->max_rx_bndl_sz, target->max_tx_bndl_sz); if (target->max_tx_bndl_sz) - target->tx_bndl_enable = true; + /* tx_bndl_mask is enabled per AC, each has 1 bit */ + target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1; if (target->max_rx_bndl_sz) target->rx_bndl_enable = true; @@ -2532,7 +2620,7 @@ static void htc_setup_msg_bndl(struct htc_target *target) * padding will spill into the next credit buffer * which is fatal. */ - target->tx_bndl_enable = false; + target->tx_bndl_mask = 0; } } @@ -2589,8 +2677,8 @@ int ath6kl_htc_wait_target(struct htc_target *target) } ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n", - (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", - target->htc_tgt_ver); + (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", + target->htc_tgt_ver); if (target->msg_per_bndl_max > 0) htc_setup_msg_bndl(target); @@ -2784,14 +2872,14 @@ void ath6kl_htc_cleanup(struct htc_target *target) ath6kl_hif_cleanup_scatter(target->dev->ar); list_for_each_entry_safe(packet, tmp_packet, - &target->free_ctrl_txbuf, list) { + &target->free_ctrl_txbuf, list) { list_del(&packet->list); kfree(packet->buf_start); kfree(packet); } list_for_each_entry_safe(packet, tmp_packet, - &target->free_ctrl_rxbuf, list) { + &target->free_ctrl_rxbuf, list) { list_del(&packet->list); kfree(packet->buf_start); kfree(packet); diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h index 57672e1ed1a6..5027ccc36b62 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.h +++ b/drivers/net/wireless/ath/ath6kl/htc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -87,6 +88,8 @@ #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) #define WMI_MAX_SERVICES 5 +#define WMM_NUM_AC 4 + /* reserved and used to flush ALL packets */ #define HTC_TX_PACKET_TAG_ALL 0 #define HTC_SERVICE_TX_PACKET_TAG 1 @@ -498,6 +501,7 @@ struct htc_endpoint { u8 seqno; u32 conn_flags; struct htc_endpoint_stats ep_st; + u16 tx_drop_packet_threshold; }; struct htc_control_buffer { @@ -519,9 +523,16 @@ struct htc_target { struct ath6kl_htc_credit_info *credit_info; int tgt_creds; unsigned int tgt_cred_sz; + + /* protects free_ctrl_txbuf and free_ctrl_rxbuf */ spinlock_t htc_lock; + + /* FIXME: does this protext rx_bufq and endpoint structures or what? */ spinlock_t rx_lock; + + /* protects endpoint->txq */ spinlock_t tx_lock; + struct ath6kl_device *dev; u32 htc_flags; u32 rx_st_flags; @@ -531,7 +542,7 @@ struct htc_target { /* max messages per bundle for HTC */ int msg_per_bndl_max; - bool tx_bndl_enable; + u32 tx_bndl_mask; int rx_bndl_enable; int max_rx_bndl_sz; int max_tx_bndl_sz; @@ -543,6 +554,9 @@ struct htc_target { int max_xfer_szper_scatreq; int chk_irq_status_cnt; + + /* counts the number of Tx without bundling continously per AC */ + u32 ac_tx_count[WMM_NUM_AC]; }; void *ath6kl_htc_create(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 0d76c3778106..03cae142f178 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -74,7 +75,7 @@ static const struct ath6kl_hw hw_list[] = { }, .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, - .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, + .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, }, { .id = AR6004_HW_1_0_VERSION, @@ -351,11 +352,7 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val, blk_size |= ((u32)htc_ctrl_buf) << 16; /* set the host interest area for the block size */ - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_mbox_io_block_sz)), - (u8 *)&blk_size, - 4); + status = ath6kl_bmi_write_hi32(ar, hi_mbox_io_block_sz, blk_size); if (status) { ath6kl_err("bmi_write_memory for IO block size failed\n"); goto out; @@ -367,11 +364,8 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val, if (mbox_isr_yield_val) { /* set the host interest area for the mbox ISR yield limit */ - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_mbox_isr_yield_limit)), - (u8 *)&mbox_isr_yield_val, - 4); + status = ath6kl_bmi_write_hi32(ar, hi_mbox_isr_yield_limit, + mbox_isr_yield_val); if (status) { ath6kl_err("bmi_write_memory for yield limit failed\n"); goto out; @@ -384,7 +378,6 @@ out: static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) { - int status = 0; int ret; /* @@ -392,43 +385,54 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) * default values. Required if checksum offload is needed. Set * RxMetaVersion to 2. */ - if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx, - ar->rx_meta_ver, 0, 0)) { - ath6kl_err("unable to set the rx frame format\n"); - status = -EIO; + ret = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx, + ar->rx_meta_ver, 0, 0); + if (ret) { + ath6kl_err("unable to set the rx frame format: %d\n", ret); + return ret; } - if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) - if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1, - IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { - ath6kl_err("unable to set power save fail event policy\n"); - status = -EIO; + if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) { + ret = ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1, + IGNORE_PS_FAIL_DURING_SCAN); + if (ret) { + ath6kl_err("unable to set power save fail event policy: %d\n", + ret); + return ret; } + } - if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) - if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0, - WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) { - ath6kl_err("unable to set barker preamble policy\n"); - status = -EIO; + if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) { + ret = ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0, + WMI_FOLLOW_BARKER_IN_ERP); + if (ret) { + ath6kl_err("unable to set barker preamble policy: %d\n", + ret); + return ret; } + } - if (ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx, - WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) { - ath6kl_err("unable to set keep alive interval\n"); - status = -EIO; + ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx, + WLAN_CONFIG_KEEP_ALIVE_INTERVAL); + if (ret) { + ath6kl_err("unable to set keep alive interval: %d\n", ret); + return ret; } - if (ath6kl_wmi_disctimeout_cmd(ar->wmi, idx, - WLAN_CONFIG_DISCONNECT_TIMEOUT)) { - ath6kl_err("unable to set disconnect timeout\n"); - status = -EIO; + ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, idx, + WLAN_CONFIG_DISCONNECT_TIMEOUT); + if (ret) { + ath6kl_err("unable to set disconnect timeout: %d\n", ret); + return ret; } - if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) - if (ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED)) { - ath6kl_err("unable to set txop bursting\n"); - status = -EIO; + if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) { + ret = ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED); + if (ret) { + ath6kl_err("unable to set txop bursting: %d\n", ret); + return ret; } + } if (ar->p2p && (ar->vif_max == 1 || idx)) { ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx, @@ -452,7 +456,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) } } - return status; + return ret; } int ath6kl_configure_target(struct ath6kl *ar) @@ -462,8 +466,7 @@ int ath6kl_configure_target(struct ath6kl *ar) int i, status; param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG); - if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_serial_enable)), (u8 *)¶m, 4)) { + if (ath6kl_bmi_write_hi32(ar, hi_serial_enable, param)) { ath6kl_err("bmi_write_memory for uart debug failed\n"); return -EIO; } @@ -499,11 +502,8 @@ int ath6kl_configure_target(struct ath6kl *ar) if (ar->p2p && ar->vif_max == 1) fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; - param = HTC_PROTOCOL_VERSION; - if (ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_app_host_interest)), - (u8 *)¶m, 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest, + HTC_PROTOCOL_VERSION) != 0) { ath6kl_err("bmi_write_memory for htc version failed\n"); return -EIO; } @@ -511,10 +511,7 @@ int ath6kl_configure_target(struct ath6kl *ar) /* set the firmware mode to STA/IBSS/AP */ param = 0; - if (ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_option_flag)), - (u8 *)¶m, 4) != 0) { + if (ath6kl_bmi_read_hi32(ar, hi_option_flag, ¶m) != 0) { ath6kl_err("bmi_read_memory for setting fwmode failed\n"); return -EIO; } @@ -526,11 +523,7 @@ int ath6kl_configure_target(struct ath6kl *ar) param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); - if (ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_option_flag)), - (u8 *)¶m, - 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_option_flag, param) != 0) { ath6kl_err("bmi_write_memory for setting fwmode failed\n"); return -EIO; } @@ -549,16 +542,13 @@ int ath6kl_configure_target(struct ath6kl *ar) param = ar->hw.board_ext_data_addr; ram_reserved_size = ar->hw.reserved_ram_size; - if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_ext_data)), - (u8 *)¶m, 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) { ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); return -EIO; } - if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_end_ram_reserve_sz)), - (u8 *)&ram_reserved_size, 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, + ram_reserved_size) != 0) { ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); return -EIO; } @@ -569,20 +559,13 @@ int ath6kl_configure_target(struct ath6kl *ar) return -EIO; /* Configure GPIO AR600x UART */ - param = ar->hw.uarttx_pin; - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_dbg_uart_txpin)), - (u8 *)¶m, 4); + status = ath6kl_bmi_write_hi32(ar, hi_dbg_uart_txpin, + ar->hw.uarttx_pin); if (status) return status; /* Configure target refclk_hz */ - param = ar->hw.refclk_hz; - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_refclk_hz)), - (u8 *)¶m, 4); + status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz); if (status) return status; @@ -832,13 +815,13 @@ static int ath6kl_fetch_testscript_file(struct ath6kl *ar) return 0; snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.testscript); + ar->hw.fw.dir, ar->hw.fw.testscript); ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript, &ar->fw_testscript_len); if (ret) { ath6kl_err("Failed to get testscript file %s: %d\n", - filename, ret); + filename, ret); return ret; } @@ -922,7 +905,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) switch (ie_id) { case ATH6KL_FW_IE_OTP_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n", - ie_len); + ie_len); ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL); @@ -935,7 +918,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) break; case ATH6KL_FW_IE_FW_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n", - ie_len); + ie_len); /* in testmode we already might have a fw file */ if (ar->fw != NULL) @@ -952,7 +935,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) break; case ATH6KL_FW_IE_PATCH_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n", - ie_len); + ie_len); ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL); @@ -1096,22 +1079,14 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) */ if (ar->hw.board_addr != 0) { board_address = ar->hw.board_addr; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_data)), - (u8 *) &board_address, 4); + ath6kl_bmi_write_hi32(ar, hi_board_data, + board_address); } else { - ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_data)), - (u8 *) &board_address, 4); + ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address); } /* determine where in target ram to write extended board data */ - ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_ext_data)), - (u8 *) &board_ext_address, 4); + ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address); if (ar->target_type == TARGET_TYPE_AR6003 && board_ext_address == 0) { @@ -1123,6 +1098,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) case TARGET_TYPE_AR6003: board_data_size = AR6003_BOARD_DATA_SZ; board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ; + if (ar->fw_board_len > (board_data_size + board_ext_data_size)) + board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2; break; case TARGET_TYPE_AR6004: board_data_size = AR6004_BOARD_DATA_SZ; @@ -1154,10 +1131,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) /* record that extended board data is initialized */ param = (board_ext_data_size << 16) | 1; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_ext_data_config)), - (unsigned char *) ¶m, 4); + ath6kl_bmi_write_hi32(ar, hi_board_ext_data_config, param); } if (ar->fw_board_len < board_data_size) { @@ -1178,11 +1152,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) } /* record the fact that Board Data IS initialized */ - param = 1; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_data_initialized)), - (u8 *)¶m, 4); + ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1); return ret; } @@ -1209,10 +1179,7 @@ static int ath6kl_upload_otp(struct ath6kl *ar) } /* read firmware start address */ - ret = ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_app_start)), - (u8 *) &address, sizeof(address)); + ret = ath6kl_bmi_read_hi32(ar, hi_app_start, &address); if (ret) { ath6kl_err("Failed to read hi_app_start: %d\n", ret); @@ -1270,7 +1237,7 @@ static int ath6kl_upload_firmware(struct ath6kl *ar) static int ath6kl_upload_patch(struct ath6kl *ar) { - u32 address, param; + u32 address; int ret; if (ar->fw_patch == NULL) @@ -1287,18 +1254,14 @@ static int ath6kl_upload_patch(struct ath6kl *ar) return ret; } - param = address; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_dset_list_head)), - (unsigned char *) ¶m, 4); + ath6kl_bmi_write_hi32(ar, hi_dset_list_head, address); return 0; } static int ath6kl_upload_testscript(struct ath6kl *ar) { - u32 address, param; + u32 address; int ret; if (ar->testmode != 2) @@ -1310,7 +1273,7 @@ static int ath6kl_upload_testscript(struct ath6kl *ar) address = ar->hw.testscript_addr; ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n", - address, ar->fw_testscript_len); + address, ar->fw_testscript_len); ret = ath6kl_bmi_write(ar, address, ar->fw_testscript, ar->fw_testscript_len); @@ -1319,23 +1282,9 @@ static int ath6kl_upload_testscript(struct ath6kl *ar) return ret; } - param = address; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_ota_testscript)), - (unsigned char *) ¶m, 4); - - param = 4096; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_end_ram_reserve_sz)), - (unsigned char *) ¶m, 4); - - param = 1; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_test_apps_related)), - (unsigned char *) ¶m, 4); + ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address); + ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096); + ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1); return 0; } @@ -1346,7 +1295,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) int status = 0; if (ar->target_type != TARGET_TYPE_AR6003 && - ar->target_type != TARGET_TYPE_AR6004) + ar->target_type != TARGET_TYPE_AR6004) return -EINVAL; /* temporarily disable system sleep */ @@ -1403,7 +1352,8 @@ static int ath6kl_init_upload(struct ath6kl *ar) return status; /* WAR to avoid SDIO CRC err */ - if (ar->version.target_ver == AR6003_HW_2_0_VERSION) { + if (ar->version.target_ver == AR6003_HW_2_0_VERSION || + ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { ath6kl_err("temporary war to avoid sdio crc error\n"); param = 0x20; @@ -1726,9 +1676,11 @@ void ath6kl_stop_txrx(struct ath6kl *ar) * configure NOT to reset the target during a debug session. */ ath6kl_dbg(ATH6KL_DBG_TRC, - "attempting to reset target on instance destroy\n"); + "attempting to reset target on instance destroy\n"); ath6kl_reset_device(ar, ar->target_type, true, true); clear_bit(WLAN_ENABLED, &ar->flag); + + up(&ar->sem); } EXPORT_SYMBOL(ath6kl_stop_txrx); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index b96d01a7919b..229e1922ebe4 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -80,11 +81,21 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) { struct ath6kl_sta *sta = &ar->sta_list[i]; + struct ath6kl_mgmt_buff *entry, *tmp; /* empty the queued pkts in the PS queue if any */ spin_lock_bh(&sta->psq_lock); skb_queue_purge(&sta->psq); skb_queue_purge(&sta->apsdq); + + if (sta->mgmt_psq_len != 0) { + list_for_each_entry_safe(entry, tmp, &sta->mgmt_psq, list) { + kfree(entry); + } + INIT_LIST_HEAD(&sta->mgmt_psq); + sta->mgmt_psq_len = 0; + } + spin_unlock_bh(&sta->psq_lock); memset(&ar->ap_stats.sta[sta->aid - 1], 0, @@ -339,7 +350,7 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, __le32 data; if (target_type != TARGET_TYPE_AR6003 && - target_type != TARGET_TYPE_AR6004) + target_type != TARGET_TYPE_AR6004) return; data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) : @@ -588,11 +599,9 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, memcpy(vif->bssid, bssid, sizeof(vif->bssid)); vif->bss_ch = channel; - if ((vif->nw_type == INFRA_NETWORK)) { - ar->listen_intvl_b = listen_int; + if ((vif->nw_type == INFRA_NETWORK)) ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, - 0, ar->listen_intvl_b); - } + vif->listen_intvl_t, 0); netif_wake_queue(vif->ndev); @@ -810,6 +819,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) struct sk_buff *skb; bool psq_empty = false; struct ath6kl *ar = vif->ar; + struct ath6kl_mgmt_buff *mgmt_buf; conn = ath6kl_find_sta_by_aid(ar, aid); @@ -820,7 +830,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) * becomes empty update the PVB for this station. */ spin_lock_bh(&conn->psq_lock); - psq_empty = skb_queue_empty(&conn->psq); + psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0); spin_unlock_bh(&conn->psq_lock); if (psq_empty) @@ -828,15 +838,31 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) return; spin_lock_bh(&conn->psq_lock); - skb = skb_dequeue(&conn->psq); - spin_unlock_bh(&conn->psq_lock); + if (conn->mgmt_psq_len > 0) { + mgmt_buf = list_first_entry(&conn->mgmt_psq, + struct ath6kl_mgmt_buff, list); + list_del(&mgmt_buf->list); + conn->mgmt_psq_len--; + spin_unlock_bh(&conn->psq_lock); + + conn->sta_flags |= STA_PS_POLLED; + ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, + mgmt_buf->id, mgmt_buf->freq, + mgmt_buf->wait, mgmt_buf->buf, + mgmt_buf->len, mgmt_buf->no_cck); + conn->sta_flags &= ~STA_PS_POLLED; + kfree(mgmt_buf); + } else { + skb = skb_dequeue(&conn->psq); + spin_unlock_bh(&conn->psq_lock); - conn->sta_flags |= STA_PS_POLLED; - ath6kl_data_tx(skb, vif->ndev); - conn->sta_flags &= ~STA_PS_POLLED; + conn->sta_flags |= STA_PS_POLLED; + ath6kl_data_tx(skb, vif->ndev); + conn->sta_flags &= ~STA_PS_POLLED; + } spin_lock_bh(&conn->psq_lock); - psq_empty = skb_queue_empty(&conn->psq); + psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0); spin_unlock_bh(&conn->psq_lock); if (psq_empty) @@ -922,8 +948,8 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, } ath6kl_cfg80211_disconnect_event(vif, reason, bssid, - assoc_resp_len, assoc_info, - prot_reason_status); + assoc_resp_len, assoc_info, + prot_reason_status); aggr_reset_state(vif->aggr_cntxt->aggr_conn); @@ -943,9 +969,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, } else { set_bit(CONNECT_PEND, &vif->flags); if (((reason == ASSOC_FAILED) && - (prot_reason_status == 0x11)) || - ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) - && (vif->reconnect_flag == 1))) { + (prot_reason_status == 0x11)) || + ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) && + (vif->reconnect_flag == 1))) { set_bit(CONNECTED, &vif->flags); return; } @@ -1079,7 +1105,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) if (mc_all_on || mc_all_off) { /* Enable/disable all multicast */ ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", - mc_all_on ? "enabling" : "disabling"); + mc_all_on ? "enabling" : "disabling"); ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, mc_all_on); if (ret) @@ -1092,7 +1118,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) found = false; netdev_for_each_mc_addr(ha, ndev) { if (memcmp(ha->addr, mc_filter->hw_addr, - ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { found = true; break; } @@ -1111,7 +1137,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) false); if (ret) { ath6kl_warn("Failed to remove multicast filter:%pM\n", - mc_filter->hw_addr); + mc_filter->hw_addr); return; } @@ -1126,7 +1152,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) found = false; list_for_each_entry(mc_filter, &vif->mc_filter, list) { if (memcmp(ha->addr, mc_filter->hw_addr, - ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { found = true; break; } @@ -1151,7 +1177,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) true); if (ret) { ath6kl_warn("Failed to add multicast filter :%pM\n", - mc_filter->hw_addr); + mc_filter->hw_addr); kfree(mc_filter); goto out; } @@ -1184,5 +1210,7 @@ void init_netdev(struct net_device *dev) sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES; + dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + return; } diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 4febee723495..53528648b425 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,6 +32,7 @@ struct ath6kl_sdio { struct sdio_func *func; + /* protects access to bus_req_freeq */ spinlock_t lock; /* free list */ @@ -49,16 +51,20 @@ struct ath6kl_sdio { /* scatter request list head */ struct list_head scat_req; - /* Avoids disabling irq while the interrupts being handled */ - struct mutex mtx_irq; + atomic_t irq_handling; + wait_queue_head_t irq_wq; + /* protects access to scat_req */ spinlock_t scat_lock; + bool scatter_enabled; bool is_disabled; const struct sdio_device_id *id; struct work_struct wr_async_work; struct list_head wr_asyncq; + + /* protects access to wr_asyncq */ spinlock_t wr_async_lock; }; @@ -404,7 +410,10 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, return -ENOMEM; mutex_lock(&ar_sdio->dma_buffer_mutex); tbuf = ar_sdio->dma_buffer; - memcpy(tbuf, buf, len); + + if (request & HIF_WRITE) + memcpy(tbuf, buf, len); + bounced = true; } else tbuf = buf; @@ -462,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n"); ar_sdio = sdio_get_drvdata(func); - mutex_lock(&ar_sdio->mtx_irq); + atomic_set(&ar_sdio->irq_handling, 1); /* * Release the host during interrups so we can pick it back up when * we process commands. @@ -471,7 +480,10 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); sdio_claim_host(ar_sdio->func); - mutex_unlock(&ar_sdio->mtx_irq); + + atomic_set(&ar_sdio->irq_handling, 0); + wake_up(&ar_sdio->irq_wq); + WARN_ON(status && status != -ECANCELED); } @@ -572,6 +584,13 @@ static void ath6kl_sdio_irq_enable(struct ath6kl *ar) sdio_release_host(ar_sdio->func); } +static bool ath6kl_sdio_is_on_irq(struct ath6kl *ar) +{ + struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); + + return !atomic_read(&ar_sdio->irq_handling); +} + static void ath6kl_sdio_irq_disable(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); @@ -579,14 +598,21 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar) sdio_claim_host(ar_sdio->func); - mutex_lock(&ar_sdio->mtx_irq); + if (atomic_read(&ar_sdio->irq_handling)) { + sdio_release_host(ar_sdio->func); + + ret = wait_event_interruptible(ar_sdio->irq_wq, + ath6kl_sdio_is_on_irq(ar)); + if (ret) + return; + + sdio_claim_host(ar_sdio->func); + } ret = sdio_release_irq(ar_sdio->func); if (ret) ath6kl_err("Failed to release sdio irq: %d\n", ret); - mutex_unlock(&ar_sdio->mtx_irq); - sdio_release_host(ar_sdio->func); } @@ -601,6 +627,8 @@ static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar) node = list_first_entry(&ar_sdio->scat_req, struct hif_scatter_req, list); list_del(&node->list); + + node->scat_q_depth = get_queue_depth(&ar_sdio->scat_req); } spin_unlock_bh(&ar_sdio->scat_lock); @@ -633,8 +661,8 @@ static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar, return -EINVAL; ath6kl_dbg(ATH6KL_DBG_SCATTER, - "hif-scatter: total len: %d scatter entries: %d\n", - scat_req->len, scat_req->scat_entries); + "hif-scatter: total len: %d scatter entries: %d\n", + scat_req->len, scat_req->scat_entries); if (request & HIF_SYNCHRONOUS) status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest); @@ -813,6 +841,7 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; mmc_pm_flag_t flags; + bool try_deepsleep = false; int ret; if (ar->state == ATH6KL_STATE_SCHED_SCAN) { @@ -839,14 +868,22 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) goto cut_pwr; ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); - if (ret) + if (ret && ret != -ENOTCONN) + ath6kl_err("wow suspend failed: %d\n", ret); + + if (ret && + (!ar->wow_suspend_mode || + ar->wow_suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP)) + try_deepsleep = true; + else if (ret && + ar->wow_suspend_mode == WLAN_POWER_STATE_CUT_PWR) goto cut_pwr; - - return 0; + if (!ret) + return 0; } if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP || - !ar->suspend_mode) { + !ar->suspend_mode || try_deepsleep) { flags = sdio_get_host_pm_caps(func); if (!(flags & MMC_PM_KEEP_POWER)) @@ -901,8 +938,15 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) case ATH6KL_STATE_WOW: break; + case ATH6KL_STATE_SCHED_SCAN: break; + + case ATH6KL_STATE_SUSPENDING: + break; + + case ATH6KL_STATE_RESUMING: + break; } ath6kl_cfg80211_resume(ar); @@ -981,7 +1025,7 @@ static int ath6kl_sdio_diag_read32(struct ath6kl *ar, u32 address, u32 *data) (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC); if (status) { ath6kl_err("%s: failed to read from window data addr\n", - __func__); + __func__); return status; } @@ -1285,7 +1329,6 @@ static int ath6kl_sdio_probe(struct sdio_func *func, spin_lock_init(&ar_sdio->scat_lock); spin_lock_init(&ar_sdio->wr_async_lock); mutex_init(&ar_sdio->dma_buffer_mutex); - mutex_init(&ar_sdio->mtx_irq); INIT_LIST_HEAD(&ar_sdio->scat_req); INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); @@ -1293,6 +1336,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func, INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work); + init_waitqueue_head(&ar_sdio->irq_wq); + for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]); diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index 108a723a1085..78e0ef4567a5 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2010 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,6 +20,7 @@ #define AR6003_BOARD_DATA_SZ 1024 #define AR6003_BOARD_EXT_DATA_SZ 768 +#define AR6003_BOARD_EXT_DATA_SZ_V2 1024 #define AR6004_BOARD_DATA_SZ 6144 #define AR6004_BOARD_EXT_DATA_SZ 0 diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index f0cd61d6188a..6675c92b542b 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h index 7fd47a62d078..fe651d6707df 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.h +++ b/drivers/net/wireless/ath/ath6kl/testmode.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index a3dc6943c7f7..f85353fd1792 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -158,8 +159,8 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, */ if (is_apsdq_empty) { ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, - vif->fw_vif_idx, - conn->aid, 1, 0); + vif->fw_vif_idx, + conn->aid, 1, 0); } *flags |= WMI_DATA_HDR_FLAGS_UAPSD; @@ -284,6 +285,9 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, int status = 0; struct ath6kl_cookie *cookie = NULL; + if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) + return -EACCES; + spin_lock_bh(&ar->lock); ath6kl_dbg(ATH6KL_DBG_WLAN_TX, @@ -359,6 +363,11 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) return 0; } + if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) { + dev_kfree_skb(skb); + return 0; + } + if (!test_bit(WMI_READY, &ar->flag)) goto fail_tx; @@ -370,7 +379,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) if (test_bit(WMI_ENABLED, &ar->flag)) { if ((dev->features & NETIF_F_IP_CSUM) && - (csum == CHECKSUM_PARTIAL)) { + (csum == CHECKSUM_PARTIAL)) { csum_start = skb->csum_start - (skb_network_header(skb) - skb->head) + sizeof(struct ath6kl_llc_snap_hdr); @@ -394,7 +403,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) } if ((dev->features & NETIF_F_IP_CSUM) && - (csum == CHECKSUM_PARTIAL)) { + (csum == CHECKSUM_PARTIAL)) { meta_v2.csum_start = csum_start; meta_v2.csum_dest = csum_dest; @@ -419,7 +428,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) } if ((vif->nw_type == ADHOC_NETWORK) && - ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags)) + ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags)) chk_adhoc_ps_mapping = true; else { /* get the stream mapping */ @@ -593,7 +602,8 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, */ if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] < ar->hiac_stream_active_pri && - ar->cookie_count <= MAX_HI_COOKIE_NUM) + ar->cookie_count <= + target->endpoint[endpoint].tx_drop_packet_threshold) /* * Give preference to the highest priority stream by * dropping the packets which overflowed. @@ -876,7 +886,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) if (!IS_ALIGNED((unsigned long) skb->data, 4)) skb->data = PTR_ALIGN(skb->data - 4, 4); set_htc_rxpkt_info(packet, skb, skb->data, - ATH6KL_BUFFER_SIZE, endpoint); + ATH6KL_BUFFER_SIZE, endpoint); list_add_tail(&packet->list, &queue); } @@ -1256,8 +1266,8 @@ static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif, flags = 0; ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, - vif->fw_vif_idx, - conn->aid, 0, flags); + vif->fw_vif_idx, + conn->aid, 0, flags); } return; @@ -1296,7 +1306,15 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) skb_put(skb, packet->act_len + HTC_HDR_LENGTH); skb_pull(skb, HTC_HDR_LENGTH); + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ", + skb->data, skb->len); + if (ept == ar->ctrl_ep) { + if (test_bit(WMI_ENABLED, &ar->flag)) { + ath6kl_check_wow_status(ar); + ath6kl_wmi_control_rx(ar->wmi, skb); + return; + } if_idx = wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data); } else { @@ -1321,10 +1339,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) spin_unlock_bh(&vif->if_lock); - - ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ", - skb->data, skb->len); - skb->dev = vif->ndev; if (!test_bit(WMI_ENABLED, &ar->flag)) { @@ -1336,11 +1350,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) ath6kl_check_wow_status(ar); - if (ept == ar->ctrl_ep) { - ath6kl_wmi_control_rx(ar->wmi, skb); - return; - } - min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) + sizeof(struct ath6kl_llc_snap_hdr); @@ -1416,8 +1425,33 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) if (!(conn->sta_flags & STA_PS_SLEEP)) { struct sk_buff *skbuff = NULL; bool is_apsdq_empty; + struct ath6kl_mgmt_buff *mgmt; + u8 idx; spin_lock_bh(&conn->psq_lock); + while (conn->mgmt_psq_len > 0) { + mgmt = list_first_entry( + &conn->mgmt_psq, + struct ath6kl_mgmt_buff, + list); + list_del(&mgmt->list); + conn->mgmt_psq_len--; + spin_unlock_bh(&conn->psq_lock); + idx = vif->fw_vif_idx; + + ath6kl_wmi_send_mgmt_cmd(ar->wmi, + idx, + mgmt->id, + mgmt->freq, + mgmt->wait, + mgmt->buf, + mgmt->len, + mgmt->no_cck); + + kfree(mgmt); + spin_lock_bh(&conn->psq_lock); + } + conn->mgmt_psq_len = 0; while ((skbuff = skb_dequeue(&conn->psq))) { spin_unlock_bh(&conn->psq_lock); ath6kl_data_tx(skbuff, vif->ndev); @@ -1541,7 +1575,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) aggr_conn = vif->aggr_cntxt->aggr_conn; if (aggr_process_recv_frm(aggr_conn, tid, seq_no, - is_amsdu, skb)) { + is_amsdu, skb)) { /* aggregation code will handle the skb */ return; } diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index c72567c6d338..325b1224c2b1 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 97abf4699b41..2b442332cd0f 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -126,7 +127,7 @@ int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb) if (!is_ethertype(be16_to_cpu(type))) { ath6kl_dbg(ATH6KL_DBG_WMI, - "%s: pkt is already in 802.3 format\n", __func__); + "%s: pkt is already in 802.3 format\n", __func__); return 0; } @@ -827,8 +828,8 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 && pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) { /* WMM OUT (00:50:F2) */ - if (pie[1] > 5 - && pie[6] == WMM_PARAM_OUI_SUBTYPE) + if (pie[1] > 5 && + pie[6] == WMM_PARAM_OUI_SUBTYPE) wmi->is_wmm_enabled = true; } break; @@ -912,17 +913,17 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len) regpair = ath6kl_get_regpair((u16) reg_code); country = ath6kl_regd_find_country_by_rd((u16) reg_code); ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", - regpair->regDmnEnum); + regpair->regDmnEnum); } - if (country) { + if (country && wmi->parent_dev->wiphy_registered) { alpha2[0] = country->isoName[0]; alpha2[1] = country->isoName[1]; regulatory_hint(wmi->parent_dev->wiphy, alpha2); ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n", - alpha2[0], alpha2[1]); + alpha2[0], alpha2[1]); } } @@ -1033,8 +1034,9 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, if (len < 8 + 2 + 2) return -EINVAL; - if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags) - && memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { + if (bih->frame_type == BEACON_FTYPE && + test_bit(CONNECTED, &vif->flags) && + memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { const u8 *tim; tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2, len - 8 - 2 - 2); @@ -1366,8 +1368,8 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Upper threshold breached */ if (rssi < sq_thresh->upper_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious upper rssi threshold event: %d\n", - rssi); + "spurious upper rssi threshold event: %d\n", + rssi); } else if ((rssi < sq_thresh->upper_threshold[1]) && (rssi >= sq_thresh->upper_threshold[0])) { new_threshold = WMI_RSSI_THRESHOLD1_ABOVE; @@ -1390,7 +1392,7 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Lower threshold breached */ if (rssi > sq_thresh->lower_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious lower rssi threshold event: %d %d\n", + "spurious lower rssi threshold event: %d %d\n", rssi, sq_thresh->lower_threshold[0]); } else if ((rssi > sq_thresh->lower_threshold[1]) && (rssi <= sq_thresh->lower_threshold[0])) { @@ -1551,8 +1553,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Upper threshold breached */ if (snr < sq_thresh->upper_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious upper snr threshold event: %d\n", - snr); + "spurious upper snr threshold event: %d\n", + snr); } else if ((snr < sq_thresh->upper_threshold[1]) && (snr >= sq_thresh->upper_threshold[0])) { new_threshold = WMI_SNR_THRESHOLD1_ABOVE; @@ -1569,8 +1571,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Lower threshold breached */ if (snr > sq_thresh->lower_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious lower snr threshold event: %d\n", - sq_thresh->lower_threshold[0]); + "spurious lower snr threshold event: %d\n", + sq_thresh->lower_threshold[0]); } else if ((snr > sq_thresh->lower_threshold[1]) && (snr <= sq_thresh->lower_threshold[0])) { new_threshold = WMI_SNR_THRESHOLD4_BELOW; @@ -2028,6 +2030,26 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, return ret; } +int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx, + u16 bmiss_time, u16 num_beacons) +{ + struct sk_buff *skb; + struct wmi_bmiss_time_cmd *cmd; + int ret; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_bmiss_time_cmd *) skb->data; + cmd->bmiss_time = cpu_to_le16(bmiss_time); + cmd->num_beacons = cpu_to_le16(num_beacons); + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BMISS_TIME_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} + int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) { struct sk_buff *skb; @@ -2613,7 +2635,7 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, int ret; if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) && - wow_mode != ATH6KL_WOW_MODE_DISABLE) { + wow_mode != ATH6KL_WOW_MODE_DISABLE) { ath6kl_err("invalid wow mode: %d\n", wow_mode); return -EINVAL; } @@ -3014,6 +3036,22 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac, NO_SYNC_WMIFLAG); } +int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable) +{ + struct sk_buff *skb; + struct wmi_ap_hidden_ssid_cmd *cmd; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_hidden_ssid_cmd *) skb->data; + cmd->hidden_ssid = enable ? 1 : 0; + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_HIDDEN_SSID_CMDID, + NO_SYNC_WMIFLAG); +} + /* This command will be used to enable/disable AP uAPSD feature */ int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) { @@ -3183,8 +3221,9 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur) * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P * mgmt operations using station interface. */ -int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, - u32 wait, const u8 *data, u16 data_len) +static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, + u32 freq, u32 wait, const u8 *data, + u16 data_len) { struct sk_buff *skb; struct wmi_send_action_cmd *p; @@ -3220,9 +3259,9 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, NO_SYNC_WMIFLAG); } -int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, - u32 wait, const u8 *data, u16 data_len, - u32 no_cck) +static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, + u32 freq, u32 wait, const u8 *data, + u16 data_len, u32 no_cck) { struct sk_buff *skb; struct wmi_send_mgmt_cmd *p; @@ -3259,6 +3298,32 @@ int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, NO_SYNC_WMIFLAG); } +int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, + u32 wait, const u8 *data, u16 data_len, + u32 no_cck) +{ + int status; + struct ath6kl *ar = wmi->parent_dev; + + if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, + ar->fw_capabilities)) { + /* + * If capable of doing P2P mgmt operations using + * station interface, send additional information like + * supported rates to advertise and xmit rates for + * probe requests + */ + status = __ath6kl_wmi_send_mgmt_cmd(ar->wmi, if_idx, id, freq, + wait, data, data_len, + no_cck); + } else { + status = ath6kl_wmi_send_action_cmd(ar->wmi, if_idx, id, freq, + wait, data, data_len); + } + + return status; +} + int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, const u8 *dst, const u8 *data, u16 data_len) @@ -3370,32 +3435,101 @@ static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len) return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len); } -/* Control Path */ -int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) +/* Process interface specific wmi events, caller would free the datap */ +static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id, + u8 *datap, u32 len) { - struct wmi_cmd_hdr *cmd; struct ath6kl_vif *vif; - u32 len; - u16 id; - u8 if_idx; - u8 *datap; - int ret = 0; - if (WARN_ON(skb == NULL)) + vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx); + if (!vif) { + ath6kl_dbg(ATH6KL_DBG_WMI, + "Wmi event for unavailable vif, vif_index:%d\n", + if_idx); return -EINVAL; + } - if (skb->len < sizeof(struct wmi_cmd_hdr)) { - ath6kl_err("bad packet 1\n"); - dev_kfree_skb(skb); + switch (cmd_id) { + case WMI_CONNECT_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n"); + return ath6kl_wmi_connect_event_rx(wmi, datap, len, vif); + case WMI_DISCONNECT_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n"); + return ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif); + case WMI_TKIP_MICERR_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n"); + return ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif); + case WMI_BSSINFO_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); + return ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif); + case WMI_NEIGHBOR_REPORT_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n"); + return ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len, + vif); + case WMI_SCAN_COMPLETE_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n"); + return ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif); + case WMI_REPORT_STATISTICS_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n"); + return ath6kl_wmi_stats_event_rx(wmi, datap, len, vif); + case WMI_CAC_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n"); + return ath6kl_wmi_cac_event_rx(wmi, datap, len, vif); + case WMI_PSPOLL_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n"); + return ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif); + case WMI_DTIMEXPIRY_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n"); + return ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif); + case WMI_ADDBA_REQ_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n"); + return ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif); + case WMI_DELBA_REQ_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n"); + return ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif); + case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, + "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); + return ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); + case WMI_REMAIN_ON_CHNL_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); + return ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); + case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, + "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n"); + return ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap, + len, vif); + case WMI_TX_STATUS_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n"); + return ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif); + case WMI_RX_PROBE_REQ_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n"); + return ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif); + case WMI_RX_ACTION_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); + return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); + default: + ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); return -EINVAL; } + return 0; +} + +static int ath6kl_wmi_proc_events(struct wmi *wmi, struct sk_buff *skb) +{ + struct wmi_cmd_hdr *cmd; + int ret = 0; + u32 len; + u16 id; + u8 if_idx; + u8 *datap; + cmd = (struct wmi_cmd_hdr *) skb->data; id = le16_to_cpu(cmd->cmd_id); if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK; skb_pull(skb, sizeof(struct wmi_cmd_hdr)); - datap = skb->data; len = skb->len; @@ -3403,15 +3537,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ", datap, len); - vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx); - if (!vif) { - ath6kl_dbg(ATH6KL_DBG_WMI, - "Wmi event for unavailable vif, vif_index:%d\n", - if_idx); - dev_kfree_skb(skb); - return -EINVAL; - } - switch (id) { case WMI_GET_BITRATE_CMDID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n"); @@ -3429,26 +3554,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n"); ret = ath6kl_wmi_ready_event_rx(wmi, datap, len); break; - case WMI_CONNECT_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n"); - ret = ath6kl_wmi_connect_event_rx(wmi, datap, len, vif); - break; - case WMI_DISCONNECT_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n"); - ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif); - break; case WMI_PEER_NODE_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n"); ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len); break; - case WMI_TKIP_MICERR_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n"); - ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif); - break; - case WMI_BSSINFO_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); - ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif); - break; case WMI_REGDOMAIN_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n"); ath6kl_wmi_regdomain_event(wmi, datap, len); @@ -3457,23 +3566,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n"); ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len); break; - case WMI_NEIGHBOR_REPORT_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n"); - ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len, - vif); - break; - case WMI_SCAN_COMPLETE_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n"); - ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif); - break; case WMI_CMDERROR_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n"); ret = ath6kl_wmi_error_event_rx(wmi, datap, len); break; - case WMI_REPORT_STATISTICS_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n"); - ret = ath6kl_wmi_stats_event_rx(wmi, datap, len, vif); - break; case WMI_RSSI_THRESHOLD_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n"); ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len); @@ -3493,10 +3589,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n"); ret = ath6kl_wmi_control_rx_xtnd(wmi, skb); break; - case WMI_CAC_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n"); - ret = ath6kl_wmi_cac_event_rx(wmi, datap, len, vif); - break; case WMI_CHANNEL_CHANGE_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n"); break; @@ -3536,28 +3628,12 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n"); ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len); break; - case WMI_PSPOLL_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n"); - ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif); - break; - case WMI_DTIMEXPIRY_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n"); - ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif); - break; case WMI_SET_PARAMS_REPLY_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n"); break; - case WMI_ADDBA_REQ_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n"); - ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif); - break; case WMI_ADDBA_RESP_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n"); break; - case WMI_DELBA_REQ_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n"); - ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif); - break; case WMI_REPORT_BTCOEX_CONFIG_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n"); @@ -3570,52 +3646,39 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); ret = ath6kl_wmi_tx_complete_event_rx(datap, len); break; - case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, - "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); - ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); - break; - case WMI_REMAIN_ON_CHNL_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); - ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); - break; - case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, - "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n"); - ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap, - len, vif); - break; - case WMI_TX_STATUS_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n"); - ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif); - break; - case WMI_RX_PROBE_REQ_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n"); - ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif); - break; case WMI_P2P_CAPABILITIES_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n"); ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len); break; - case WMI_RX_ACTION_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); - ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); - break; case WMI_P2P_INFO_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n"); ret = ath6kl_wmi_p2p_info_event_rx(datap, len); break; default: - ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id); - ret = -EINVAL; + /* may be the event is interface specific */ + ret = ath6kl_wmi_proc_events_vif(wmi, if_idx, id, datap, len); break; } dev_kfree_skb(skb); - return ret; } +/* Control Path */ +int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) +{ + if (WARN_ON(skb == NULL)) + return -EINVAL; + + if (skb->len < sizeof(struct wmi_cmd_hdr)) { + ath6kl_err("bad packet 1\n"); + dev_kfree_skb(skb); + return -EINVAL; + } + + return ath6kl_wmi_proc_events(wmi, skb); +} + void ath6kl_wmi_reset(struct wmi *wmi) { spin_lock_bh(&wmi->lock); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index e7919869725e..4092e3e80790 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -110,6 +111,8 @@ struct wmi { u8 fat_pipe_exist; struct ath6kl *parent_dev; u8 pwr_mode; + + /* protects fat_pipe_exist and stream_exist_for_ac */ spinlock_t lock; enum htc_endpoint_id ep_id; struct sq_threshold_params @@ -997,6 +1000,12 @@ struct wmi_listen_int_cmd { __le16 num_beacons; } __packed; +/* WMI_SET_BMISS_TIME_CMDID */ +struct wmi_bmiss_time_cmd { + __le16 bmiss_time; + __le16 num_beacons; +}; + /* WMI_SET_POWER_MODE_CMDID */ enum wmi_power_mode { REC_POWER = 0x01, @@ -1014,7 +1023,7 @@ struct wmi_power_mode_cmd { */ enum power_save_fail_event_policy { SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1, - IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2, + IGNORE_PS_FAIL_DURING_SCAN = 2, }; struct wmi_power_params_cmd { @@ -1212,7 +1221,7 @@ struct wmi_snr_threshold_params_cmd { enum wmi_preamble_policy { WMI_IGNORE_BARKER_IN_ERP = 0, - WMI_DONOT_IGNORE_BARKER_IN_ERP + WMI_FOLLOW_BARKER_IN_ERP, }; struct wmi_set_lpreamble_cmd { @@ -2128,6 +2137,10 @@ struct wmi_rx_frame_format_cmd { u8 reserved[1]; } __packed; +struct wmi_ap_hidden_ssid_cmd { + u8 hidden_ssid; +} __packed; + /* AP mode events */ struct wmi_ap_set_apsd_cmd { u8 enable; @@ -2413,6 +2426,8 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, u16 listen_interval, u16 listen_beacons); +int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx, + u16 bmiss_time, u16 num_beacons); int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode); int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period, u16 ps_poll_num, u16 dtim_policy, @@ -2484,6 +2499,7 @@ u8 ath6kl_wmi_get_traffic_class(u8 user_priority); u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri); /* AP mode */ +int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable); int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, struct wmi_connect_cmd *p); @@ -2505,9 +2521,6 @@ int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable); int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur); -int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, - u32 wait, const u8 *data, u16 data_len); - int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, u32 wait, const u8 *data, u16 data_len, u32 no_cck); diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 86a891f93fc9..d7d8e9199140 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -834,9 +834,10 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); - if (AR_SREV_9271_10(ah)) - REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, - modesIndex, regWrites); + if (AR_SREV_9271_10(ah)) { + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA); + REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa); + } ENABLE_REGWRITE_BUFFER(ah); @@ -858,21 +859,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REGWRITE_BUFFER_FLUSH(ah); - if (AR_SREV_9271(ah)) { - if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) - REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271, - modesIndex, regWrites); - else - REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, - modesIndex, regWrites); - } - REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { - REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - } ar5008_hw_override_ini(ah, chan); ar5008_hw_set_channel_regs(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index e3f268900763..d9a69fc470cd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -34,23 +34,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9271Modes_9271), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, ARRAY_SIZE(ar9271Common_9271), 2); - INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271, - ar9287Common_normal_cck_fir_coeff_9287_1_1, - ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2); - INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271, - ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, - ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2); - INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, - ar9271Modes_9271_1_0_only, - ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); - INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271, - ar9271Modes_high_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); - INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, - ar9271Modes_normal_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); return; } @@ -79,7 +64,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, ARRAY_SIZE(ar9280Common_9280_2), 2); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9280Modes_fast_clock_9280_2, ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); } else if (AR_SREV_9160_10_OR_LATER(ah)) { @@ -160,11 +145,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INI_RA(addac, 31,1) = 0; } } -} - -/* Support for Japan ch.14 (2484) spread */ -void ar9002_hw_cck_chan14_spread(struct ath_hw *ah) -{ if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniCckfirNormal, ar9287Common_normal_cck_fir_coeff_9287_1_1, @@ -204,14 +184,10 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) } } -static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) +static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) { - u32 txgain_type; - if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) { - txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); - if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9280Modes_high_power_tx_gain_9280_2, @@ -227,8 +203,22 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) } } +static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) +{ + if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9271Modes_high_power_tx_gain_9271, + ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9271Modes_normal_power_tx_gain_9271, + ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); +} + static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) { + u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); + if (AR_SREV_9287_11_OR_LATER(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9287Modes_rx_gain_9287_1_1, @@ -236,15 +226,15 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) else if (AR_SREV_9280_20(ah)) ar9280_20_hw_init_rxgain_ini(ah); - if (AR_SREV_9287_11_OR_LATER(ah)) { + if (AR_SREV_9271(ah)) { + ar9271_hw_init_txgain_ini(ah, txgain_type); + } else if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9287Modes_tx_gain_9287_1_1, ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); } else if (AR_SREV_9280_20(ah)) { - ar9280_20_hw_init_txgain_ini(ah); + ar9280_20_hw_init_txgain_ini(ah, txgain_type); } else if (AR_SREV_9285_12_OR_LATER(ah)) { - u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); - /* txgain table */ if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { if (AR_SREV_9285E_20(ah)) { diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index d571c329ee59..4d18c66a6790 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -3092,12 +3092,6 @@ static const u32 ar9271Common_9271[][2] = { {0x0000d384, 0xf3307ff0}, }; -static const u32 ar9271Modes_9271_1_0_only[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, -}; - static const u32 ar9271Modes_9271_ANI_reg[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 7b6417b5212e..aa2abaf31cba 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -347,15 +347,12 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags) { struct ar5416_desc *ads = AR5416DESC(ds); - struct ath9k_hw_capabilities *pCap = &ah->caps; ads->ds_ctl1 = size & AR_BufLen; if (flags & ATH9K_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxIntrReq; - ads->ds_rxstatus8 &= ~AR_RxDone; - if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) - memset(&(ads->u), 0, sizeof(ads->u)); + memset(&ads->u.rx, 0, sizeof(ads->u.rx)); } EXPORT_SYMBOL(ath9k_hw_setuprxdesc); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 453af6dc514b..f9eb2c357169 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -60,6 +60,8 @@ #define AR_PHY_RF_CTL3 0x9828 #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 +#define AR_PHY_TX_END_TO_ADC_ON 0xFF000000 +#define AR_PHY_TX_END_TO_ADC_ON_S 24 #define AR_PHY_ADC_CTL 0x982C #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 026f9de15d15..46c79a3d4737 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -295,266 +295,6 @@ static const u32 ar9300_2p2_radio_core[][2] = { {0x00016bd4, 0x00000000}, }; -static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x02000101}, - {0x0000a004, 0x02000102}, - {0x0000a008, 0x02000103}, - {0x0000a00c, 0x02000104}, - {0x0000a010, 0x02000200}, - {0x0000a014, 0x02000201}, - {0x0000a018, 0x02000202}, - {0x0000a01c, 0x02000203}, - {0x0000a020, 0x02000204}, - {0x0000a024, 0x02000205}, - {0x0000a028, 0x02000208}, - {0x0000a02c, 0x02000302}, - {0x0000a030, 0x02000303}, - {0x0000a034, 0x02000304}, - {0x0000a038, 0x02000400}, - {0x0000a03c, 0x02010300}, - {0x0000a040, 0x02010301}, - {0x0000a044, 0x02010302}, - {0x0000a048, 0x02000500}, - {0x0000a04c, 0x02010400}, - {0x0000a050, 0x02020300}, - {0x0000a054, 0x02020301}, - {0x0000a058, 0x02020302}, - {0x0000a05c, 0x02020303}, - {0x0000a060, 0x02020400}, - {0x0000a064, 0x02030300}, - {0x0000a068, 0x02030301}, - {0x0000a06c, 0x02030302}, - {0x0000a070, 0x02030303}, - {0x0000a074, 0x02030400}, - {0x0000a078, 0x02040300}, - {0x0000a07c, 0x02040301}, - {0x0000a080, 0x02040302}, - {0x0000a084, 0x02040303}, - {0x0000a088, 0x02030500}, - {0x0000a08c, 0x02040400}, - {0x0000a090, 0x02050203}, - {0x0000a094, 0x02050204}, - {0x0000a098, 0x02050205}, - {0x0000a09c, 0x02040500}, - {0x0000a0a0, 0x02050301}, - {0x0000a0a4, 0x02050302}, - {0x0000a0a8, 0x02050303}, - {0x0000a0ac, 0x02050400}, - {0x0000a0b0, 0x02050401}, - {0x0000a0b4, 0x02050402}, - {0x0000a0b8, 0x02050403}, - {0x0000a0bc, 0x02050500}, - {0x0000a0c0, 0x02050501}, - {0x0000a0c4, 0x02050502}, - {0x0000a0c8, 0x02050503}, - {0x0000a0cc, 0x02050504}, - {0x0000a0d0, 0x02050600}, - {0x0000a0d4, 0x02050601}, - {0x0000a0d8, 0x02050602}, - {0x0000a0dc, 0x02050603}, - {0x0000a0e0, 0x02050604}, - {0x0000a0e4, 0x02050700}, - {0x0000a0e8, 0x02050701}, - {0x0000a0ec, 0x02050702}, - {0x0000a0f0, 0x02050703}, - {0x0000a0f4, 0x02050704}, - {0x0000a0f8, 0x02050705}, - {0x0000a0fc, 0x02050708}, - {0x0000a100, 0x02050709}, - {0x0000a104, 0x0205070a}, - {0x0000a108, 0x0205070b}, - {0x0000a10c, 0x0205070c}, - {0x0000a110, 0x0205070d}, - {0x0000a114, 0x02050710}, - {0x0000a118, 0x02050711}, - {0x0000a11c, 0x02050712}, - {0x0000a120, 0x02050713}, - {0x0000a124, 0x02050714}, - {0x0000a128, 0x02050715}, - {0x0000a12c, 0x02050730}, - {0x0000a130, 0x02050731}, - {0x0000a134, 0x02050732}, - {0x0000a138, 0x02050733}, - {0x0000a13c, 0x02050734}, - {0x0000a140, 0x02050735}, - {0x0000a144, 0x02050750}, - {0x0000a148, 0x02050751}, - {0x0000a14c, 0x02050752}, - {0x0000a150, 0x02050753}, - {0x0000a154, 0x02050754}, - {0x0000a158, 0x02050755}, - {0x0000a15c, 0x02050770}, - {0x0000a160, 0x02050771}, - {0x0000a164, 0x02050772}, - {0x0000a168, 0x02050773}, - {0x0000a16c, 0x02050774}, - {0x0000a170, 0x02050775}, - {0x0000a174, 0x00000776}, - {0x0000a178, 0x00000776}, - {0x0000a17c, 0x00000776}, - {0x0000a180, 0x00000776}, - {0x0000a184, 0x00000776}, - {0x0000a188, 0x00000776}, - {0x0000a18c, 0x00000776}, - {0x0000a190, 0x00000776}, - {0x0000a194, 0x00000776}, - {0x0000a198, 0x00000776}, - {0x0000a19c, 0x00000776}, - {0x0000a1a0, 0x00000776}, - {0x0000a1a4, 0x00000776}, - {0x0000a1a8, 0x00000776}, - {0x0000a1ac, 0x00000776}, - {0x0000a1b0, 0x00000776}, - {0x0000a1b4, 0x00000776}, - {0x0000a1b8, 0x00000776}, - {0x0000a1bc, 0x00000776}, - {0x0000a1c0, 0x00000776}, - {0x0000a1c4, 0x00000776}, - {0x0000a1c8, 0x00000776}, - {0x0000a1cc, 0x00000776}, - {0x0000a1d0, 0x00000776}, - {0x0000a1d4, 0x00000776}, - {0x0000a1d8, 0x00000776}, - {0x0000a1dc, 0x00000776}, - {0x0000a1e0, 0x00000776}, - {0x0000a1e4, 0x00000776}, - {0x0000a1e8, 0x00000776}, - {0x0000a1ec, 0x00000776}, - {0x0000a1f0, 0x00000776}, - {0x0000a1f4, 0x00000776}, - {0x0000a1f8, 0x00000776}, - {0x0000a1fc, 0x00000776}, - {0x0000b000, 0x02000101}, - {0x0000b004, 0x02000102}, - {0x0000b008, 0x02000103}, - {0x0000b00c, 0x02000104}, - {0x0000b010, 0x02000200}, - {0x0000b014, 0x02000201}, - {0x0000b018, 0x02000202}, - {0x0000b01c, 0x02000203}, - {0x0000b020, 0x02000204}, - {0x0000b024, 0x02000205}, - {0x0000b028, 0x02000208}, - {0x0000b02c, 0x02000302}, - {0x0000b030, 0x02000303}, - {0x0000b034, 0x02000304}, - {0x0000b038, 0x02000400}, - {0x0000b03c, 0x02010300}, - {0x0000b040, 0x02010301}, - {0x0000b044, 0x02010302}, - {0x0000b048, 0x02000500}, - {0x0000b04c, 0x02010400}, - {0x0000b050, 0x02020300}, - {0x0000b054, 0x02020301}, - {0x0000b058, 0x02020302}, - {0x0000b05c, 0x02020303}, - {0x0000b060, 0x02020400}, - {0x0000b064, 0x02030300}, - {0x0000b068, 0x02030301}, - {0x0000b06c, 0x02030302}, - {0x0000b070, 0x02030303}, - {0x0000b074, 0x02030400}, - {0x0000b078, 0x02040300}, - {0x0000b07c, 0x02040301}, - {0x0000b080, 0x02040302}, - {0x0000b084, 0x02040303}, - {0x0000b088, 0x02030500}, - {0x0000b08c, 0x02040400}, - {0x0000b090, 0x02050203}, - {0x0000b094, 0x02050204}, - {0x0000b098, 0x02050205}, - {0x0000b09c, 0x02040500}, - {0x0000b0a0, 0x02050301}, - {0x0000b0a4, 0x02050302}, - {0x0000b0a8, 0x02050303}, - {0x0000b0ac, 0x02050400}, - {0x0000b0b0, 0x02050401}, - {0x0000b0b4, 0x02050402}, - {0x0000b0b8, 0x02050403}, - {0x0000b0bc, 0x02050500}, - {0x0000b0c0, 0x02050501}, - {0x0000b0c4, 0x02050502}, - {0x0000b0c8, 0x02050503}, - {0x0000b0cc, 0x02050504}, - {0x0000b0d0, 0x02050600}, - {0x0000b0d4, 0x02050601}, - {0x0000b0d8, 0x02050602}, - {0x0000b0dc, 0x02050603}, - {0x0000b0e0, 0x02050604}, - {0x0000b0e4, 0x02050700}, - {0x0000b0e8, 0x02050701}, - {0x0000b0ec, 0x02050702}, - {0x0000b0f0, 0x02050703}, - {0x0000b0f4, 0x02050704}, - {0x0000b0f8, 0x02050705}, - {0x0000b0fc, 0x02050708}, - {0x0000b100, 0x02050709}, - {0x0000b104, 0x0205070a}, - {0x0000b108, 0x0205070b}, - {0x0000b10c, 0x0205070c}, - {0x0000b110, 0x0205070d}, - {0x0000b114, 0x02050710}, - {0x0000b118, 0x02050711}, - {0x0000b11c, 0x02050712}, - {0x0000b120, 0x02050713}, - {0x0000b124, 0x02050714}, - {0x0000b128, 0x02050715}, - {0x0000b12c, 0x02050730}, - {0x0000b130, 0x02050731}, - {0x0000b134, 0x02050732}, - {0x0000b138, 0x02050733}, - {0x0000b13c, 0x02050734}, - {0x0000b140, 0x02050735}, - {0x0000b144, 0x02050750}, - {0x0000b148, 0x02050751}, - {0x0000b14c, 0x02050752}, - {0x0000b150, 0x02050753}, - {0x0000b154, 0x02050754}, - {0x0000b158, 0x02050755}, - {0x0000b15c, 0x02050770}, - {0x0000b160, 0x02050771}, - {0x0000b164, 0x02050772}, - {0x0000b168, 0x02050773}, - {0x0000b16c, 0x02050774}, - {0x0000b170, 0x02050775}, - {0x0000b174, 0x00000776}, - {0x0000b178, 0x00000776}, - {0x0000b17c, 0x00000776}, - {0x0000b180, 0x00000776}, - {0x0000b184, 0x00000776}, - {0x0000b188, 0x00000776}, - {0x0000b18c, 0x00000776}, - {0x0000b190, 0x00000776}, - {0x0000b194, 0x00000776}, - {0x0000b198, 0x00000776}, - {0x0000b19c, 0x00000776}, - {0x0000b1a0, 0x00000776}, - {0x0000b1a4, 0x00000776}, - {0x0000b1a8, 0x00000776}, - {0x0000b1ac, 0x00000776}, - {0x0000b1b0, 0x00000776}, - {0x0000b1b4, 0x00000776}, - {0x0000b1b8, 0x00000776}, - {0x0000b1bc, 0x00000776}, - {0x0000b1c0, 0x00000776}, - {0x0000b1c4, 0x00000776}, - {0x0000b1c8, 0x00000776}, - {0x0000b1cc, 0x00000776}, - {0x0000b1d0, 0x00000776}, - {0x0000b1d4, 0x00000776}, - {0x0000b1d8, 0x00000776}, - {0x0000b1dc, 0x00000776}, - {0x0000b1e0, 0x00000776}, - {0x0000b1e4, 0x00000776}, - {0x0000b1e8, 0x00000776}, - {0x0000b1ec, 0x00000776}, - {0x0000b1f0, 0x00000776}, - {0x0000b1f4, 0x00000776}, - {0x0000b1f8, 0x00000776}, - {0x0000b1fc, 0x00000776}, -}; - static const u32 ar9300_2p2_mac_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, @@ -572,48 +312,6 @@ static const u32 ar9300_2p2_soc_postamble[][5] = { {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, }; -static const u32 ar9200_merlin_2p2_radio_core[][2] = { - /* Addr allmodes */ - {0x00007800, 0x00040000}, - {0x00007804, 0xdb005012}, - {0x00007808, 0x04924914}, - {0x0000780c, 0x21084210}, - {0x00007810, 0x6d801300}, - {0x00007814, 0x0019beff}, - {0x00007818, 0x07e41000}, - {0x0000781c, 0x00392000}, - {0x00007820, 0x92592480}, - {0x00007824, 0x00040000}, - {0x00007828, 0xdb005012}, - {0x0000782c, 0x04924914}, - {0x00007830, 0x21084210}, - {0x00007834, 0x6d801300}, - {0x00007838, 0x0019beff}, - {0x0000783c, 0x07e40000}, - {0x00007840, 0x00392000}, - {0x00007844, 0x92592480}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, - {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x92592692}, - {0x0000785c, 0x00000000}, - {0x00007860, 0x56400000}, - {0x00007864, 0x0a8e370e}, - {0x00007868, 0xc0102850}, - {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, - {0x00007874, 0x001b6db0}, - {0x00007878, 0x00376b63}, - {0x0000787c, 0x06db6db6}, - {0x00007880, 0x006d8000}, - {0x00007884, 0xffeffffe}, - {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, - {0x00007894, 0x5a108000}, -}; - static const u32 ar9300_2p2_baseband_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 7b4aa000cc2e..0f56e322dd3b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -87,11 +87,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* additional clock settings */ if (ah->is_clk_25mhz) - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p1_xtal_25M, ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); else - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p1_xtal_40M, ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); } else if (AR_SREV_9330_12(ah)) { @@ -140,11 +140,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* additional clock settings */ if (ah->is_clk_25mhz) - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p2_xtal_25M, ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); else - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p2_xtal_40M, ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); } else if (AR_SREV_9340(ah)) { @@ -194,15 +194,16 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), 5); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9340Modes_fast_clock_1p0, ARRAY_SIZE(ar9340Modes_fast_clock_1p0), 3); - INIT_INI_ARRAY(&ah->iniModesAdditional_40M, - ar9340_1p0_radio_core_40M, - ARRAY_SIZE(ar9340_1p0_radio_core_40M), - 2); + if (!ah->is_clk_25mhz) + INIT_INI_ARRAY(&ah->iniAdditional, + ar9340_1p0_radio_core_40M, + ARRAY_SIZE(ar9340_1p0_radio_core_40M), + 2); } else if (AR_SREV_9485_11(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -321,7 +322,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 2); /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9462_modes_fast_clock_2p0, ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3); @@ -378,7 +379,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), 5); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9580_1p0_modes_fast_clock, ARRAY_SIZE(ar9580_1p0_modes_fast_clock), 3); @@ -445,7 +446,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 2); /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9300Modes_fast_clock_2p2, ARRAY_SIZE(ar9300Modes_fast_clock_2p2), 3); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 70e27d2a5e43..bc992b237ae5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -679,18 +679,17 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, * different modal values. */ if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - if (AR_SREV_9330(ah)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); - - if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) - REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); if (AR_SREV_9462(ah)) ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); + if (chan->channel == 2484) + ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); + ah->modes_index = modesIndex; ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); @@ -1320,13 +1319,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, * different modal values. */ if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); - - if (AR_SREV_9330(ah)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) - REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); ah->modes_index = modesIndex; *ini_reloaded = true; diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3d8e51cd5d8f..8c84049682ab 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -583,19 +583,13 @@ struct ath_ant_comb { #define SC_OP_INVALID BIT(0) #define SC_OP_BEACONS BIT(1) -#define SC_OP_RXAGGR BIT(2) -#define SC_OP_TXAGGR BIT(3) -#define SC_OP_OFFCHANNEL BIT(4) -#define SC_OP_PREAMBLE_SHORT BIT(5) -#define SC_OP_PROTECT_ENABLE BIT(6) -#define SC_OP_RXFLUSH BIT(7) -#define SC_OP_LED_ASSOCIATED BIT(8) -#define SC_OP_LED_ON BIT(9) -#define SC_OP_TSF_RESET BIT(11) -#define SC_OP_BT_PRIORITY_DETECTED BIT(12) -#define SC_OP_BT_SCAN BIT(13) -#define SC_OP_ANI_RUN BIT(14) -#define SC_OP_PRIM_STA_VIF BIT(15) +#define SC_OP_OFFCHANNEL BIT(2) +#define SC_OP_RXFLUSH BIT(3) +#define SC_OP_TSF_RESET BIT(4) +#define SC_OP_BT_PRIORITY_DETECTED BIT(5) +#define SC_OP_BT_SCAN BIT(6) +#define SC_OP_ANI_RUN BIT(7) +#define SC_OP_PRIM_STA_VIF BIT(8) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) @@ -617,15 +611,12 @@ struct ath9k_vif_iter_data { int nstations; /* number of station vifs */ int nwds; /* number of WDS vifs */ int nadhocs; /* number of adhoc vifs */ - int nothers; /* number of vifs not specified above. */ }; struct ath_softc { struct ieee80211_hw *hw; struct device *dev; - int chan_idx; - int chan_is_ht; struct survey_info *cur_survey; struct survey_info survey[ATH9K_NUM_CHANNELS]; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 43882f9e25c4..626418222c85 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -67,7 +67,7 @@ int ath_beaconq_config(struct ath_softc *sc) * up rate codes, and channel flags. Beacons are always sent out at the * lowest rate, and are not retried. */ -static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, +static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, struct ath_buf *bf, int rateidx) { struct sk_buff *skb = bf->bf_mpdu; @@ -82,7 +82,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, sband = &sc->sbands[common->hw->conf.channel->band]; rate = sband->bitrates[rateidx].hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) + if (vif->bss_conf.use_short_preamble) rate |= sband->bitrates[rateidx].hw_value_short; memset(&info, 0, sizeof(info)); @@ -209,7 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, } } - ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx); + ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx); while (skb) { ath_tx_cabq(hw, skb); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index c2edf688da49..35d1c8e91d1c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -738,9 +738,9 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" - " ADHOC: %i OTHER: %i TOTAL: %hi BEACON-VIF: %hi\n", + " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", iter_data.naps, iter_data.nstations, iter_data.nmeshes, - iter_data.nwds, iter_data.nadhocs, iter_data.nothers, + iter_data.nwds, iter_data.nadhocs, sc->nvifs, sc->nbcnvifs); if (len > sizeof(buf)) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 63e4c4b1cb3d..fbe23de1297f 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -362,7 +362,8 @@ void ath9k_stop_btcoex(struct ath_softc *sc) ath9k_hw_btcoex_disable(ah); if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) ath9k_btcoex_timer_pause(sc); - ath_mci_flush_profile(&sc->btcoex.mci); + if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) + ath_mci_flush_profile(&sc->btcoex.mci); } } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2a29a7cdef18..2b8f61c210e1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -919,7 +919,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) /* setup initial channel */ init_channel = ath9k_cmn_get_curchannel(hw, ah); - ath9k_hw_htc_resetinit(ah); ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (ret) { ath_err(common, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2eb0ef315e31..6c69e4e8b1cb 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -449,6 +449,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) ah->slottime = ATH9K_SLOT_TIME_9; ah->globaltxtimeout = (u32) -1; ah->power_mode = ATH9K_PM_UNDEFINED; + ah->htc_reset_init = true; } static int ath9k_hw_init_macaddr(struct ath_hw *ah) @@ -555,7 +556,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) return -EIO; } - if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && !ah->is_pciexpress)) { @@ -619,9 +620,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (!ah->is_pciexpress) ath9k_hw_disablepcie(ah); - if (!AR_SREV_9300_20_OR_LATER(ah)) - ar9002_hw_cck_chan14_spread(ah); - r = ath9k_hw_post_init(ah); if (r) return r; @@ -1521,17 +1519,81 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_check_alive); +/* + * Fast channel change: + * (Change synthesizer based on channel freq without resetting chip) + * + * Don't do FCC when + * - Flag is not set + * - Chip is just coming out of full sleep + * - Channel to be set is same as current channel + * - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel) + */ +static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) +{ + struct ath_common *common = ath9k_hw_common(ah); + int ret; + + if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) + goto fail; + + if (ah->chip_fullsleep) + goto fail; + + if (!ah->curchan) + goto fail; + + if (chan->channel == ah->curchan->channel) + goto fail; + + if ((chan->channelFlags & CHANNEL_ALL) != + (ah->curchan->channelFlags & CHANNEL_ALL)) + goto fail; + + if (!ath9k_hw_check_alive(ah)) + goto fail; + + /* + * For AR9462, make sure that calibration data for + * re-using are present. + */ + if (AR_SREV_9462(ah) && (!ah->caldata || + !ah->caldata->done_txiqcal_once || + !ah->caldata->done_txclcal_once || + !ah->caldata->rtt_hist.num_readings)) + goto fail; + + ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", + ah->curchan->channel, chan->channel); + + ret = ath9k_hw_channel_change(ah, chan); + if (!ret) + goto fail; + + ath9k_hw_loadnf(ah, ah->curchan); + ath9k_hw_start_nfcal(ah, true); + + if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah)) + ar9003_mci_2g5g_switch(ah, true); + + if (AR_SREV_9271(ah)) + ar9002_hw_load_ani_reg(ah, chan); + + return 0; +fail: + return -EINVAL; +} + int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, - struct ath9k_hw_cal_data *caldata, bool bChannelChange) + struct ath9k_hw_cal_data *caldata, bool fastcc) { struct ath_common *common = ath9k_hw_common(ah); u32 saveLedState; - struct ath9k_channel *curchan = ah->curchan; u32 saveDefAntenna; u32 macStaId1; u64 tsf = 0; int i, r; - bool allow_fbs = false, start_mci_reset = false; + bool start_mci_reset = false; bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); bool save_fullsleep = ah->chip_fullsleep; @@ -1544,8 +1606,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) return -EIO; - if (curchan && !ah->chip_fullsleep) - ath9k_hw_getnf(ah, curchan); + if (ah->curchan && !ah->chip_fullsleep) + ath9k_hw_getnf(ah, ah->curchan); ah->caldata = caldata; if (caldata && @@ -1558,32 +1620,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } ah->noise = ath9k_hw_getchan_noise(ah, chan); - if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) - bChannelChange = false; - - if (caldata && - caldata->done_txiqcal_once && - caldata->done_txclcal_once && - caldata->rtt_hist.num_readings) - allow_fbs = true; - - if (bChannelChange && - (!ah->chip_fullsleep) && - (ah->curchan != NULL) && - (chan->channel != ah->curchan->channel) && - (allow_fbs || - ((chan->channelFlags & CHANNEL_ALL) == - (ah->curchan->channelFlags & CHANNEL_ALL)))) { - if (ath9k_hw_channel_change(ah, chan)) { - ath9k_hw_loadnf(ah, ah->curchan); - ath9k_hw_start_nfcal(ah, true); - if (mci && ar9003_mci_is_ready(ah)) - ar9003_mci_2g5g_switch(ah, true); - - if (AR_SREV_9271(ah)) - ar9002_hw_load_ani_reg(ah, chan); - return 0; - } + if (fastcc) { + r = ath9k_hw_do_fastcc(ah, chan); + if (!r) + return r; } if (mci) @@ -2389,8 +2429,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9485_OR_LATER(ah)) ah->enabled_cals |= TX_IQ_ON_AGC_CAL; } - if (AR_SREV_9462(ah)) - pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; + + if (AR_SREV_9462(ah)) { + + if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) + pCap->hw_caps |= ATH9K_HW_CAP_MCI; + + if (AR_SREV_9462_20(ah)) + pCap->hw_caps |= ATH9K_HW_CAP_RTT; + + } + return 0; } @@ -2516,12 +2565,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) } EXPORT_SYMBOL(ath9k_hw_set_gpio); -u32 ath9k_hw_getdefantenna(struct ath_hw *ah) -{ - return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; -} -EXPORT_SYMBOL(ath9k_hw_getdefantenna); - void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) { REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); @@ -2579,6 +2622,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah) return false; ath9k_hw_init_pll(ah, NULL); + ah->htc_reset_init = true; return true; } EXPORT_SYMBOL(ath9k_hw_phy_disable); @@ -2939,12 +2983,6 @@ EXPORT_SYMBOL(ath_gen_timer_isr); /* HTC */ /********/ -void ath9k_hw_htc_resetinit(struct ath_hw *ah) -{ - ah->htc_reset_init = true; -} -EXPORT_SYMBOL(ath9k_hw_htc_resetinit); - static struct { u32 version; const char * name; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1707137e0a30..aa1680a0c7fd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -827,19 +827,14 @@ struct ath_hw { struct ar5416IniArray iniAddac; struct ar5416IniArray iniPcieSerdes; struct ar5416IniArray iniPcieSerdesLowPower; - struct ar5416IniArray iniModesAdditional; - struct ar5416IniArray iniModesAdditional_40M; + struct ar5416IniArray iniModesFastClock; + struct ar5416IniArray iniAdditional; struct ar5416IniArray iniModesRxGain; struct ar5416IniArray iniModesTxGain; - struct ar5416IniArray iniModes_9271_1_0_only; struct ar5416IniArray iniCckfirNormal; struct ar5416IniArray iniCckfirJapan2484; struct ar5416IniArray ini_japan2484; - struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271; - struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271; struct ar5416IniArray iniModes_9271_ANI_reg; - struct ar5416IniArray iniModes_high_power_tx_gain_9271; - struct ar5416IniArray iniModes_normal_power_tx_gain_9271; struct ar5416IniArray ini_radio_post_sys2ant; struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; @@ -924,7 +919,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid); void ath9k_hw_deinit(struct ath_hw *ah); int ath9k_hw_init(struct ath_hw *ah); int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, - struct ath9k_hw_cal_data *caldata, bool bChannelChange); + struct ath9k_hw_cal_data *caldata, bool fastcc); int ath9k_hw_fill_cap_info(struct ath_hw *ah); u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); @@ -934,7 +929,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, u32 ah_signal_type); void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); -u32 ath9k_hw_getdefantenna(struct ath_hw *ah); void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); /* General Operation */ @@ -988,9 +982,6 @@ void ath_gen_timer_isr(struct ath_hw *hw); void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); -/* HTC */ -void ath9k_hw_htc_resetinit(struct ath_hw *ah); - /* PHY */ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, u32 *coef_mantissa, u32 *coef_exponent); @@ -1000,7 +991,6 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); * Code Specific to AR5008, AR9001 or AR9002, * we stuff these here to avoid callbacks for AR9003. */ -void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); int ar9002_hw_rf_claim(struct ath_hw *ah); void ar9002_hw_enable_async_fifo(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 944e9b518f19..60159f4ee532 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -172,7 +172,7 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) struct ath_common *common = ath9k_hw_common(ah); struct ath_softc *sc = (struct ath_softc *) common->priv; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { unsigned long flags; spin_lock_irqsave(&sc->sc_serial_rw, flags); iowrite32(val, sc->mem + reg_offset); @@ -188,7 +188,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) struct ath_softc *sc = (struct ath_softc *) common->priv; u32 val; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { unsigned long flags; spin_lock_irqsave(&sc->sc_serial_rw, flags); val = ioread32(sc->mem + reg_offset); @@ -219,7 +219,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl unsigned long uninitialized_var(flags); u32 val; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { spin_lock_irqsave(&sc->sc_serial_rw, flags); val = __ath9k_reg_rmw(sc, reg_offset, set, clr); spin_unlock_irqrestore(&sc->sc_serial_rw, flags); @@ -484,19 +484,11 @@ static void ath9k_init_misc(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; + setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; - - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - sc->sc_flags |= SC_OP_TXAGGR; - sc->sc_flags |= SC_OP_RXAGGR; - } - - sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); - sc->beacon.slottime = ATH9K_SLOT_TIME_9; for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 5f4ae6c9a93c..f7bd2532269c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -185,13 +185,6 @@ bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q) } EXPORT_SYMBOL(ath9k_hw_stop_dma_queue); -void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) -{ - *txqs &= ah->intr_txqs; - ah->intr_txqs &= ~(*txqs); -} -EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs); - bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, const struct ath9k_tx_queue_info *qinfo) { @@ -340,6 +333,15 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, } EXPORT_SYMBOL(ath9k_hw_setuptxqueue); +static void ath9k_hw_clear_queue_interrupts(struct ath_hw *ah, u32 q) +{ + ah->txok_interrupt_mask &= ~(1 << q); + ah->txerr_interrupt_mask &= ~(1 << q); + ah->txdesc_interrupt_mask &= ~(1 << q); + ah->txeol_interrupt_mask &= ~(1 << q); + ah->txurn_interrupt_mask &= ~(1 << q); +} + bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) { struct ath_common *common = ath9k_hw_common(ah); @@ -354,11 +356,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) ath_dbg(common, QUEUE, "Release TX queue: %u\n", q); qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; - ah->txok_interrupt_mask &= ~(1 << q); - ah->txerr_interrupt_mask &= ~(1 << q); - ah->txdesc_interrupt_mask &= ~(1 << q); - ah->txeol_interrupt_mask &= ~(1 << q); - ah->txurn_interrupt_mask &= ~(1 << q); + ath9k_hw_clear_queue_interrupts(ah, q); ath9k_hw_set_txq_interrupts(ah, qi); return true; @@ -510,26 +508,17 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) if (AR_SREV_9300_20_OR_LATER(ah)) REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); - if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) + ath9k_hw_clear_queue_interrupts(ah, q); + if (qi->tqi_qflags & TXQ_FLAG_TXINT_ENABLE) { ah->txok_interrupt_mask |= 1 << q; - else - ah->txok_interrupt_mask &= ~(1 << q); - if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) ah->txerr_interrupt_mask |= 1 << q; - else - ah->txerr_interrupt_mask &= ~(1 << q); + } if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) ah->txdesc_interrupt_mask |= 1 << q; - else - ah->txdesc_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) ah->txeol_interrupt_mask |= 1 << q; - else - ah->txeol_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) ah->txurn_interrupt_mask |= 1 << q; - else - ah->txurn_interrupt_mask &= ~(1 << q); ath9k_hw_set_txq_interrupts(ah, qi); return true; @@ -747,8 +736,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) qi.tqi_cwmax = 0; if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) - qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | - TXQ_FLAG_TXERRINT_ENABLE; + qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); } diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 11dbd1473a13..21c955609e6c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -583,8 +583,7 @@ enum ath9k_tx_queue { #define ATH9K_WME_UPSD 4 enum ath9k_tx_queue_flags { - TXQ_FLAG_TXOKINT_ENABLE = 0x0001, - TXQ_FLAG_TXERRINT_ENABLE = 0x0001, + TXQ_FLAG_TXINT_ENABLE = 0x0001, TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, TXQ_FLAG_TXURNINT_ENABLE = 0x0008, @@ -714,7 +713,6 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); void ath9k_hw_abort_tx_dma(struct ath_hw *ah); -void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, const struct ath9k_tx_queue_info *qinfo); bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index cc2535c38bed..38794850f005 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc) if (--sc->ps_usecount != 0) goto unlock; - if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) + if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) + goto unlock; + + if (sc->ps_idle) mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK))) + PS_WAIT_FOR_PSPOLL_DATA))) mode = ATH9K_PM_NETWORK_SLEEP; else goto unlock; @@ -332,10 +334,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, hchan = ah->curchan; } - if (fastcc && (ah->chip_fullsleep || - !ath9k_hw_check_alive(ah))) - fastcc = false; - if (!ath_prepare_reset(sc, retry_tx, flush)) fastcc = false; @@ -641,7 +639,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, #endif an->sta = sta; an->vif = vif; - if (sc->sc_flags & SC_OP_TXAGGR) { + + if (sta->ht_cap.ht_supported) { ath_tx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor); @@ -660,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) an->sta = NULL; #endif - if (sc->sc_flags & SC_OP_TXAGGR) + if (sta->ht_cap.ht_supported) ath_tx_node_cleanup(sc, an); } @@ -993,12 +992,8 @@ static int ath9k_start(struct ieee80211_hw *hw) curchan->center_freq); ath9k_ps_wakeup(sc); - mutex_lock(&sc->mutex); - /* setup initial channel */ - sc->chan_idx = curchan->hw_value; - init_channel = ath9k_cmn_get_curchannel(hw, ah); /* Reset SERDES registers */ @@ -1047,9 +1042,6 @@ static int ath9k_start(struct ieee80211_hw *hw) sc->sc_flags &= ~SC_OP_INVALID; sc->sc_ah->is_monitoring = false; - /* Disable BMISS interrupt when we're not associated */ - ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); - if (!ath_complete_reset(sc, false)) { r = -EIO; spin_unlock_bh(&sc->sc_pcu_lock); @@ -1277,7 +1269,6 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) iter_data->nwds++; break; default: - iter_data->nothers++; break; } } @@ -1761,7 +1752,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_node *an = (struct ath_node *) sta->drv_priv; - if (!(sc->sc_flags & SC_OP_TXAGGR)) + if (!sta->ht_cap.ht_supported) return; switch (cmd) { @@ -1973,7 +1964,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); - if (changed & BSS_CHANGED_BSSID) { + if (changed & BSS_CHANGED_ASSOC) { ath9k_config_bss(sc, vif); ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", @@ -2053,25 +2044,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath_beacon_config(sc, vif); } - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - sc->sc_flags |= SC_OP_PREAMBLE_SHORT; - else - sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n", - bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && - hw->conf.channel->band != IEEE80211_BAND_5GHZ) - sc->sc_flags |= SC_OP_PROTECT_ENABLE; - else - sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; - } - mutex_unlock(&sc->mutex); ath9k_ps_restore(sc); } @@ -2129,15 +2101,10 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_RX_START: - if (!(sc->sc_flags & SC_OP_RXAGGR)) - ret = -ENOTSUPP; break; case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: - if (!(sc->sc_flags & SC_OP_TXAGGR)) - return -EOPNOTSUPP; - ath9k_ps_wakeup(sc); ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (!ret) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 6407af22f7b9..4f848493fece 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -748,7 +748,8 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc, * If 802.11g protection is enabled, determine whether to use RTS/CTS or * just CTS. Note that this is only done for OFDM/HT unicast frames. */ - if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) && + if ((tx_info->control.vif && + tx_info->control.vif->bss_conf.use_cts_prot) && (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM || WLAN_RC_PHY_HT(rate_table->info[rix].phy))) { rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; @@ -1298,12 +1299,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, return caps; } -static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, +static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta, u8 tidno) { + struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_atx_tid *txtid; - if (!(sc->sc_flags & SC_OP_TXAGGR)) + if (!sta->ht_cap.ht_supported) return false; txtid = ATH_AN_2_TID(an, tidno); @@ -1374,13 +1376,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, if (ieee80211_is_data_qos(fc) && skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { u8 *qc, tid; - struct ath_node *an; qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & 0xf; - an = (struct ath_node *)sta->drv_priv; - if(ath_tx_aggr_check(sc, an, tid)) + if(ath_tx_aggr_check(sc, sta, tid)) ieee80211_start_tx_ba_session(sta, tid, 0); } } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1b1b279c304a..f4ae3ba994a8 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -982,8 +982,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, { struct ath_hw *ah = common->ah; - memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); - /* * everything but the rate is checked here, the rate check is done * separately to avoid doing two lookups for a rate for each frame. @@ -1841,6 +1839,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (sc->sc_flags & SC_OP_RXFLUSH) goto requeue_drop_frag; + memset(rxs, 0, sizeof(struct ieee80211_rx_status)); + rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; if (rs.rs_tstamp > tsf_lower && unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 80b1856f817d..458f81b4a7cb 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1151,6 +1151,7 @@ enum { #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 +#define AR_ENT_OTP_49GHZ_DISABLE 0x00100000 #define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000 #define AR_CH0_BB_DPLL1 0x16180 diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9f785015a7dc..834e6bc45e8b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -955,7 +955,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, */ rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); info->rtscts_rate = rate->hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) + + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) info->rtscts_rate |= rate->hw_value_short; for (i = 0; i < 4; i++) { @@ -1290,14 +1292,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid an = (struct ath_node *)sta->drv_priv; - if (sc->sc_flags & SC_OP_TXAGGR) { - txtid = ATH_AN_2_TID(an, tid); - txtid->baw_size = - IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; - txtid->state |= AGGR_ADDBA_COMPLETE; - txtid->state &= ~AGGR_ADDBA_PROGRESS; - ath_tx_resume_tid(sc, txtid); - } + txtid = ATH_AN_2_TID(an, tid); + txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; + txtid->state |= AGGR_ADDBA_COMPLETE; + txtid->state &= ~AGGR_ADDBA_PROGRESS; + ath_tx_resume_tid(sc, txtid); } /********************/ @@ -1356,8 +1355,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) * based intr on the EOSP frames. */ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | - TXQ_FLAG_TXERRINT_ENABLE; + qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; } else { if (qtype == ATH9K_TX_QUEUE_UAPSD) qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; @@ -1523,7 +1521,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); /* flush any pending frames if aggregation is enabled */ - if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx) ath_txq_drain_pending_buffers(sc, txq); ath_txq_unlock_complete(sc, txq); @@ -1871,7 +1869,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, struct ath_buf *bf; u8 tidno; - if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an && + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an && ieee80211_is_data_qos(hdr->frame_control)) { tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; @@ -2141,7 +2139,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, } else ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_txq_schedule(sc, txq); } @@ -2166,7 +2164,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_txq_schedule(sc, txq); break; } @@ -2263,10 +2261,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) void ath_tx_tasklet(struct ath_softc *sc) { + struct ath_hw *ah = sc->sc_ah; + u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs; int i; - u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); - - ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index d9218fe02036..ea2c737138d3 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c @@ -57,7 +57,8 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, } EXPORT_SYMBOL(ath_rxbuf_alloc); -void ath_printk(const char *level, const char *fmt, ...) +void ath_printk(const char *level, const struct ath_common* common, + const char *fmt, ...) { struct va_format vaf; va_list args; @@ -67,7 +68,11 @@ void ath_printk(const char *level, const char *fmt, ...) vaf.fmt = fmt; vaf.va = &args; - printk("%sath: %pV", level, &vaf); + if (common && common->hw && common->hw->wiphy) + printk("%sath: %s: %pV", + level, wiphy_name(common->hw->wiphy), &vaf); + else + printk("%sath: %pV", level, &vaf); va_end(args); } diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 835462dc1206..67c13af6f206 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -932,6 +932,9 @@ struct b43_wl { /* Flag that implement the queues stopping. */ bool tx_queue_stopped[B43_QOS_QUEUE_NUM]; + /* firmware loading work */ + struct work_struct firmware_load; + /* The device LEDs. */ struct b43_leds leds; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1d633f3b3274..c79e6638c88d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2390,8 +2390,14 @@ error: return err; } -static int b43_request_firmware(struct b43_wldev *dev) +static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl); +static void b43_one_core_detach(struct b43_bus_dev *dev); + +static void b43_request_firmware(struct work_struct *work) { + struct b43_wl *wl = container_of(work, + struct b43_wl, firmware_load); + struct b43_wldev *dev = wl->current_dev; struct b43_request_fw_context *ctx; unsigned int i; int err; @@ -2399,23 +2405,23 @@ static int b43_request_firmware(struct b43_wldev *dev) ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) - return -ENOMEM; + return; ctx->dev = dev; ctx->req_type = B43_FWTYPE_PROPRIETARY; err = b43_try_request_fw(ctx); if (!err) - goto out; /* Successfully loaded it. */ - err = ctx->fatal_failure; - if (err) + goto start_ieee80211; /* Successfully loaded it. */ + /* Was fw version known? */ + if (ctx->fatal_failure) goto out; + /* proprietary fw not found, try open source */ ctx->req_type = B43_FWTYPE_OPENSOURCE; err = b43_try_request_fw(ctx); if (!err) - goto out; /* Successfully loaded it. */ - err = ctx->fatal_failure; - if (err) + goto start_ieee80211; /* Successfully loaded it. */ + if(ctx->fatal_failure) goto out; /* Could not find a usable firmware. Print the errors. */ @@ -2425,11 +2431,20 @@ static int b43_request_firmware(struct b43_wldev *dev) b43err(dev->wl, errmsg); } b43_print_fw_helptext(dev->wl, 1); - err = -ENOENT; + goto out; + +start_ieee80211: + err = ieee80211_register_hw(wl->hw); + if (err) + goto err_one_core_detach; + b43_leds_register(wl->current_dev); + goto out; + +err_one_core_detach: + b43_one_core_detach(dev->dev); out: kfree(ctx); - return err; } static int b43_upload_microcode(struct b43_wldev *dev) @@ -3023,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev) macctl |= B43_MACCTL_INFRA; b43_write32(dev, B43_MMIO_MACCTL, macctl); - err = b43_request_firmware(dev); - if (err) - goto out; err = b43_upload_microcode(dev); if (err) goto out; /* firmware is released later */ @@ -4155,6 +4167,7 @@ redo: mutex_unlock(&wl->mutex); cancel_delayed_work_sync(&dev->periodic_work); cancel_work_sync(&wl->tx_work); + cancel_work_sync(&wl->firmware_load); mutex_lock(&wl->mutex); dev = wl->current_dev; if (!dev || b43_status(dev) < B43_STAT_STARTED) { @@ -5314,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core) if (err) goto bcma_err_wireless_exit; - err = ieee80211_register_hw(wl->hw); - if (err) - goto bcma_err_one_core_detach; - b43_leds_register(wl->current_dev); + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43_request_firmware); + schedule_work(&wl->firmware_load); bcma_out: return err; -bcma_err_one_core_detach: - b43_one_core_detach(dev); bcma_err_wireless_exit: ieee80211_free_hw(wl->hw); return err; @@ -5390,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) if (err) goto err_wireless_exit; - if (first) { - err = ieee80211_register_hw(wl->hw); - if (err) - goto err_one_core_detach; - b43_leds_register(wl->current_dev); - } + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43_request_firmware); + schedule_work(&wl->firmware_load); out: return err; - err_one_core_detach: - b43_one_core_detach(dev); err_wireless_exit: if (first) b43_wireless_exit(dev, wl); diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 98e3d44400c6..a29da674e69d 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -581,6 +581,9 @@ struct b43legacy_wl { struct mutex mutex; /* locks wireless core state */ spinlock_t leds_lock; /* lock for leds */ + /* firmware loading work */ + struct work_struct firmware_load; + /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 75e70bce40f6..df7e16dfb36c 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1557,8 +1557,15 @@ err_format: return -EPROTO; } -static int b43legacy_request_firmware(struct b43legacy_wldev *dev) +static int b43legacy_one_core_attach(struct ssb_device *dev, + struct b43legacy_wl *wl); +static void b43legacy_one_core_detach(struct ssb_device *dev); + +static void b43legacy_request_firmware(struct work_struct *work) { + struct b43legacy_wl *wl = container_of(work, + struct b43legacy_wl, firmware_load); + struct b43legacy_wldev *dev = wl->current_dev; struct b43legacy_firmware *fw = &dev->fw; const u8 rev = dev->dev->id.revision; const char *filename; @@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) if (err) goto err_load; } + err = ieee80211_register_hw(wl->hw); + if (err) + goto err_one_core_detach; + return; - return 0; +err_one_core_detach: + b43legacy_one_core_detach(dev->dev); + goto error; err_load: b43legacy_print_fw_helptext(dev->wl); @@ -1639,7 +1652,7 @@ err_no_initvals: error: b43legacy_release_firmware(dev); - return err; + return; } static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) @@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) macctl |= B43legacy_MACCTL_INFRA; b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); - err = b43legacy_request_firmware(dev); - if (err) - goto out; err = b43legacy_upload_microcode(dev); if (err) goto out; /* firmware is released later */ @@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev, if (err) goto err_wireless_exit; - if (first) { - err = ieee80211_register_hw(wl->hw); - if (err) - goto err_one_core_detach; - } + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43legacy_request_firmware); + schedule_work(&wl->firmware_load); out: return err; -err_one_core_detach: - b43legacy_one_core_detach(dev); err_wireless_exit: if (first) b43legacy_wireless_exit(dev, wl); @@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev) /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); + cancel_work_sync(&wl->firmware_load); B43legacy_WARN_ON(!wl); if (wl->current_dev == wldev) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 15d7f00513be..d13ae9c299f2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2003,7 +2003,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, s32 err = 0; u16 channel; u32 freq; - u64 notify_timestamp; u16 notify_capability; u16 notify_interval; u8 *notify_ie; @@ -2026,7 +2025,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, freq = ieee80211_channel_to_frequency(channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); - notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ notify_capability = le16_to_cpu(bi->capability); notify_interval = le16_to_cpu(bi->beacon_period); notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); @@ -2040,10 +2038,9 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, WL_CONN("Capability: %X\n", notify_capability); WL_CONN("Beacon interval: %d\n", notify_interval); WL_CONN("Signal: %d\n", notify_signal); - WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, - notify_timestamp, notify_capability, notify_interval, notify_ie, + 0, notify_capability, notify_interval, notify_ie, notify_ielen, notify_signal, GFP_KERNEL); if (!bss) @@ -2098,7 +2095,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, s32 err = 0; u16 channel; u32 freq; - u64 notify_timestamp; u16 notify_capability; u16 notify_interval; u8 *notify_ie; @@ -2134,7 +2130,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, freq = ieee80211_channel_to_frequency(channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); - notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ notify_capability = le16_to_cpu(bi->capability); notify_interval = le16_to_cpu(bi->beacon_period); notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); @@ -2145,10 +2140,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, WL_CONN("capability: %X\n", notify_capability); WL_CONN("beacon interval: %d\n", notify_interval); WL_CONN("signal: %d\n", notify_signal); - WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, - notify_timestamp, notify_capability, notify_interval, + 0, notify_capability, notify_interval, notify_ie, notify_ielen, notify_signal, GFP_KERNEL); if (!bss) { diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index 66e84ec0eb55..570d6fb88967 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -1997,18 +1997,6 @@ struct ipw_cmd_log { #define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ #define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ -/* - * The definitions below were lifted off the ipw2100 driver, which only - * supports 'b' mode, so I'm sure these are not exactly correct. - * - * Somebody fix these!! - */ -#define REG_MIN_CHANNEL 0 -#define REG_MAX_CHANNEL 14 - -#define REG_CHANNEL_MASK 0x00003FFF -#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff - #define IPW_MAX_CONFIG_RETRIES 10 #endif /* __ipw2200_h__ */ diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 0ccc934a35bb..0c1209390169 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -2466,7 +2466,7 @@ il3945_bg_alive_start(struct work_struct *data) container_of(data, struct il_priv, alive_start.work); mutex_lock(&il->mutex); - if (test_bit(S_EXIT_PENDING, &il->status)) + if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) goto out; il3945_alive_start(il); diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 456f32da6b26..c5b1d199e0bc 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -1855,11 +1855,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work) struct il_priv *il = container_of(work, struct il_priv, _3945.thermal_periodic.work); - if (test_bit(S_EXIT_PENDING, &il->status)) - return; - mutex_lock(&il->mutex); + if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) + goto out; + il3945_reg_txpower_periodic(il); +out: mutex_unlock(&il->mutex); } diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index b42052b47d8e..e5ac04739bcc 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -5355,7 +5355,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_ASSOC) { D_MAC80211("ASSOC %d\n", bss_conf->assoc); if (bss_conf->assoc) { - il->timestamp = bss_conf->timestamp; + il->timestamp = bss_conf->last_tsf; if (!il_is_rfkill(il)) il->ops->post_associate(il); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f98baaba0c2a..56f41c9409d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1189,6 +1189,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) memcpy(&rxon, &ctx->active, sizeof(rxon)); + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); priv->wowlan = true; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index cc0227c1f352..44c6f712b77d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -671,7 +671,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->status)); else - wake_up(&priv->shrd->wait_command_queue); + wake_up(&trans(priv)->wait_command_queue); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 36909077f994..2e1a31797a9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -822,7 +822,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, if (changes & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { - priv->timestamp = bss_conf->timestamp; + priv->timestamp = bss_conf->last_tsf; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { /* diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 28422c03d673..f1226dbf789d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -816,6 +816,7 @@ void iwl_down(struct iwl_priv *priv) if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); /* Clear out all status bits but a few that are stable across reset */ @@ -962,8 +963,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) { priv->workqueue = create_singlethread_workqueue(DRV_NAME); - init_waitqueue_head(&priv->shrd->wait_command_queue); - INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); @@ -1186,6 +1185,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, u16 num_mac; u32 ucode_flags; struct iwl_trans_config trans_cfg; + static const u8 no_reclaim_cmds[] = { + REPLY_RX_PHY_CMD, + REPLY_RX, + REPLY_RX_MPDU_CMD, + REPLY_COMPRESSED_BA, + STATISTICS_NOTIFICATION, + REPLY_TX, + }; /************************ * 1. Allocating HW data @@ -1211,6 +1218,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, * to know about. */ trans_cfg.op_mode = op_mode; + trans_cfg.no_reclaim_cmds = no_reclaim_cmds; + trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); ucode_flags = fw->ucode_capa.flags; @@ -1398,6 +1407,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) iwl_tt_exit(priv); /*This will stop the queues, move the device to low power state */ + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); iwl_eeprom_free(priv->shrd); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8b85940731f2..46490d3b95b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -838,6 +838,9 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); #endif + /* uCode is no longer loaded. */ + priv->ucode_loaded = false; + /* Set the FW error flag -- cleared on iwl_down */ set_bit(STATUS_FW_ERROR, &priv->shrd->status); @@ -850,7 +853,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) * commands by clearing the ready bit */ clear_bit(STATUS_READY, &priv->status); - wake_up(&priv->shrd->wait_command_queue); + wake_up(&trans(priv)->wait_command_queue); if (!ondemand) { /* diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 9b71c87847c2..b7b1c04f2fba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -230,15 +230,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, int pos = 0; int sram; struct iwl_priv *priv = file->private_data; + const struct fw_img *img; size_t bufsz; /* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { priv->dbgfs_sram_offset = 0x800000; - if (priv->shrd->ucode_type == IWL_UCODE_INIT) - priv->dbgfs_sram_len = priv->fw->ucode_init.data.len; - else - priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len; + if (!priv->ucode_loaded) { + IWL_ERR(priv, "No uCode has been loadded.\n"); + return -EINVAL; + } + img = &priv->fw->img[priv->shrd->ucode_type]; + priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; } len = priv->dbgfs_sram_len; @@ -335,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; + const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN]; if (!priv->wowlan_sram) return -ENODATA; return simple_read_from_buffer(user_buf, count, ppos, priv->wowlan_sram, - priv->fw->ucode_wowlan.data.len); + img->sec[IWL_UCODE_SECTION_DATA].len); } static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index aa4b3b122da4..16956b777f96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -769,6 +769,8 @@ struct iwl_priv { /* firmware reload counter and timestamp */ unsigned long reload_jiffies; int reload_count; + bool ucode_loaded; + bool init_ucode_run; /* Don't run init uCode again */ /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 29a3ae48df6d..6f312c77af5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -69,6 +69,7 @@ #include "iwl-trans.h" #include "iwl-shared.h" #include "iwl-op-mode.h" +#include "iwl-agn-hw.h" /* private includes */ #include "iwl-fw-file.h" @@ -96,6 +97,16 @@ struct iwl_drv { +/* + * struct fw_sec: Just for the image parsing proccess. + * For the fw storage we are using struct fw_desc. + */ +struct fw_sec { + const void *data; /* the sec data */ + size_t size; /* section size */ + u32 offset; /* offset of writing in the device */ +}; + static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) { if (desc->v_addr) @@ -107,32 +118,34 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) { - iwl_free_fw_desc(drv, &img->code); - iwl_free_fw_desc(drv, &img->data); + int i; + for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) + iwl_free_fw_desc(drv, &img->sec[i]); } static void iwl_dealloc_ucode(struct iwl_drv *drv) { - iwl_free_fw_img(drv, &drv->fw.ucode_rt); - iwl_free_fw_img(drv, &drv->fw.ucode_init); - iwl_free_fw_img(drv, &drv->fw.ucode_wowlan); + int i; + for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) + iwl_free_fw_img(drv, drv->fw.img + i); } static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, - const void *data, size_t len) + struct fw_sec *sec) { - if (!len) { + if (!sec || !sec->size) { desc->v_addr = NULL; return -EINVAL; } - desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len, + desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; - desc->len = len; - memcpy(desc->v_addr, data, len); + desc->len = sec->size; + desc->offset = sec->offset; + memcpy(desc->v_addr, sec->data, sec->size); return 0; } @@ -177,18 +190,123 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) GFP_KERNEL, drv, iwl_ucode_callback); } -struct iwlagn_firmware_pieces { - const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; - size_t inst_size, data_size, init_size, init_data_size, - wowlan_inst_size, wowlan_data_size; +struct fw_img_parsing { + struct fw_sec sec[IWL_UCODE_SECTION_MAX]; + int sec_counter; +}; + +/* + * struct fw_sec_parsing: to extract fw section and it's offset from tlv + */ +struct fw_sec_parsing { + __le32 offset; + const u8 data[]; +} __packed; + +/** + * struct iwl_tlv_calib_data - parse the default calib data from TLV + * + * @ucode_type: the uCode to which the following default calib relates. + * @calib: default calibrations. + */ +struct iwl_tlv_calib_data { + __le32 ucode_type; + __le64 calib; +} __packed; + +struct iwl_firmware_pieces { + struct fw_img_parsing img[IWL_UCODE_TYPE_MAX]; u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; }; +/* + * These functions are just to extract uCode section data from the pieces + * structure. + */ +static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec) +{ + return &pieces->img[type].sec[sec]; +} + +static void set_sec_data(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + const void *data) +{ + pieces->img[type].sec[sec].data = data; +} + +static void set_sec_size(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + size_t size) +{ + pieces->img[type].sec[sec].size = size; +} + +static size_t get_sec_size(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec) +{ + return pieces->img[type].sec[sec].size; +} + +static void set_sec_offset(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + u32 offset) +{ + pieces->img[type].sec[sec].offset = offset; +} + +/* + * Gets uCode section from tlv. + */ +static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces, + const void *data, enum iwl_ucode_type type, + int size) +{ + struct fw_img_parsing *img; + struct fw_sec *sec; + struct fw_sec_parsing *sec_parse; + + if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX)) + return -1; + + sec_parse = (struct fw_sec_parsing *)data; + + img = &pieces->img[type]; + sec = &img->sec[img->sec_counter]; + + sec->offset = le32_to_cpu(sec_parse->offset); + sec->data = sec_parse->data; + + ++img->sec_counter; + + return 0; +} + +static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data) +{ + struct iwl_tlv_calib_data *def_calib = + (struct iwl_tlv_calib_data *)data; + u32 ucode_type = le32_to_cpu(def_calib->ucode_type); + if (ucode_type >= IWL_UCODE_TYPE_MAX) { + IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n", + ucode_type); + return -EINVAL; + } + drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib); + return 0; +} + static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces) + const struct firmware *ucode_raw, + struct iwl_firmware_pieces *pieces) { struct iwl_ucode_header *ucode = (void *)ucode_raw->data; u32 api_ver, hdr_size, build; @@ -206,11 +324,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, return -EINVAL; } build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = - le32_to_cpu(ucode->u.v2.init_data_size); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v2.inst_size)); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v2.data_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v2.init_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v2.init_data_size)); src = ucode->u.v2.data; break; case 0: @@ -222,11 +343,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, return -EINVAL; } build = 0; - pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); - pieces->init_data_size = - le32_to_cpu(ucode->u.v1.init_data_size); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v1.inst_size)); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v1.data_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v1.init_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v1.init_data_size)); src = ucode->u.v1.data; break; } @@ -248,9 +372,12 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, buildstr); /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != hdr_size + pieces->inst_size + - pieces->data_size + pieces->init_size + - pieces->init_data_size) { + + if (ucode_raw->size != hdr_size + + get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) + + get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) + + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) + + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) { IWL_ERR(drv, "uCode file size %d does not match expected size\n", @@ -258,21 +385,29 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, return -EINVAL; } - pieces->inst = src; - src += pieces->inst_size; - pieces->data = src; - src += pieces->data_size; - pieces->init = src; - src += pieces->init_size; - pieces->init_data = src; - src += pieces->init_data_size; + set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, src); + src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST); + set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, src); + src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA); + set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, src); + src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST); + set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, src); + src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA); + set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); return 0; } static int iwl_parse_tlv_firmware(struct iwl_drv *drv, const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces, + struct iwl_firmware_pieces *pieces, struct iwl_ucode_capabilities *capa) { struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; @@ -368,20 +503,40 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, switch (tlv_type) { case IWL_UCODE_TLV_INST: - pieces->inst = tlv_data; - pieces->inst_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); break; case IWL_UCODE_TLV_DATA: - pieces->data = tlv_data; - pieces->data_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); break; case IWL_UCODE_TLV_INIT: - pieces->init = tlv_data; - pieces->init_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); break; case IWL_UCODE_TLV_INIT_DATA: - pieces->init_data = tlv_data; - pieces->init_data_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); break; case IWL_UCODE_TLV_BOOT: IWL_ERR(drv, "Found unexpected BOOT ucode\n"); @@ -455,12 +610,22 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, drv->fw.enhance_sensitivity_table = true; break; case IWL_UCODE_TLV_WOWLAN_INST: - pieces->wowlan_inst = tlv_data; - pieces->wowlan_inst_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); break; case IWL_UCODE_TLV_WOWLAN_DATA: - pieces->wowlan_data = tlv_data; - pieces->wowlan_data_size = tlv_len; + set_sec_data(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); break; case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: if (tlv_len != sizeof(u32)) @@ -468,6 +633,32 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, capa->standard_phy_calibration_size = le32_to_cpup((__le32 *)tlv_data); break; + case IWL_UCODE_TLV_SEC_RT: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, + tlv_len); + drv->fw.mvm_fw = true; + break; + case IWL_UCODE_TLV_SEC_INIT: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT, + tlv_len); + drv->fw.mvm_fw = true; + break; + case IWL_UCODE_TLV_SEC_WOWLAN: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN, + tlv_len); + drv->fw.mvm_fw = true; + break; + case IWL_UCODE_TLV_DEF_CALIB: + if (tlv_len != sizeof(struct iwl_tlv_calib_data)) + goto invalid_tlv_len; + if (iwl_set_default_calib(drv, tlv_data)) + goto tlv_error; + break; + case IWL_UCODE_TLV_PHY_SKU: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); + break; default: IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); break; @@ -484,11 +675,77 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, invalid_tlv_len: IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + tlv_error: iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); return -EINVAL; } +static int alloc_pci_desc(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type) +{ + int i; + for (i = 0; + i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); + i++) + if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), + get_sec(pieces, type, i))) + return -1; + return 0; +} + +static int validate_sec_sizes(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + const struct iwl_cfg *cfg) +{ + IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); + + /* Verify that uCode images will fit in card's SRAM. */ + if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { + IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { + IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { + IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { + IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + return -1; + } + return 0; +} + + /** * iwl_ucode_callback - callback when firmware was loaded * @@ -502,11 +759,12 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) struct iwl_fw *fw = &drv->fw; struct iwl_ucode_header *ucode; int err; - struct iwlagn_firmware_pieces pieces; + struct iwl_firmware_pieces pieces; const unsigned int api_max = cfg->ucode_api_max; unsigned int api_ok = cfg->ucode_api_ok; const unsigned int api_min = cfg->ucode_api_min; u32 api_ver; + int i; fw->ucode_capa.max_probe_length = 200; fw->ucode_capa.standard_phy_calibration_size = @@ -588,76 +846,48 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", drv->fw.ucode_ver); IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", - pieces.inst_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", - pieces.data_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", - pieces.init_size); + get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", - pieces.init_data_size); + get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); /* Verify that uCode images will fit in card's SRAM */ - if (pieces.inst_size > cfg->max_inst_size) { + if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", - pieces.inst_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); goto try_again; } - if (pieces.data_size > cfg->max_data_size) { + if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", - pieces.data_size); + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); goto try_again; } - if (pieces.init_size > cfg->max_inst_size) { - IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", - pieces.init_size); - goto try_again; - } - - if (pieces.init_data_size > cfg->max_data_size) { - IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", - pieces.init_data_size); + /* + * In mvm uCode there is no difference between data and instructions + * sections. + */ + if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg)) goto try_again; - } /* Allocate ucode buffers for card's bus-master loading ... */ /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code, - pieces.inst, pieces.inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data, - pieces.data, pieces.data_size)) - goto err_pci_alloc; - - /* Initialization instructions and data */ - if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_init.code, - pieces.init, pieces.init_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_init.data, - pieces.init_data, pieces.init_data_size)) + for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) + if (alloc_pci_desc(drv, &pieces, i)) goto err_pci_alloc; - } - - /* WoWLAN instructions and data */ - if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_wowlan.code, - pieces.wowlan_inst, - pieces.wowlan_inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(drv, - &drv->fw.ucode_wowlan.data, - pieces.wowlan_data, - pieces.wowlan_data_size)) - goto err_pci_alloc; - } /* Now that we can no longer fail, copy information */ diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 7ca6c9526357..c924ccb93c8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -124,6 +124,11 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_WOWLAN_INST = 16, IWL_UCODE_TLV_WOWLAN_DATA = 17, IWL_UCODE_TLV_FLAGS = 18, + IWL_UCODE_TLV_SEC_RT = 19, + IWL_UCODE_TLV_SEC_INIT = 20, + IWL_UCODE_TLV_SEC_WOWLAN = 21, + IWL_UCODE_TLV_DEF_CALIB = 22, + IWL_UCODE_TLV_PHY_SKU = 23, }; struct iwl_ucode_tlv { diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 453812a21176..8e36bdc1e522 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -85,22 +85,52 @@ enum iwl_ucode_tlv_flag { #define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 +/** + * enum iwl_ucode_type + * + * The type of ucode. + * + * @IWL_UCODE_REGULAR: Normal runtime ucode + * @IWL_UCODE_INIT: Initial ucode + * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode + */ +enum iwl_ucode_type { + IWL_UCODE_REGULAR, + IWL_UCODE_INIT, + IWL_UCODE_WOWLAN, + IWL_UCODE_TYPE_MAX, +}; + +/* + * enumeration of ucode section. + * This enumeration is used for legacy tlv style (before 16.0 uCode). + */ +enum iwl_ucode_sec { + IWL_UCODE_SECTION_INST, + IWL_UCODE_SECTION_DATA, +}; +/* + * For 16.0 uCode and above, there is no differentiation between sections, + * just an offset to the HW address. + */ +#define IWL_UCODE_SECTION_MAX 4 + struct iwl_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; u32 flags; }; -/* one for each uCode image (inst/data, boot/init/runtime) */ +/* one for each uCode image (inst/data, init/runtime/wowlan) */ struct fw_desc { dma_addr_t p_addr; /* hardware address */ void *v_addr; /* software address */ u32 len; /* size in bytes */ + u32 offset; /* offset in the device */ }; struct fw_img { - struct fw_desc code; /* firmware code image */ - struct fw_desc data; /* firmware data image */ + struct fw_desc sec[IWL_UCODE_SECTION_MAX]; }; /* uCode version contains 4 values: Major/Minor/API/Serial */ @@ -114,9 +144,7 @@ struct fw_img { * * @ucode_ver: ucode version from the ucode file * @fw_version: firmware version string - * @ucode_rt: run time ucode image - * @ucode_init: init ucode image - * @ucode_wowlan: wake on wireless ucode image (optional) + * @img: ucode image like ucode_rt, ucode_init, ucode_wowlan. * @ucode_capa: capabilities parsed from the ucode file. * @enhance_sensitivity_table: device can do enhanced sensitivity. * @init_evtlog_ptr: event log offset for init ucode. @@ -132,15 +160,18 @@ struct iwl_fw { char fw_version[ETHTOOL_BUSINFO_LEN]; /* ucode images */ - struct fw_img ucode_rt; - struct fw_img ucode_init; - struct fw_img ucode_wowlan; + struct fw_img img[IWL_UCODE_TYPE_MAX]; struct iwl_ucode_capabilities ucode_capa; bool enhance_sensitivity_table; u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; + + u64 default_calib[IWL_UCODE_TYPE_MAX]; + u32 phy_config; + + bool mvm_fw; }; #endif /* __iwl_fw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 9212ee3bef9b..b6805f8e9a01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; - if (priv->fw->ucode_wowlan.code.len && + if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && trans(priv)->ops->wowlan_suspend && device_can_wakeup(trans(priv)->dev)) { hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | @@ -437,6 +437,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) unsigned long flags; u32 base, status = 0xffffffff; int ret = -EIO; + const struct fw_img *img; IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->mutex); @@ -457,16 +458,18 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) #ifdef CONFIG_IWLWIFI_DEBUGFS if (ret == 0) { - if (!priv->wowlan_sram) + img = &(priv->fw->img[IWL_UCODE_WOWLAN]); + if (!priv->wowlan_sram) { priv->wowlan_sram = - kzalloc(priv->fw->ucode_wowlan.data.len, + kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, GFP_KERNEL); + } if (priv->wowlan_sram) _iwl_read_targ_mem_words( - trans(priv), 0x800000, - priv->wowlan_sram, - priv->fw->ucode_wowlan.data.len / 4); + trans(priv), 0x800000, + priv->wowlan_sram, + img->sec[IWL_UCODE_SECTION_DATA].len / 4); } #endif } diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index cf34087aa2fe..b515d657a0ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -192,23 +192,6 @@ struct iwl_hw_params { const struct iwl_sensitivity_ranges *sens; }; -/** - * enum iwl_ucode_type - * - * The type of ucode currently loaded on the hardware. - * - * @IWL_UCODE_NONE: No ucode loaded - * @IWL_UCODE_REGULAR: Normal runtime ucode - * @IWL_UCODE_INIT: Initial ucode - * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode - */ -enum iwl_ucode_type { - IWL_UCODE_NONE, - IWL_UCODE_REGULAR, - IWL_UCODE_INIT, - IWL_UCODE_WOWLAN, -}; - /* * LED mode * IWL_LED_DEFAULT: use device default @@ -376,7 +359,6 @@ struct iwl_cfg { * @nic: pointer to the nic data * @hw_params: see struct iwl_hw_params * @lock: protect general shared data - * @wait_command_queue: the wait_queue for SYNC host commands * @eeprom: pointer to the eeprom/OTP image * @ucode_type: indicator of loaded ucode image * @device_pointers: pointers to ucode event tables @@ -391,8 +373,6 @@ struct iwl_shared { struct iwl_hw_params hw_params; const struct iwl_fw *fw; - wait_queue_head_t wait_command_queue; - /* eeprom -- this is in the card's little endian byte order */ u8 *eeprom; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index b06c6763cb7a..76f7f9251436 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -466,6 +466,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) unsigned char *rsp_data_ptr = NULL; int status = 0, rsp_data_len = 0; u32 devid, inst_size = 0, data_size = 0; + const struct fw_img *img; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: @@ -494,6 +495,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: iwl_testmode_cfg_init_calib(priv); + priv->ucode_loaded = false; iwl_trans_stop_device(trans); break; @@ -512,6 +514,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: iwl_scan_cancel_timeout(priv, 200); + priv->ucode_loaded = false; iwl_trans_stop_device(trans); status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); if (status) { @@ -591,25 +594,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; } - switch (priv->shrd->ucode_type) { - case IWL_UCODE_REGULAR: - inst_size = priv->fw->ucode_rt.code.len; - data_size = priv->fw->ucode_rt.data.len; - break; - case IWL_UCODE_INIT: - inst_size = priv->fw->ucode_init.code.len; - data_size = priv->fw->ucode_init.data.len; - break; - case IWL_UCODE_WOWLAN: - inst_size = priv->fw->ucode_wowlan.code.len; - data_size = priv->fw->ucode_wowlan.data.len; - break; - case IWL_UCODE_NONE: + if (!priv->ucode_loaded) { IWL_ERR(priv, "No uCode has not been loaded\n"); - break; - default: - IWL_ERR(priv, "Unsupported uCode type\n"); - break; + return -EINVAL; + } else { + img = &priv->fw->img[priv->shrd->ucode_type]; + inst_size = img->sec[IWL_UCODE_SECTION_INST].len; + data_size = img->sec[IWL_UCODE_SECTION_DATA].len; } NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 67965599bb30..1c2fe87bd7e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -291,6 +291,8 @@ struct iwl_trans_pcie { wait_queue_head_t ucode_write_waitq; unsigned long status; u8 cmd_queue; + u8 n_no_reclaim_cmds; + u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 9bc3c73af5e9..8b1a7988e176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -395,13 +395,17 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, * there is no command buffer to reclaim. * Ucode should set SEQ_RX_FRAME bit if ucode-originated, * but apparently a few don't get set; catch them here. */ - reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && - (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && - (pkt->hdr.cmd != REPLY_RX) && - (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && - (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && - (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && - (pkt->hdr.cmd != REPLY_TX); + reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME); + if (reclaim) { + int i; + + for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) { + if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) { + reclaim = false; + break; + } + } + } sequence = le16_to_cpu(pkt->hdr.sequence); index = SEQ_TO_INDEX(sequence); @@ -412,17 +416,6 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, else cmd = NULL; - /* warn if this is cmd response / notification and the uCode - * didn't set the SEQ_RX_FRAME for a frame that is - * uCode-originated - * If you saw this code after the second half of 2012, then - * please remove it - */ - WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && - (!(pkt->hdr.sequence & SEQ_RX_FRAME)), - "reclaim is false, SEQ_RX_FRAME unset: %s\n", - get_cmd_string(pkt->hdr.cmd)); - err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); /* @@ -691,7 +684,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) */ clear_bit(STATUS_READY, &trans->shrd->status); clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); - wake_up(&trans->shrd->wait_command_queue); + wake_up(&trans->wait_command_queue); IWL_ERR(trans, "RF is used by WiMAX\n"); return; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index eb430b6e1cde..e92972fd6ecf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -928,7 +928,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->hdr.cmd)); - wake_up(&trans->shrd->wait_command_queue); + wake_up(&trans->wait_command_queue); } meta->flags = 0; @@ -992,7 +992,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return ret; } - ret = wait_event_timeout(trans->shrd->wait_command_queue, + ret = wait_event_timeout(trans->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), HOST_COMPLETE_TIMEOUT); if (!ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 91628565409f..b4f796c82e1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -951,12 +951,13 @@ static const u8 iwlagn_pan_ac_to_queue[] = { /* * ucode */ -static int iwl_load_section(struct iwl_trans *trans, const char *name, - const struct fw_desc *image, u32 dst_addr) +static int iwl_load_section(struct iwl_trans *trans, u8 section_num, + const struct fw_desc *section) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - dma_addr_t phy_addr = image->p_addr; - u32 byte_cnt = image->len; + dma_addr_t phy_addr = section->p_addr; + u32 byte_cnt = section->len; + u32 dst_addr = section->offset; int ret; trans_pcie->ucode_write_complete = false; @@ -989,12 +990,13 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); + IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", + section_num); ret = wait_event_timeout(trans_pcie->ucode_write_waitq, trans_pcie->ucode_write_complete, 5 * HZ); if (!ret) { - IWL_ERR(trans, "Could not load the %s uCode section\n", - name); + IWL_ERR(trans, "Could not load the [%d] uCode section\n", + section_num); return -ETIMEDOUT; } @@ -1005,16 +1007,16 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, const struct fw_img *image) { int ret = 0; + int i; - ret = iwl_load_section(trans, "INST", &image->code, - IWLAGN_RTC_INST_LOWER_BOUND); - if (ret) - return ret; + for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) { + if (!image->sec[i].p_addr) + break; - ret = iwl_load_section(trans, "DATA", &image->data, - IWLAGN_RTC_DATA_LOWER_BOUND); - if (ret) - return ret; + ret = iwl_load_section(trans, i, &image->sec[i]); + if (ret) + return ret; + } /* Remove all resets to allow NIC to operate */ iwl_write32(trans, CSR_RESET, 0); @@ -1466,8 +1468,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", le16_to_cpu(dev_cmd->hdr.sequence)); IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); - iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); - iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); /* Set up entry for this TFD in Tx byte-count array */ iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); @@ -1628,6 +1628,13 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->cmd_queue = trans_cfg->cmd_queue; + if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) + trans_pcie->n_no_reclaim_cmds = 0; + else + trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds; + if (trans_pcie->n_no_reclaim_cmds) + memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds, + trans_pcie->n_no_reclaim_cmds * sizeof(u8)); } static void iwl_trans_pcie_free(struct iwl_trans *trans) @@ -2322,6 +2329,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); } + /* Initialize the wait queue for commands */ + init_waitqueue_head(&trans->wait_command_queue); + return trans; out_pci_release_regions: diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 7d1990c7f658..0c81cbaa8088 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -274,6 +274,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) return p; } +#define MAX_NO_RECLAIM_CMDS 6 + /** * struct iwl_trans_config - transport configuration * @@ -281,10 +283,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * Must be set before any other call. * @cmd_queue: the index of the command queue. * Must be set before start_fw. + * @no_reclaim_cmds: Some devices erroneously don't set the + * SEQ_RX_FRAME bit on some notifications, this is the + * list of such notifications to filter. Max length is + * %MAX_NO_RECLAIM_CMDS. + * @n_no_reclaim_cmds: # of commands in list */ struct iwl_trans_config { struct iwl_op_mode *op_mode; u8 cmd_queue; + const u8 *no_reclaim_cmds; + int n_no_reclaim_cmds; }; /** @@ -404,6 +413,7 @@ enum iwl_trans_state { * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @nvm_device_type: indicates OTP or eeprom * @pm_support: set to true in start_hw if link pm is supported + * @wait_command_queue: the wait_queue for SYNC host commands */ struct iwl_trans { const struct iwl_trans_ops *ops; @@ -420,6 +430,8 @@ struct iwl_trans { int nvm_device_type; bool pm_support; + wait_queue_head_t wait_command_queue; + /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char trans_specific[0] __aligned(sizeof(void *)); @@ -488,8 +500,8 @@ static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) static inline int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->send_cmd(trans, cmd); } @@ -508,8 +520,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, int tid, int txq_id, int ssn, struct sk_buff_head *skbs) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); } @@ -517,8 +529,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->tx_agg_disable(trans, sta_id, tid); } @@ -526,8 +538,8 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, int sta_id, int tid) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->tx_agg_alloc(trans, sta_id, tid); } @@ -540,8 +552,8 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, { might_sleep(); - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); } @@ -553,16 +565,16 @@ static inline void iwl_trans_free(struct iwl_trans *trans) static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->wait_tx_queue_empty(trans); } static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q) { - if (trans->state != IWL_TRANS_FW_ALIVE) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->check_stuck_queue(trans, q); } diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index d97cf44b75ba..252828728837 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -80,17 +80,10 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { static inline const struct fw_img * iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { - switch (ucode_type) { - case IWL_UCODE_INIT: - return &priv->fw->ucode_init; - case IWL_UCODE_WOWLAN: - return &priv->fw->ucode_wowlan; - case IWL_UCODE_REGULAR: - return &priv->fw->ucode_rt; - case IWL_UCODE_NONE: - break; - } - return NULL; + if (ucode_type >= IWL_UCODE_TYPE_MAX) + return NULL; + + return &priv->fw->img[ucode_type]; } /* @@ -342,7 +335,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_priv *priv, +static int iwl_verify_sec_sparse(struct iwl_priv *priv, const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -357,7 +350,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, - i + IWLAGN_RTC_INST_LOWER_BOUND); + i + fw_desc->offset); val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) return -EIO; @@ -366,7 +359,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, return 0; } -static void iwl_print_mismatch_inst(struct iwl_priv *priv, +static void iwl_print_mismatch_sec(struct iwl_priv *priv, const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -378,7 +371,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, - IWLAGN_RTC_INST_LOWER_BOUND); + fw_desc->offset); for (offs = 0; offs < len && errors < 20; @@ -408,14 +401,14 @@ static int iwl_verify_ucode(struct iwl_priv *priv, return -EINVAL; } - if (!iwl_verify_inst_sparse(priv, &img->code)) { + if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); return 0; } IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); - iwl_print_mismatch_inst(priv, &img->code); + iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); return -EIO; } @@ -465,6 +458,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, priv->shrd->ucode_type = ucode_type; fw = iwl_get_ucode_image(priv, ucode_type); + priv->ucode_loaded = false; + if (!fw) return -EINVAL; @@ -519,6 +514,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return ret; } + priv->ucode_loaded = true; + return 0; } @@ -530,10 +527,10 @@ int iwl_run_init_ucode(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); /* No init ucode required? Curious, but maybe ok */ - if (!priv->fw->ucode_init.code.len) + if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) return 0; - if (priv->shrd->ucode_type != IWL_UCODE_NONE) + if (priv->init_ucode_run) return 0; iwl_init_notification_wait(&priv->notif_wait, &calib_wait, @@ -555,6 +552,8 @@ int iwl_run_init_ucode(struct iwl_priv *priv) */ ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, UCODE_CALIB_TIMEOUT); + if (!ret) + priv->init_ucode_run = true; goto out; @@ -563,5 +562,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) out: /* Whatever happened, stop the device */ iwl_trans_stop_device(trans(priv)); + priv->ucode_loaded = false; + return ret; } diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index a7cd311cb1b7..3fa1ecebadfd 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1631,42 +1631,6 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, /* - * "Site survey", here just current channel and noise level - */ - -static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, - int idx, struct survey_info *survey) -{ - struct lbs_private *priv = wiphy_priv(wiphy); - s8 signal, noise; - int ret; - - if (dev == priv->mesh_dev) - return -EOPNOTSUPP; - - if (idx != 0) - ret = -ENOENT; - - lbs_deb_enter(LBS_DEB_CFG80211); - - survey->channel = ieee80211_get_channel(wiphy, - ieee80211_channel_to_frequency(priv->channel, - IEEE80211_BAND_2GHZ)); - - ret = lbs_get_rssi(priv, &signal, &noise); - if (ret == 0) { - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = noise; - } - - lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); - return ret; -} - - - - -/* * Change interface */ @@ -2068,7 +2032,6 @@ static struct cfg80211_ops lbs_cfg80211_ops = { .del_key = lbs_cfg_del_key, .set_default_key = lbs_cfg_set_default_key, .get_station = lbs_cfg_get_station, - .dump_survey = lbs_get_survey, .change_virtual_intf = lbs_change_intf, .join_ibss = lbs_join_ibss, .leave_ibss = lbs_leave_ibss, diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index b4f6cb3298a4..b7ce6a6e355f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -639,7 +639,6 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, } memset(&rx_status, 0, sizeof(rx_status)); - rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data)); rx_status.flag |= RX_FLAG_MACTIME_MPDU; rx_status.freq = data->channel->center_freq; rx_status.band = data->channel->band; @@ -684,6 +683,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, if (mac80211_hwsim_addr_match(data2, hdr->addr1)) ack = true; + rx_status.mactime = + le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(data2->hw, nskb); } diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 34bba5234294..a5e182b5e944 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -44,16 +44,16 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, ht_cap->ht_cap.ampdu_params_info = (sband->ht_cap.ampdu_factor & - IEEE80211_HT_AMPDU_PARM_FACTOR)| + IEEE80211_HT_AMPDU_PARM_FACTOR) | ((sband->ht_cap.ampdu_density << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & IEEE80211_HT_AMPDU_PARM_DENSITY); memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, - sizeof(sband->ht_cap.mcs)); + sizeof(sband->ht_cap.mcs)); if (priv->bss_mode == NL80211_IFTYPE_STATION || - (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); @@ -69,8 +69,8 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, * table which matches the requested BA status. */ static struct mwifiex_tx_ba_stream_tbl * -mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv, - enum mwifiex_ba_status ba_status) +mwifiex_get_ba_status(struct mwifiex_private *priv, + enum mwifiex_ba_status ba_status) { struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; unsigned long flags; @@ -107,12 +107,11 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, tid = del_ba_param_set >> DELBA_TID_POS; if (del_ba->del_result == BA_RESULT_SUCCESS) { - mwifiex_11n_delete_ba_stream_tbl(priv, tid, - del_ba->peer_mac_addr, TYPE_DELBA_SENT, - INITIATOR_BIT(del_ba_param_set)); + mwifiex_del_ba_tbl(priv, tid, del_ba->peer_mac_addr, + TYPE_DELBA_SENT, + INITIATOR_BIT(del_ba_param_set)); - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, - BA_STREAM_SETUP_INPROGRESS); + tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); if (tx_ba_tbl) mwifiex_send_addba(priv, tx_ba_tbl->tid, tx_ba_tbl->ra); @@ -120,18 +119,17 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, * In case of failure, recreate the deleted stream in case * we initiated the ADDBA */ - if (INITIATOR_BIT(del_ba_param_set)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - del_ba->peer_mac_addr, tid, - BA_STREAM_SETUP_INPROGRESS); - - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, - BA_STREAM_SETUP_INPROGRESS); - if (tx_ba_tbl) - mwifiex_11n_delete_ba_stream_tbl(priv, - tx_ba_tbl->tid, tx_ba_tbl->ra, - TYPE_DELBA_SENT, true); - } + if (!INITIATOR_BIT(del_ba_param_set)) + return 0; + + mwifiex_create_ba_tbl(priv, del_ba->peer_mac_addr, tid, + BA_SETUP_INPROGRESS); + + tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); + + if (tx_ba_tbl) + mwifiex_del_ba_tbl(priv, tx_ba_tbl->tid, tx_ba_tbl->ra, + TYPE_DELBA_SENT, true); } return 0; @@ -160,18 +158,17 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, & IEEE80211_ADDBA_PARAM_TID_MASK) >> BLOCKACKPARAM_TID_POS; if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, + tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr); if (tx_ba_tbl) { dev_dbg(priv->adapter->dev, "info: BA stream complete\n"); - tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE; + tx_ba_tbl->ba_status = BA_SETUP_COMPLETE; } else { dev_err(priv->adapter->dev, "BA stream not created\n"); } } else { - mwifiex_11n_delete_ba_stream_tbl(priv, tid, - add_ba_rsp->peer_mac_addr, - TYPE_DELBA_SENT, true); + mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr, + TYPE_DELBA_SENT, true); if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) priv->aggr_prio_tbl[tid].ampdu_ap = BA_STREAM_NOT_ALLOWED; @@ -392,9 +389,9 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, chan_list->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) - && (bss_desc->bcn_ht_info->ht_param & - IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) + if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && + bss_desc->bcn_ht_info->ht_param & + IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. radio_type, (bss_desc->bcn_ht_info->ht_param & @@ -467,7 +464,7 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu); dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n", - max_amsdu, priv->adapter->max_tx_buf_size); + max_amsdu, priv->adapter->max_tx_buf_size); if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K) curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; @@ -507,7 +504,7 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl) { if (!tx_ba_tsr_tbl && - mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) + mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) return; dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl); @@ -544,16 +541,15 @@ void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv) * table which matches the given RA/TID pair. */ struct mwifiex_tx_ba_stream_tbl * -mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, - int tid, u8 *ra) +mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra) { struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; unsigned long flags; spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { - if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN)) - && (tx_ba_tsr_tbl->tid == tid)) { + if (!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN) && + tx_ba_tsr_tbl->tid == tid) { spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); return tx_ba_tsr_tbl; @@ -567,14 +563,13 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, * This function creates an entry in Tx BA stream table for the * given RA/TID pair. */ -void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, - u8 *ra, int tid, - enum mwifiex_ba_status ba_status) +void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, + enum mwifiex_ba_status ba_status) { struct mwifiex_tx_ba_stream_tbl *new_node; unsigned long flags; - if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) { + if (!mwifiex_get_ba_tbl(priv, tid, ra)) { new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), GFP_ATOMIC); if (!new_node) { @@ -668,9 +663,8 @@ void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba) tid = del_ba_param_set >> DELBA_TID_POS; - mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr, - TYPE_DELBA_RECEIVE, - INITIATOR_BIT(del_ba_param_set)); + mwifiex_del_ba_tbl(priv, tid, cmd_del_ba->peer_mac_addr, + TYPE_DELBA_RECEIVE, INITIATOR_BIT(del_ba_param_set)); } /* @@ -724,7 +718,7 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid; dev_dbg(priv->adapter->dev, "data: %s tid=%d\n", - __func__, rx_reo_tbl->tid); + __func__, rx_reo_tbl->tid); memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN); rx_reo_tbl++; count++; diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 90b421e343d4..77646d777dce 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -46,13 +46,12 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, struct mwifiex_tx_ba_stream_tbl *tx_tbl); void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv); -struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct +struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra); -void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra, - int tid, - enum mwifiex_ba_status ba_status); +void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, + enum mwifiex_ba_status ba_status); int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac); int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, int initiator); @@ -87,9 +86,8 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) static inline u8 mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) { - return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) - && ((priv->is_data_rate_auto) - || !((priv->bitmap_rates[2]) & 0x03))) + return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) && + (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03))) ? true : false); } @@ -150,11 +148,11 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, */ static inline int mwifiex_is_ba_stream_setup(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int tid) + struct mwifiex_ra_list_tbl *ptr, int tid) { struct mwifiex_tx_ba_stream_tbl *tx_tbl; - tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra); + tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra); if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl)) return true; diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index ea6832dc6677..9eefb2a0ce9f 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -84,7 +84,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, /* Add payload */ skb_put(skb_aggr, skb_src->len); memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data, - skb_src->len); + skb_src->len); *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len + LLC_SNAP_LEN)) & 3)) : 0; skb_put(skb_aggr, *pad); @@ -119,14 +119,14 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - - sizeof(*local_tx_pd)); + sizeof(*local_tx_pd)); if (local_tx_pd->tx_control == 0) /* TxCtrl set by user or default */ local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); - if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (priv->adapter->pps_uapsd_mode)) { + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && + priv->adapter->pps_uapsd_mode) { if (true == mwifiex_check_last_packet_indication(priv)) { priv->adapter->tx_lock_flag = true; local_tx_pd->flags = @@ -257,9 +257,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, mwifiex_write_data_complete(adapter, skb_aggr, -1); return -1; } - if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (adapter->pps_uapsd_mode) && - (adapter->tx_lock_flag)) { + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && + adapter->pps_uapsd_mode && adapter->tx_lock_flag) { priv->adapter->tx_lock_flag = false; if (ptx_pd) ptx_pd->flags = 0; @@ -279,7 +278,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, case -1: adapter->data_sent = false; dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", - __func__, ret); + __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb_aggr, ret); return 0; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 681d3f2a4c28..9c44088054dd 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -27,31 +27,31 @@ #include "11n_rxreorder.h" /* - * This function dispatches all packets in the Rx reorder table. + * This function dispatches all packets in the Rx reorder table until the + * start window. * * There could be holes in the buffer, which are skipped by the function. * Since the buffer is linear, the function uses rotation to simulate * circular buffer. */ static void -mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl - *rx_reor_tbl_ptr, int start_win) +mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl *tbl, int start_win) { - int no_pkt_to_send, i; + int pkt_to_send, i; void *rx_tmp_ptr; unsigned long flags; - no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ? - min((start_win - rx_reor_tbl_ptr->start_win), - rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size; + pkt_to_send = (start_win > tbl->start_win) ? + min((start_win - tbl->start_win), tbl->win_size) : + tbl->win_size; - for (i = 0; i < no_pkt_to_send; ++i) { + for (i = 0; i < pkt_to_send; ++i) { spin_lock_irqsave(&priv->rx_pkt_lock, flags); rx_tmp_ptr = NULL; - if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) { - rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; - rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + if (tbl->rx_reorder_ptr[i]) { + rx_tmp_ptr = tbl->rx_reorder_ptr[i]; + tbl->rx_reorder_ptr[i] = NULL; } spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); if (rx_tmp_ptr) @@ -63,13 +63,12 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, * We don't have a circular buffer, hence use rotation to simulate * circular buffer */ - for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) { - rx_reor_tbl_ptr->rx_reorder_ptr[i] = - rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; - rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; + for (i = 0; i < tbl->win_size - pkt_to_send; ++i) { + tbl->rx_reorder_ptr[i] = tbl->rx_reorder_ptr[pkt_to_send + i]; + tbl->rx_reorder_ptr[pkt_to_send + i] = NULL; } - rx_reor_tbl_ptr->start_win = start_win; + tbl->start_win = start_win; spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); } @@ -83,20 +82,20 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, */ static void mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) + struct mwifiex_rx_reorder_tbl *tbl) { int i, j, xchg; void *rx_tmp_ptr; unsigned long flags; - for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) { + for (i = 0; i < tbl->win_size; ++i) { spin_lock_irqsave(&priv->rx_pkt_lock, flags); - if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) { + if (!tbl->rx_reorder_ptr[i]) { spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); break; } - rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; - rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + rx_tmp_ptr = tbl->rx_reorder_ptr[i]; + tbl->rx_reorder_ptr[i] = NULL; spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); } @@ -107,15 +106,13 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, * circular buffer */ if (i > 0) { - xchg = rx_reor_tbl_ptr->win_size - i; + xchg = tbl->win_size - i; for (j = 0; j < xchg; ++j) { - rx_reor_tbl_ptr->rx_reorder_ptr[j] = - rx_reor_tbl_ptr->rx_reorder_ptr[i + j]; - rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL; + tbl->rx_reorder_ptr[j] = tbl->rx_reorder_ptr[i + j]; + tbl->rx_reorder_ptr[i + j] = NULL; } } - rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) - &(MAX_TID_VALUE - 1); + tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1); spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); } @@ -126,28 +123,25 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, * pending packets in the Rx reorder table before deletion. */ static void -mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl - *rx_reor_tbl_ptr) +mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl *tbl) { unsigned long flags; - if (!rx_reor_tbl_ptr) + if (!tbl) return; - mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, - (rx_reor_tbl_ptr->start_win + - rx_reor_tbl_ptr->win_size) - &(MAX_TID_VALUE - 1)); + mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) & + (MAX_TID_VALUE - 1)); - del_timer(&rx_reor_tbl_ptr->timer_context.timer); + del_timer(&tbl->timer_context.timer); spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); - list_del(&rx_reor_tbl_ptr->list); + list_del(&tbl->list); spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - kfree(rx_reor_tbl_ptr->rx_reorder_ptr); - kfree(rx_reor_tbl_ptr); + kfree(tbl->rx_reorder_ptr); + kfree(tbl); } /* @@ -157,16 +151,15 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, static struct mwifiex_rx_reorder_tbl * mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; unsigned long flags; spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); - list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) { - if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN)) - && (rx_reor_tbl_ptr->tid == tid)) { + list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) { + if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) { spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - return rx_reor_tbl_ptr; + return tbl; } } spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); @@ -200,19 +193,19 @@ mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr) static void mwifiex_flush_data(unsigned long context) { - struct reorder_tmr_cnxt *reorder_cnxt = + struct reorder_tmr_cnxt *ctx = (struct reorder_tmr_cnxt *) context; int start_win; - start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr); - if (start_win >= 0) { - dev_dbg(reorder_cnxt->priv->adapter->dev, - "info: flush data %d\n", start_win); - mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv, - reorder_cnxt->ptr, - ((reorder_cnxt->ptr->start_win + - start_win + 1) & (MAX_TID_VALUE - 1))); - } + start_win = mwifiex_11n_find_last_seq_num(ctx->ptr); + + if (start_win < 0) + return; + + dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", start_win); + mwifiex_11n_dispatch_pkt(ctx->priv, ctx->ptr, + (ctx->ptr->start_win + start_win + 1) & + (MAX_TID_VALUE - 1)); } /* @@ -227,10 +220,10 @@ mwifiex_flush_data(unsigned long context) */ static void mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, - int tid, int win_size, int seq_num) + int tid, int win_size, int seq_num) { int i; - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node; + struct mwifiex_rx_reorder_tbl *tbl, *new_node; u16 last_seq = 0; unsigned long flags; @@ -238,17 +231,16 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, * If we get a TID, ta pair which is already present dispatch all the * the packets and move the window size until the ssn */ - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); - if (rx_reor_tbl_ptr) { - mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, - seq_num); + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); + if (tbl) { + mwifiex_11n_dispatch_pkt(priv, tbl, seq_num); return; } - /* if !rx_reor_tbl_ptr then create one */ + /* if !tbl then create one */ new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); if (!new_node) { dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n", - __func__); + __func__); return; } @@ -360,7 +352,8 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set); mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr, - tid, win_size, le16_to_cpu(cmd_addba_req->ssn)); + tid, win_size, + le16_to_cpu(cmd_addba_req->ssn)); return 0; } @@ -401,35 +394,34 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, u16 seq_num, u16 tid, u8 *ta, u8 pkt_type, void *payload) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; int start_win, end_win, win_size; u16 pkt_index; - rx_reor_tbl_ptr = - mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, - tid, ta); - if (!rx_reor_tbl_ptr) { + tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, + tid, ta); + if (!tbl) { if (pkt_type != PKT_TYPE_BAR) mwifiex_process_rx_packet(priv->adapter, payload); return 0; } - start_win = rx_reor_tbl_ptr->start_win; - win_size = rx_reor_tbl_ptr->win_size; + start_win = tbl->start_win; + win_size = tbl->win_size; end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); - del_timer(&rx_reor_tbl_ptr->timer_context.timer); - mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies - + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); + del_timer(&tbl->timer_context.timer); + mod_timer(&tbl->timer_context.timer, + jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); /* * If seq_num is less then starting win then ignore and drop the * packet */ if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ - if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1)) - && (seq_num < start_win)) + if (seq_num >= ((start_win + TWOPOW11) & + (MAX_TID_VALUE - 1)) && (seq_num < start_win)) return -1; - } else if ((seq_num < start_win) - || (seq_num > (start_win + (TWOPOW11)))) { + } else if ((seq_num < start_win) || + (seq_num > (start_win + TWOPOW11))) { return -1; } @@ -440,17 +432,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, if (pkt_type == PKT_TYPE_BAR) seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); - if (((end_win < start_win) - && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) - && (seq_num > end_win)) || ((end_win > start_win) - && ((seq_num > end_win) || (seq_num < start_win)))) { + if (((end_win < start_win) && + (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) && + (seq_num > end_win)) || + ((end_win > start_win) && ((seq_num > end_win) || + (seq_num < start_win)))) { end_win = seq_num; if (((seq_num - win_size) + 1) >= 0) start_win = (end_win - win_size) + 1; else start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; - mwifiex_11n_dispatch_pkt_until_start_win(priv, - rx_reor_tbl_ptr, start_win); + mwifiex_11n_dispatch_pkt(priv, tbl, start_win); } if (pkt_type != PKT_TYPE_BAR) { @@ -459,17 +451,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, else pkt_index = (seq_num+MAX_TID_VALUE) - start_win; - if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index]) + if (tbl->rx_reorder_ptr[pkt_index]) return -1; - rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload; + tbl->rx_reorder_ptr[pkt_index] = payload; } /* * Dispatch all packets sequentially from start_win until a * hole is found and adjust the start_win appropriately */ - mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); + mwifiex_11n_scan_and_dispatch(priv, tbl); return 0; } @@ -480,10 +472,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, * The TID/TA are taken from del BA event body. */ void -mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, - u8 *peer_mac, u8 type, int initiator) +mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, + u8 type, int initiator) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; struct mwifiex_tx_ba_stream_tbl *ptx_tbl; u8 cleanup_rx_reorder_tbl; unsigned long flags; @@ -493,23 +485,23 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, else cleanup_rx_reorder_tbl = (initiator) ? false : true; - dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, " - "initiator=%d\n", peer_mac, tid, initiator); + dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d initiator=%d\n", + peer_mac, tid, initiator); if (cleanup_rx_reorder_tbl) { - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, peer_mac); - if (!rx_reor_tbl_ptr) { + if (!tbl) { dev_dbg(priv->adapter->dev, - "event: TID, TA not found in table\n"); + "event: TID, TA not found in table\n"); return; } - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr); + mwifiex_del_rx_reorder_entry(priv, tbl); } else { - ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac); + ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac); if (!ptx_tbl) { dev_dbg(priv->adapter->dev, - "event: TID, RA not found in table\n"); + "event: TID, RA not found in table\n"); return; } @@ -532,7 +524,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp; int tid, win_size; - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; uint16_t block_ack_param_set; block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); @@ -548,19 +540,18 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> BLOCKACKPARAM_WINSIZE_POS; - dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM" - " tid=%d ssn=%d win_size=%d\n", - add_ba_rsp->peer_mac_addr, - tid, add_ba_rsp->ssn, win_size); + dev_dbg(priv->adapter->dev, + "cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n", + add_ba_rsp->peer_mac_addr, tid, + add_ba_rsp->ssn, win_size); } else { dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", - add_ba_rsp->peer_mac_addr, tid); + add_ba_rsp->peer_mac_addr, tid); - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, - tid, add_ba_rsp->peer_mac_addr); - if (rx_reor_tbl_ptr) - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, - rx_reor_tbl_ptr); + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, + add_ba_rsp->peer_mac_addr); + if (tbl) + mwifiex_del_rx_reorder_entry(priv, tbl); } return 0; @@ -599,7 +590,7 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) list_for_each_entry_safe(del_tbl_ptr, tmp_node, &priv->rx_reorder_tbl_ptr, list) { spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr); + mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr); spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); } spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 033c8adbdcd4..f1bffebabc60 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -41,9 +41,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, u8 pkttype, void *payload); -void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid, - u8 *PeerMACAddr, u8 type, - int initiator); +void mwifiex_del_ba_tbl(struct mwifiex_private *priv, int Tid, + u8 *PeerMACAddr, u8 type, int initiator); void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, struct host_cmd_ds_11n_batimeout *event); int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 84508b065265..65050384c42b 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -127,8 +127,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, if (timeout) wiphy_dbg(wiphy, - "info: ignoring the timeout value" - " for IEEE power save\n"); + "info: ignore timeout value for IEEE Power Save\n"); ps_mode = enabled; @@ -168,7 +167,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, params->key, params->key_len, - key_index, 0)) { + key_index, 0)) { wiphy_err(wiphy, "crypto keys added\n"); return -EFAULT; } @@ -225,7 +224,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) } if (ch->hw_value == next_chan + 1 && - ch->max_power == max_pwr) { + ch->max_power == max_pwr) { next_chan++; no_of_parsed_chan++; } else { @@ -252,7 +251,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) domain_info->no_of_triplet = no_of_triplet; if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, - HostCmd_ACT_GEN_SET, 0, NULL)) { + HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(wiphy, "11D: setting domain info in FW\n"); return -1; } @@ -271,7 +270,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) * - Set bt Country IE */ static int mwifiex_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) + struct regulatory_request *request) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); @@ -316,7 +315,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, if (chan->band == IEEE80211_BAND_2GHZ) { if (channel_type == NL80211_CHAN_NO_HT) if (priv->adapter->config_bands == BAND_B || - priv->adapter->config_bands == BAND_G) + priv->adapter->config_bands == BAND_G) config_bands = priv->adapter->config_bands; else @@ -336,7 +335,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { adapter->adhoc_start_band = config_bands; if ((config_bands & BAND_GN) || - (config_bands & BAND_AN)) + (config_bands & BAND_AN)) adapter->adhoc_11n_enabled = true; else adapter->adhoc_11n_enabled = false; @@ -350,9 +349,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, mwifiex_send_domain_info_cmd_fw(wiphy); } - wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " - "mode %d\n", config_bands, adapter->sec_chan_offset, - priv->bss_mode); + wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n", + config_bands, adapter->sec_chan_offset, priv->bss_mode); if (!chan) return 0; @@ -403,8 +401,8 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) { int ret; - if (frag_thr < MWIFIEX_FRAG_MIN_VALUE - || frag_thr > MWIFIEX_FRAG_MAX_VALUE) + if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || + frag_thr > MWIFIEX_FRAG_MAX_VALUE) return -EINVAL; /* Send request to firmware */ @@ -746,8 +744,7 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, adapter->channel_type = NL80211_CHAN_NO_HT; wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", - (mode & BAND_B) ? "b" : "", - (mode & BAND_G) ? "g" : ""); + (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : ""); return 0; } @@ -802,8 +799,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) ie_buf[1] = bss_info.ssid.ssid_len; memcpy(&ie_buf[sizeof(struct ieee_types_header)], - &bss_info.ssid.ssid, - bss_info.ssid.ssid_len); + &bss_info.ssid.ssid, bss_info.ssid.ssid_len); ie_len = ie_buf[1] + sizeof(struct ieee_types_header); band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); @@ -812,8 +808,8 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) band)); bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, - bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, - 0, ie_buf, ie_len, 0, GFP_KERNEL); + bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, + 0, ie_buf, ie_len, 0, GFP_KERNEL); cfg80211_put_bss(bss); memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); @@ -952,14 +948,15 @@ done: if (!bss) { if (is_scanning_required) { - dev_warn(priv->adapter->dev, "assoc: requested " - "bss not found in scan results\n"); + dev_warn(priv->adapter->dev, + "assoc: requested bss not found in scan results\n"); break; } is_scanning_required = 1; } else { - dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n", - (char *) req_ssid.ssid, bss->bssid); + dev_dbg(priv->adapter->dev, + "info: trying to associate to '%s' bssid %pM\n", + (char *) req_ssid.ssid, bss->bssid); memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN); break; } @@ -999,7 +996,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", - (char *) sme->ssid, sme->bssid); + (char *) sme->ssid, sme->bssid); ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, priv->bss_mode, sme->channel, sme, 0); @@ -1041,11 +1038,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, } wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", - (char *) params->ssid, params->bssid); + (char *) params->ssid, params->bssid); ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, - params->bssid, priv->bss_mode, - params->channel, NULL, params->privacy); + params->bssid, priv->bss_mode, + params->channel, NULL, params->privacy); done: if (!ret) { cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); @@ -1072,7 +1069,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", - priv->cfg_bssid); + priv->cfg_bssid); if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT; @@ -1101,7 +1098,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, priv->scan_request = request; priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), - GFP_KERNEL); + GFP_KERNEL); if (!priv->user_scan_cfg) { dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); return -ENOMEM; @@ -1117,10 +1114,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) priv->user_scan_cfg->chan_list[i].scan_type = - MWIFIEX_SCAN_TYPE_PASSIVE; + MWIFIEX_SCAN_TYPE_PASSIVE; else priv->user_scan_cfg->chan_list[i].scan_type = - MWIFIEX_SCAN_TYPE_ACTIVE; + MWIFIEX_SCAN_TYPE_ACTIVE; priv->user_scan_cfg->chan_list[i].scan_time = 0; } @@ -1191,9 +1188,9 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, memset(mcs, 0xff, rx_mcs_supp); /* Clear all the other values */ memset(&mcs[rx_mcs_supp], 0, - sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); + sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); if (priv->bss_mode == NL80211_IFTYPE_STATION || - ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) + ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(mcs_set.rx_mask); @@ -1206,10 +1203,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, * create a new virtual interface with the given name */ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, - char *name, - enum nl80211_iftype type, - u32 *flags, - struct vif_params *params) + char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_adapter *adapter; @@ -1367,11 +1364,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) int ret; void *wdev_priv; struct wireless_dev *wdev; + struct ieee80211_sta_ht_cap *ht_info; wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) { dev_err(priv->adapter->dev, "%s: allocating wireless device\n", - __func__); + __func__); return -ENOMEM; } wdev->wiphy = @@ -1383,17 +1381,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) } wdev->iftype = NL80211_IFTYPE_STATION; wdev->wiphy->max_scan_ssids = 10; - wdev->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; - mwifiex_setup_ht_caps( - &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); if (priv->adapter->config_bands & BAND_A) { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; - mwifiex_setup_ht_caps( - &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); } else { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; } @@ -1420,13 +1418,13 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) ret = wiphy_register(wdev->wiphy); if (ret < 0) { dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", - __func__); + __func__); wiphy_free(wdev->wiphy); kfree(wdev); return ret; } else { dev_dbg(priv->adapter->dev, - "info: successfully registered wiphy device\n"); + "info: successfully registered wiphy device\n"); } priv->wdev = wdev; diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 1782a77f15dc..2fe1c33765b8 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -163,65 +163,24 @@ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) return mwifiex_get_supported_rates(priv, rates); else return mwifiex_copy_rates(rates, 0, - priv->curr_bss_params.data_rates, - priv->curr_bss_params.num_of_rates); + priv->curr_bss_params.data_rates, + priv->curr_bss_params.num_of_rates); } /* * This function locates the Channel-Frequency-Power triplet based upon - * band and channel parameters. + * band and channel/frequency parameters. */ struct mwifiex_chan_freq_power * -mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private - *priv, u8 band, u16 channel) +mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq) { struct mwifiex_chan_freq_power *cfp = NULL; struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; + struct ieee80211_channel *ch = NULL; int i; - if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) - sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; - else - sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; - - if (!sband) { - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & channel %d\n", __func__, band, channel); + if (!channel && !freq) return cfp; - } - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - if (((ch->hw_value == channel) || - (channel == FIRST_VALID_CHANNEL)) - && !(ch->flags & IEEE80211_CHAN_DISABLED)) { - priv->cfp.channel = channel; - priv->cfp.freq = ch->center_freq; - priv->cfp.max_tx_power = ch->max_power; - cfp = &priv->cfp; - break; - } - } - if (i == sband->n_channels) - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & channel %d\n", __func__, band, channel); - - return cfp; -} - -/* - * This function locates the Channel-Frequency-Power triplet based upon - * band and frequency parameters. - */ -struct mwifiex_chan_freq_power * -mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, - u8 band, u32 freq) -{ - struct mwifiex_chan_freq_power *cfp = NULL; - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - int i; if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; @@ -229,25 +188,40 @@ mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; if (!sband) { - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & freq %d\n", __func__, band, freq); + dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n", + __func__, band); return cfp; } for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; - if ((ch->center_freq == freq) && - !(ch->flags & IEEE80211_CHAN_DISABLED)) { - priv->cfp.channel = ch->hw_value; - priv->cfp.freq = freq; - priv->cfp.max_tx_power = ch->max_power; - cfp = &priv->cfp; - break; + + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (freq) { + if (ch->center_freq == freq) + break; + } else { + /* find by valid channel*/ + if (ch->hw_value == channel || + channel == FIRST_VALID_CHANNEL) + break; } } - if (i == sband->n_channels) + if (i == sband->n_channels) { dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & freq %d\n", __func__, band, freq); + " & channel=%d freq=%d\n", __func__, band, channel, + freq); + } else { + if (!ch) + return cfp; + + priv->cfp.channel = ch->hw_value; + priv->cfp.freq = ch->center_freq; + priv->cfp.max_tx_power = ch->max_power; + cfp = &priv->cfp; + } return cfp; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c82eb7ff2fa2..07f6e0092552 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -67,7 +67,7 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter) return NULL; } cmd_node = list_first_entry(&adapter->cmd_free_q, - struct cmd_ctrl_node, list); + struct cmd_ctrl_node, list); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); @@ -158,8 +158,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, /* Set command sequence number */ adapter->seq_num++; host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO - (adapter->seq_num, cmd_node->priv->bss_num, - cmd_node->priv->bss_type)); + (adapter->seq_num, + cmd_node->priv->bss_num, + cmd_node->priv->bss_type)); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = cmd_node; @@ -174,8 +175,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," " seqno %#x\n", tstamp.tv_sec, tstamp.tv_usec, cmd_code, - le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, - le16_to_cpu(host_cmd->seq_num)); + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, + le16_to_cpu(host_cmd->seq_num)); skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); @@ -200,17 +201,17 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, /* Save the last command id and action to debug log */ adapter->dbg.last_cmd_index = - (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code; adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] = - le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); /* Clear BSS_NO_BITS from HostCmd */ cmd_code &= HostCmd_CMD_ID_MASK; /* Setup the timer after transmit command */ mod_timer(&adapter->cmd_timer, - jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); + jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); return 0; } @@ -230,7 +231,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) struct mwifiex_private *priv; struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) - adapter->sleep_cfm->data; + adapter->sleep_cfm->data; priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); sleep_cfm_buf->seq_num = @@ -250,7 +251,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) return -1; } if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) - == MWIFIEX_BSS_ROLE_STA) { + == MWIFIEX_BSS_ROLE_STA) { if (!sleep_cfm_buf->resp_ctrl) /* Response is not needed for sleep confirm command */ @@ -258,12 +259,12 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) else adapter->ps_state = PS_STATE_SLEEP_CFM; - if (!sleep_cfm_buf->resp_ctrl - && (adapter->is_hs_configured - && !adapter->sleep_period.period)) { + if (!sleep_cfm_buf->resp_ctrl && + (adapter->is_hs_configured && + !adapter->sleep_period.period)) { adapter->pm_wakeup_card_req = true; - mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_STA), true); + mwifiex_hs_activated_event(mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_STA), true); } } @@ -293,7 +294,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter) cmd_array = kzalloc(buf_size, GFP_KERNEL); if (!cmd_array) { dev_err(adapter->dev, "%s: failed to alloc cmd_array\n", - __func__); + __func__); return -ENOMEM; } @@ -376,9 +377,9 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) /* Save the last event to debug log */ adapter->dbg.last_event_index = - (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; adapter->dbg.last_event[adapter->dbg.last_event_index] = - (u16) eventcause; + (u16) eventcause; /* Get BSS number and corresponding priv */ priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause), @@ -398,7 +399,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { do_gettimeofday(&tstamp); dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", - tstamp.tv_sec, tstamp.tv_usec, eventcause); + tstamp.tv_sec, tstamp.tv_usec, eventcause); } ret = mwifiex_process_sta_event(priv); @@ -509,7 +510,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, /* Return error, since the command preparation failed */ if (ret) { dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n", - cmd_no); + cmd_no); mwifiex_insert_cmd_to_free_q(adapter, cmd_node); return -1; } @@ -577,9 +578,9 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, /* Exit_PS command needs to be queued in the header always. */ if (command == HostCmd_CMD_802_11_PS_MODE_ENH) { struct host_cmd_ds_802_11_ps_mode_enh *pm = - &host_cmd->params.psmode_enh; - if ((le16_to_cpu(pm->action) == DIS_PS) - || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { + &host_cmd->params.psmode_enh; + if ((le16_to_cpu(pm->action) == DIS_PS) || + (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { if (adapter->ps_state != PS_STATE_AWAKE) add_tail = false; } @@ -692,7 +693,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { resp = (struct host_cmd_ds_command *) adapter->upld_buf; dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n", - le16_to_cpu(resp->command)); + le16_to_cpu(resp->command)); return -1; } @@ -701,7 +702,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n", - le16_to_cpu(resp->command)); + le16_to_cpu(resp->command)); mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = NULL; @@ -725,8 +726,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Get BSS number and corresponding priv */ priv = mwifiex_get_priv_by_id(adapter, - HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), - HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); + HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), + HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); if (!priv) priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); /* Clear RET_BIT from HostCmd */ @@ -737,9 +738,9 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Save the last command response to debug log */ adapter->dbg.last_cmd_resp_index = - (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] = - orig_cmdresp_no; + orig_cmdresp_no; do_gettimeofday(&tstamp); dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d," @@ -761,8 +762,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD; - if ((cmdresp_result == HostCmd_RESULT_OK) - && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) + if ((cmdresp_result == HostCmd_RESULT_OK) && + (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) ret = mwifiex_ret_802_11_hs_cfg(priv, resp); } else { /* handle response */ @@ -824,44 +825,45 @@ mwifiex_cmd_timeout_func(unsigned long function_context) adapter->dbg.timeout_cmd_act = adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; do_gettimeofday(&tstamp); - dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x," - " act = %#x\n", __func__, - tstamp.tv_sec, tstamp.tv_usec, - adapter->dbg.timeout_cmd_id, - adapter->dbg.timeout_cmd_act); + dev_err(adapter->dev, + "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n", + __func__, tstamp.tv_sec, tstamp.tv_usec, + adapter->dbg.timeout_cmd_id, + adapter->dbg.timeout_cmd_act); dev_err(adapter->dev, "num_data_h2c_failure = %d\n", - adapter->dbg.num_tx_host_to_card_failure); + adapter->dbg.num_tx_host_to_card_failure); dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", - adapter->dbg.num_cmd_host_to_card_failure); + adapter->dbg.num_cmd_host_to_card_failure); dev_err(adapter->dev, "num_cmd_timeout = %d\n", - adapter->dbg.num_cmd_timeout); + adapter->dbg.num_cmd_timeout); dev_err(adapter->dev, "num_tx_timeout = %d\n", - adapter->dbg.num_tx_timeout); + adapter->dbg.num_tx_timeout); dev_err(adapter->dev, "last_cmd_index = %d\n", - adapter->dbg.last_cmd_index); + adapter->dbg.last_cmd_index); print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_id, DBG_CMD_NUM); + adapter->dbg.last_cmd_id, DBG_CMD_NUM); print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_act, DBG_CMD_NUM); + adapter->dbg.last_cmd_act, DBG_CMD_NUM); dev_err(adapter->dev, "last_cmd_resp_index = %d\n", - adapter->dbg.last_cmd_resp_index); + adapter->dbg.last_cmd_resp_index); print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM); + adapter->dbg.last_cmd_resp_id, + DBG_CMD_NUM); dev_err(adapter->dev, "last_event_index = %d\n", - adapter->dbg.last_event_index); + adapter->dbg.last_event_index); print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_event, DBG_CMD_NUM); + adapter->dbg.last_event, DBG_CMD_NUM); dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", - adapter->data_sent, adapter->cmd_sent); + adapter->data_sent, adapter->cmd_sent); dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", - adapter->ps_mode, adapter->ps_state); + adapter->ps_mode, adapter->ps_state); } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); @@ -942,7 +944,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) uint16_t cancel_scan_cmd = false; if ((adapter->curr_cmd) && - (adapter->curr_cmd->wait_q_enabled)) { + (adapter->curr_cmd->wait_q_enabled)) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); cmd_node = adapter->curr_cmd; cmd_node->wait_q_enabled = false; @@ -996,9 +998,9 @@ mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) else dev_dbg(adapter->dev, "cmd: Delay Sleep Confirm (%s%s%s)\n", - (adapter->cmd_sent) ? "D" : "", - (adapter->curr_cmd) ? "C" : "", - (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); + (adapter->cmd_sent) ? "D" : "", + (adapter->curr_cmd) ? "C" : "", + (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); } /* @@ -1050,8 +1052,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n", resp->result, conditions, - phs_cfg->params.hs_config.gpio, - phs_cfg->params.hs_config.gap); + phs_cfg->params.hs_config.gpio, + phs_cfg->params.hs_config.gap); } if (conditions != HOST_SLEEP_CFG_CANCEL) { adapter->is_hs_configured = true; @@ -1078,7 +1080,8 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) adapter->hs_activated = false; adapter->is_hs_configured = false; mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), false); + MWIFIEX_BSS_ROLE_ANY), + false); } /* @@ -1114,22 +1117,24 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter, command &= HostCmd_CMD_ID_MASK; if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { - dev_err(adapter->dev, "%s: received unexpected response for" - " cmd %x, result = %x\n", __func__, command, result); + dev_err(adapter->dev, + "%s: rcvd unexpected resp for cmd %#x, result = %x\n", + __func__, command, result); return; } if (result) { dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", - __func__); + __func__); adapter->pm_wakeup_card_req = false; adapter->ps_state = PS_STATE_AWAKE; return; } adapter->pm_wakeup_card_req = true; if (adapter->is_hs_configured) - mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), true); + mwifiex_hs_activated_event(mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_ANY), + true); adapter->ps_state = PS_STATE_SLEEP; cmd->command = cpu_to_le16(command); cmd->seq_num = cpu_to_le16(seq_num); @@ -1163,17 +1168,17 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap)); + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == GET_PS) { psmode_enh->action = cpu_to_le16(GET_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap)); + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == EN_AUTO_PS) { psmode_enh->action = cpu_to_le16(EN_AUTO_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap); + sizeof(psmode_enh->params.ps_bitmap); tlv = (u8 *) cmd + cmd_size; if (ps_bitmap & BITMAP_STA_PS) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1187,19 +1192,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, tlv += sizeof(*ps_tlv); dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); ps_mode->null_pkt_interval = - cpu_to_le16(adapter->null_pkt_interval); + cpu_to_le16(adapter->null_pkt_interval); ps_mode->multiple_dtims = - cpu_to_le16(adapter->multiple_dtim); + cpu_to_le16(adapter->multiple_dtim); ps_mode->bcn_miss_timeout = - cpu_to_le16(adapter->bcn_miss_time_out); + cpu_to_le16(adapter->bcn_miss_time_out); ps_mode->local_listen_interval = cpu_to_le16(adapter->local_listen_interval); ps_mode->adhoc_wake_period = cpu_to_le16(adapter->adhoc_awake_period); ps_mode->delay_to_ps = - cpu_to_le16(adapter->delay_to_ps); - ps_mode->mode = - cpu_to_le16(adapter->enhanced_ps_mode); + cpu_to_le16(adapter->delay_to_ps); + ps_mode->mode = cpu_to_le16(adapter->enhanced_ps_mode); } if (ps_bitmap & BITMAP_AUTO_DS) { @@ -1217,7 +1221,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, if (auto_ds) idletime = auto_ds->idle_time; dev_dbg(priv->adapter->dev, - "cmd: PS Command: Enter Auto Deep Sleep\n"); + "cmd: PS Command: Enter Auto Deep Sleep\n"); auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); } cmd->size = cpu_to_le16(cmd_size); @@ -1244,8 +1248,9 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, uint16_t auto_ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap); - dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", - __func__, resp->result, action); + dev_dbg(adapter->dev, + "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", + __func__, resp->result, action); if (action == EN_AUTO_PS) { if (auto_ps_bitmap & BITMAP_AUTO_DS) { dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); @@ -1254,7 +1259,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, if (auto_ps_bitmap & BITMAP_STA_PS) { dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); if (adapter->sleep_period.period) - dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n"); + dev_dbg(adapter->dev, + "cmd: set to uapsd/pps mode\n"); } } else if (action == DIS_AUTO_PS) { if (ps_bitmap & BITMAP_AUTO_DS) { @@ -1373,12 +1379,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", - adapter->fw_release_number); + adapter->fw_release_number); dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", - hw_spec->permanent_addr); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", + hw_spec->permanent_addr); + dev_dbg(adapter->dev, + "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", le16_to_cpu(hw_spec->hw_if_version), - le16_to_cpu(hw_spec->version)); + le16_to_cpu(hw_spec->version)); if (priv->curr_addr[0] == 0xff) memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); @@ -1393,7 +1400,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, /* If it's unidentified region code, use the default (USA) */ if (i >= MWIFIEX_MAX_REGION_CODE) { adapter->region_code = 0x10; - dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n"); + dev_dbg(adapter->dev, + "cmd: unknown region code, use default (USA)\n"); } adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index fc4ffee6c6b9..e98fc5af73dc 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -117,8 +117,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define BA_STREAM_NOT_ALLOWED 0xff #define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \ - priv->adapter->config_bands & BAND_AN) \ - && priv->curr_bss_params.bss_descriptor.bcn_ht_cap) + priv->adapter->config_bands & BAND_AN) && \ + priv->curr_bss_params.bss_descriptor.bcn_ht_cap) #define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\ BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e81bf6ef1666..54bb4839b57c 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -35,28 +35,24 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bss_prio; + struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; unsigned long flags; bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); if (!bss_prio) { dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", - __func__); + __func__); return -ENOMEM; } bss_prio->priv = priv; INIT_LIST_HEAD(&bss_prio->list); - if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur) - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - bss_prio; - - spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_lock, flags); - list_add_tail(&bss_prio->list, - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_head); - spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_lock, flags); + if (!tbl[priv->bss_priority].bss_prio_cur) + tbl[priv->bss_priority].bss_prio_cur = bss_prio; + + spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); + list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); + spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags); return 0; } @@ -157,13 +153,13 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter) ret = mwifiex_alloc_cmd_buffer(adapter); if (ret) { dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n", - __func__); + __func__); return -1; } adapter->sleep_cfm = dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm) - + INTF_HEADER_LEN); + + INTF_HEADER_LEN); if (!adapter->sleep_cfm) { dev_err(adapter->dev, "%s: failed to alloc sleep cfm" @@ -520,7 +516,7 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; struct list_head *head; - spinlock_t *lock; + spinlock_t *lock; /* bss priority lock */ unsigned long flags; for (i = 0; i < adapter->priv_num; ++i) { @@ -638,7 +634,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, ret = adapter->if_ops.check_fw_status(adapter, poll_num); if (!ret) { dev_notice(adapter->dev, - "WLAN FW already running! Skip FW download\n"); + "WLAN FW already running! Skip FW download\n"); goto done; } poll_num = MAX_FIRMWARE_POLL_TRIES; @@ -646,8 +642,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, /* Check if we are the winner for downloading FW */ if (!adapter->winner) { dev_notice(adapter->dev, - "Other interface already running!" - " Skip FW download\n"); + "Other intf already running! Skip FW download\n"); poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; goto poll_fw; } diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index bce9991612c8..8f9382b9c3ca 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -52,8 +52,9 @@ mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer) * parameter buffer pointer. */ if (priv->gen_ie_buf_len) { - dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n", - __func__, priv->gen_ie_buf_len, *buffer); + dev_dbg(priv->adapter->dev, + "info: %s: append generic ie len %d to %p\n", + __func__, priv->gen_ie_buf_len, *buffer); /* Wrap the generic IE buffer with a pass through TLV type */ ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH); @@ -123,8 +124,9 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val)); - dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - " - "%016llx\n", __func__, tsf_val, bss_desc->network_tsf); + dev_dbg(priv->adapter->dev, + "info: %s: TSF offset calc: %016llx - %016llx\n", + __func__, tsf_val, bss_desc->network_tsf); memcpy(*buffer, &tsf_val, sizeof(tsf_val)); *buffer += sizeof(tsf_val); @@ -167,7 +169,7 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1, } dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n", - priv->data_rate); + priv->data_rate); if (!priv->is_data_rate_auto) { while (*ptr) { @@ -212,7 +214,7 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv, card_rates, card_rates_size)) { *out_rates_size = 0; dev_err(priv->adapter->dev, "%s: cannot get common rates\n", - __func__); + __func__); return -1; } @@ -248,7 +250,7 @@ mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer) */ if (priv->wapi_ie_len) { dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n", - priv->wapi_ie_len, *buffer); + priv->wapi_ie_len, *buffer); /* Wrap the generic IE buffer with a pass through TLV type */ ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE); @@ -293,10 +295,10 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF); rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]); rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len) - & 0x00FF); + & 0x00FF); if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2)) memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2], - le16_to_cpu(rsn_ie_tlv->header.len)); + le16_to_cpu(rsn_ie_tlv->header.len)); else return -1; @@ -379,7 +381,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID); ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len); memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid, - le16_to_cpu(ssid_tlv->header.len)); + le16_to_cpu(ssid_tlv->header.len)); pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len); phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos; @@ -411,7 +413,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, memcpy(rates_tlv->rates, rates, rates_size); pos += sizeof(rates_tlv->header) + rates_size; dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n", - rates_size); + rates_size); /* Add the Authentication type to be used for Auth frames */ auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; @@ -425,12 +427,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len); - if (IS_SUPPORT_MULTI_BANDS(priv->adapter) - && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (!bss_desc->disable_11n) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && (bss_desc->bcn_ht_cap) + if (IS_SUPPORT_MULTI_BANDS(priv->adapter) && + !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (!bss_desc->disable_11n) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + (bss_desc->bcn_ht_cap) ) ) { /* Append a channel TLV for the channel the attempted AP was @@ -445,13 +447,13 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, chan_tlv->chan_scan_param[0].chan_number = (bss_desc->phy_param_set.ds_param_set.current_chan); dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + sizeof(struct mwifiex_chan_scan_param_set); } @@ -464,10 +466,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return -1; } - if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (!bss_desc->disable_11n) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (!bss_desc->disable_11n) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN)) mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); /* Append vendor specific IE TLV */ @@ -493,7 +495,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, tmp_cap &= CAPINFO_MASK; dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", - tmp_cap, CAPINFO_MASK); + tmp_cap, CAPINFO_MASK); assoc->cap_info_bitmap = cpu_to_le16(tmp_cap); return 0; @@ -573,17 +575,17 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, - sizeof(priv->assoc_rsp_buf)); + sizeof(priv->assoc_rsp_buf)); memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); if (le16_to_cpu(assoc_rsp->status_code)) { priv->adapter->dbg.num_cmd_assoc_failure++; - dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, " - "status code = %d, error = 0x%x, a_id = 0x%x\n", - le16_to_cpu(assoc_rsp->status_code), - le16_to_cpu(assoc_rsp->cap_info_bitmap), - le16_to_cpu(assoc_rsp->a_id)); + dev_err(priv->adapter->dev, + "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n", + le16_to_cpu(assoc_rsp->status_code), + le16_to_cpu(assoc_rsp->cap_info_bitmap), + le16_to_cpu(assoc_rsp->a_id)); ret = le16_to_cpu(assoc_rsp->status_code); goto done; @@ -600,7 +602,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, bss_desc = priv->attempted_bss_desc; dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, @@ -617,8 +619,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, else priv->curr_bss_params.wmm_enabled = false; - if ((priv->wmm_required || bss_desc->bcn_ht_cap) - && priv->curr_bss_params.wmm_enabled) + if ((priv->wmm_required || bss_desc->bcn_ht_cap) && + priv->curr_bss_params.wmm_enabled) priv->wmm_enabled = true; else priv->wmm_enabled = false; @@ -631,7 +633,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0); dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n", - priv->curr_pkt_filter); + priv->curr_pkt_filter); if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) priv->wpa_is_gtk_set = false; @@ -755,7 +757,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", - adhoc_start->ssid); + adhoc_start->ssid); memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); @@ -777,12 +779,11 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID; adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN; - if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, adapter->adhoc_start_band, (u16) - priv->adhoc_channel)) { + if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band, + (u16) priv->adhoc_channel, 0)) { struct mwifiex_chan_freq_power *cfp; - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - adapter->adhoc_start_band, FIRST_VALID_CHANNEL); + cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band, + FIRST_VALID_CHANNEL, 0); if (cfp) priv->adhoc_channel = (u8) cfp->channel; } @@ -793,7 +794,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, } dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n", - priv->adhoc_channel); + priv->adhoc_channel); priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel; priv->curr_bss_params.band = adapter->adhoc_start_band; @@ -814,7 +815,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID; adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN; adhoc_start->ss_param_set.ibss_param_set.atim_window - = cpu_to_le16(priv->atim_window); + = cpu_to_le16(priv->atim_window); memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set, sizeof(union ieee_types_ss_param_set)); @@ -842,10 +843,10 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, if ((adapter->adhoc_start_band & BAND_G) && (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, - &priv->curr_pkt_filter)) { + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter)) { dev_err(adapter->dev, - "ADHOC_S_CMD: G Protection config failed\n"); + "ADHOC_S_CMD: G Protection config failed\n"); return -1; } } @@ -861,8 +862,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", - adhoc_start->data_rate[0], adhoc_start->data_rate[1], - adhoc_start->data_rate[2], adhoc_start->data_rate[3]); + adhoc_start->data_rate[0], adhoc_start->data_rate[1], + adhoc_start->data_rate[2], adhoc_start->data_rate[3]); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); @@ -879,12 +880,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, (u8) priv->curr_bss_params.bss_descriptor.channel; dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type(priv->curr_bss_params.band); - if (adapter->adhoc_start_band & BAND_GN - || adapter->adhoc_start_band & BAND_AN) { + if (adapter->adhoc_start_band & BAND_GN || + adapter->adhoc_start_band & BAND_AN) { if (adapter->sec_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) chan_tlv->chan_scan_param[0].radio_type |= @@ -895,7 +896,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4); } dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + sizeof(struct mwifiex_chan_scan_param_set); cmd_append_size += @@ -926,15 +927,14 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, mwifiex_fill_cap_info(priv, radio_type, ht_cap); pos += sizeof(struct mwifiex_ie_types_htcap); - cmd_append_size += - sizeof(struct mwifiex_ie_types_htcap); + cmd_append_size += sizeof(struct mwifiex_ie_types_htcap); /* Fill HT INFORMATION */ ht_info = (struct mwifiex_ie_types_htinfo *) pos; memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION); ht_info->header.len = - cpu_to_le16(sizeof(struct ieee80211_ht_info)); + cpu_to_le16(sizeof(struct ieee80211_ht_info)); ht_info->ht_info.control_chan = (u8) priv->curr_bss_params.bss_descriptor.channel; @@ -948,12 +948,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, ht_info->ht_info.basic_set[0] = 0xff; pos += sizeof(struct mwifiex_ie_types_htinfo); cmd_append_size += - sizeof(struct mwifiex_ie_types_htinfo); + sizeof(struct mwifiex_ie_types_htinfo); } - cmd->size = cpu_to_le16((u16) - (sizeof(struct host_cmd_ds_802_11_ad_hoc_start) - + S_DS_GEN + cmd_append_size)); + cmd->size = + cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start) + + S_DS_GEN + cmd_append_size)); if (adapter->adhoc_start_band == BAND_B) tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME; @@ -1006,10 +1006,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, - &curr_pkt_filter)) { + HostCmd_ACT_GEN_SET, 0, + &curr_pkt_filter)) { dev_err(priv->adapter->dev, - "ADHOC_J_CMD: G Protection config failed\n"); + "ADHOC_J_CMD: G Protection config failed\n"); return -1; } } @@ -1040,13 +1040,14 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, tmp_cap &= CAPINFO_MASK; - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X" - " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK); + dev_dbg(priv->adapter->dev, + "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", + tmp_cap, CAPINFO_MASK); /* Information on BSSID descriptor passed to FW */ - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n", - adhoc_join->bss_descriptor.bssid, - adhoc_join->bss_descriptor.ssid); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n", + adhoc_join->bss_descriptor.bssid, + adhoc_join->bss_descriptor.ssid); for (i = 0; bss_desc->supported_rates[i] && i < MWIFIEX_SUPPORTED_RATES; @@ -1083,18 +1084,18 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, sizeof(struct mwifiex_chan_scan_param_set)); chan_tlv->chan_scan_param[0].chan_number = (bss_desc->phy_param_set.ds_param_set.current_chan); - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n", + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n", + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + - sizeof(struct mwifiex_chan_scan_param_set); + sizeof(struct mwifiex_chan_scan_param_set); cmd_append_size += sizeof(chan_tlv->header) + - sizeof(struct mwifiex_chan_scan_param_set); + sizeof(struct mwifiex_chan_scan_param_set); } if (priv->sec_info.wpa_enabled) @@ -1111,9 +1112,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ADHOC, &pos); - cmd->size = cpu_to_le16((u16) - (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) - + S_DS_GEN + cmd_append_size)); + cmd->size = cpu_to_le16 + ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) + + S_DS_GEN + cmd_append_size)); adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); @@ -1158,7 +1159,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) { dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* Update the created network descriptor with the new BSSID */ memcpy(bss_desc->mac_address, @@ -1171,7 +1172,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, * If BSSID has changed use SSID to compare instead of BSSID */ dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* * Make a copy of current BSSID descriptor, only needed for @@ -1185,9 +1186,9 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, } dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n", - priv->adhoc_channel); + priv->adhoc_channel); dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n", - priv->curr_bss_params.bss_descriptor.mac_address); + priv->curr_bss_params.bss_descriptor.mac_address); if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); @@ -1250,9 +1251,9 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", priv->adhoc_channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", - priv->curr_bss_params.bss_descriptor.channel); + priv->curr_bss_params.bss_descriptor.channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", - priv->curr_bss_params.band); + priv->curr_bss_params.band); return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, HostCmd_ACT_GEN_SET, 0, adhoc_ssid); @@ -1268,13 +1269,13 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc) { dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid); + priv->curr_bss_params.bss_descriptor.ssid.ssid); dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n", bss_desc->ssid.ssid); dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n", - bss_desc->ssid.ssid_len); + bss_desc->ssid.ssid_len); /* Check if the requested SSID is already joined */ if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len && @@ -1288,9 +1289,9 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, } dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", - priv->curr_bss_params.bss_descriptor.channel); + priv->curr_bss_params.bss_descriptor.channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", - priv->curr_bss_params.band); + priv->curr_bss_params.band); return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, HostCmd_ACT_GEN_SET, 0, bss_desc); diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 790a3796483c..9d1b3ca6334b 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -64,11 +64,10 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, adapter->priv_num = 0; /* Allocate memory for private structure */ - adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), - GFP_KERNEL); + adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); if (!adapter->priv[0]) { - dev_err(adapter->dev, "%s: failed to alloc priv[0]\n", - __func__); + dev_err(adapter->dev, + "%s: failed to alloc priv[0]\n", __func__); goto error; } @@ -169,8 +168,8 @@ process_start: if ((adapter->ps_state == PS_STATE_SLEEP) && (adapter->pm_wakeup_card_req && !adapter->pm_wakeup_fw_try) && - (is_command_pending(adapter) - || !mwifiex_wmm_lists_empty(adapter))) { + (is_command_pending(adapter) || + !mwifiex_wmm_lists_empty(adapter))) { adapter->pm_wakeup_fw_try = true; adapter->if_ops.wakeup(adapter); continue; @@ -187,10 +186,10 @@ process_start: adapter->tx_lock_flag) break; - if (adapter->scan_processing || adapter->data_sent - || mwifiex_wmm_lists_empty(adapter)) { - if (adapter->cmd_sent || adapter->curr_cmd - || (!is_command_pending(adapter))) + if (adapter->scan_processing || adapter->data_sent || + mwifiex_wmm_lists_empty(adapter)) { + if (adapter->cmd_sent || adapter->curr_cmd || + (!is_command_pending(adapter))) break; } } @@ -223,10 +222,10 @@ process_start: /* * The ps_state may have been changed during processing of * Sleep Request event. */ - if ((adapter->ps_state == PS_STATE_SLEEP) - || (adapter->ps_state == PS_STATE_PRE_SLEEP) - || (adapter->ps_state == PS_STATE_SLEEP_CFM) - || adapter->tx_lock_flag) + if ((adapter->ps_state == PS_STATE_SLEEP) || + (adapter->ps_state == PS_STATE_PRE_SLEEP) || + (adapter->ps_state == PS_STATE_SLEEP_CFM) || + adapter->tx_lock_flag) continue; if (!adapter->cmd_sent && !adapter->curr_cmd) { @@ -249,8 +248,8 @@ process_start: } if (adapter->delay_null_pkt && !adapter->cmd_sent && - !adapter->curr_cmd && !is_command_pending(adapter) - && mwifiex_wmm_lists_empty(adapter)) { + !adapter->curr_cmd && !is_command_pending(adapter) && + mwifiex_wmm_lists_empty(adapter)) { if (!mwifiex_send_null_packet (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | @@ -371,7 +370,7 @@ mwifiex_fill_buffer(struct sk_buff *skb) iph = ip_hdr(skb); tid = IPTOS_PREC(iph->tos); pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", - eth->h_proto, tid, skb->priority); + eth->h_proto, tid, skb->priority); break; case __constant_htons(ETH_P_ARP): pr_debug("data: ARP packet: %04x\n", eth->h_proto); @@ -425,7 +424,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct mwifiex_txinfo *tx_info; dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", - jiffies, priv->bss_type, priv->bss_num); + jiffies, priv->bss_type, priv->bss_num); if (priv->adapter->surprise_removed) { kfree_skb(skb); @@ -441,7 +440,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) { dev_dbg(priv->adapter->dev, "data: Tx: insufficient skb headroom %d\n", - skb_headroom(skb)); + skb_headroom(skb)); /* Insufficient skb headroom - allocate a new skb */ new_skb = skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN); @@ -454,7 +453,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) kfree_skb(skb); skb = new_skb; dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n", - skb_headroom(skb)); + skb_headroom(skb)); } tx_info = MWIFIEX_SKB_TXCB(skb); @@ -494,8 +493,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) if (!ret) memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); else - dev_err(priv->adapter->dev, "set mac address failed: ret=%d" - "\n", ret); + dev_err(priv->adapter->dev, + "set mac address failed: ret=%d\n", ret); memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); @@ -533,7 +532,7 @@ mwifiex_tx_timeout(struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", - jiffies, priv->bss_type, priv->bss_num); + jiffies, priv->bss_type, priv->bss_num); mwifiex_set_trans_start(dev); priv->num_tx_timeout++; } @@ -704,7 +703,7 @@ mwifiex_add_card(void *card, struct semaphore *sem, rtnl_lock(); /* Create station interface by default */ if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d", - NL80211_IFTYPE_STATION, NULL, NULL)) { + NL80211_IFTYPE_STATION, NULL, NULL)) { rtnl_unlock(); dev_err(adapter->dev, "cannot create default station" " interface\n"); @@ -781,7 +780,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) if (priv && priv->netdev) { if (!netif_queue_stopped(priv->netdev)) mwifiex_stop_net_dev_queue(priv->netdev, - adapter); + adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 6dc116647411..35225e9b1080 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -462,9 +462,9 @@ struct mwifiex_private { }; enum mwifiex_ba_status { - BA_STREAM_NOT_SETUP = 0, - BA_STREAM_SETUP_INPROGRESS, - BA_STREAM_SETUP_COMPLETE + BA_SETUP_NONE = 0, + BA_SETUP_INPROGRESS, + BA_SETUP_COMPLETE }; struct mwifiex_tx_ba_stream_tbl { @@ -771,13 +771,8 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); -struct mwifiex_chan_freq_power * - mwifiex_get_cfp_by_band_and_channel_from_cfg80211( - struct mwifiex_private *priv, - u8 band, u16 channel); -struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( - struct mwifiex_private *priv, - u8 band, u32 freq); +struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv, + u8 band, u16 channel, u32 freq); u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, u8 ht_info); u32 mwifiex_find_freq_from_band_chan(u8, u8); @@ -846,8 +841,8 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { - if ((adapter->priv[i]->bss_num == bss_num) - && (adapter->priv[i]->bss_type == bss_type)) + if ((adapter->priv[i]->bss_num == bss_num) && + (adapter->priv[i]->bss_type == bss_type)) break; } } diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index f4fbad95d3e3..5867facd415d 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -83,7 +83,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, struct pcie_service_card *card; pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", - pdev->vendor, pdev->device, pdev->revision); + pdev->vendor, pdev->device, pdev->revision); card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL); if (!card) @@ -108,6 +108,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) { struct pcie_service_card *card; struct mwifiex_adapter *adapter; + struct mwifiex_private *priv; int i; card = pci_get_drvdata(pdev); @@ -126,16 +127,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == - MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) + MWIFIEX_BSS_ROLE_STA) && + adapter->priv[i]->media_connected) mwifiex_deauthenticate(adapter->priv[i], NULL); - mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY)); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + mwifiex_disable_auto_ds(priv); + + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); @@ -219,7 +219,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) netif_carrier_on(adapter->priv[i]->netdev); mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - MWIFIEX_ASYNC_CMD); + MWIFIEX_ASYNC_CMD); return 0; } @@ -286,7 +286,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) while (mwifiex_pcie_ok_to_access_hw(adapter)) { i++; - udelay(10); + usleep_range(10, 20); /* 50ms max wait */ if (i == 50000) break; @@ -378,26 +378,26 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) /* allocate shared memory for the BD ring and divide the same in to several descriptors */ card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", - card->txbd_ring_size); + card->txbd_ring_size); card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); if (!card->txbd_ring_vbase) { - dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); + dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n"); return -ENOMEM; } card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); - dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x," - "len: %x\n", card->txbd_ring_vbase, - (u32)card->txbd_ring_pbase, - (u32)((u64)card->txbd_ring_pbase >> 32), - card->txbd_ring_size); + dev_dbg(adapter->dev, + "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", + card->txbd_ring_vbase, (u32)card->txbd_ring_pbase, + (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->txbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->txbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate buffer here so that firmware can DMA data from it */ skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); @@ -410,10 +410,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, + (u32)(((u64)*buf_pa >> 32)), skb->len); card->tx_buf_list[i] = skb; card->txbd_ring[i]->paddr = *buf_pa; @@ -467,9 +466,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", - card->rxbd_ring_size); + card->rxbd_ring_size); card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); if (!card->rxbd_ring_vbase) { dev_err(adapter->dev, "Unable to allocate buffer for " @@ -478,21 +477,23 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) } card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); - dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x," - "len: %#x\n", card->rxbd_ring_vbase, - (u32)card->rxbd_ring_pbase, - (u32)((u64)card->rxbd_ring_pbase >> 32), - card->rxbd_ring_size); + dev_dbg(adapter->dev, + "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", + card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase, + (u32)((u64)card->rxbd_ring_pbase >> 32), + card->rxbd_ring_size); for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->rxbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->rxbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate skb here so that firmware can DMA data from it */ skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for RX ring.\n"); kfree(card->rxbd_ring_vbase); return -ENOMEM; } @@ -500,10 +501,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), + skb->len); card->rx_buf_list[i] = skb; card->rxbd_ring[i]->paddr = *buf_pa; @@ -560,32 +560,34 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_EVT_BD; + MWIFIEX_MAX_EVT_BD; dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", - card->evtbd_ring_size); + card->evtbd_ring_size); card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); if (!card->evtbd_ring_vbase) { - dev_err(adapter->dev, "Unable to allocate buffer. " - "Terminating download\n"); + dev_err(adapter->dev, + "Unable to allocate buffer. Terminating download\n"); return -ENOMEM; } card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); - dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, " - "pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase, - (u32)card->evtbd_ring_pbase, - (u32)((u64)card->evtbd_ring_pbase >> 32), - card->evtbd_ring_size); + dev_dbg(adapter->dev, + "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", + card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase, + (u32)((u64)card->evtbd_ring_pbase >> 32), + card->evtbd_ring_size); for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->evtbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->evtbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate skb here so that firmware can DMA data from it */ skb = dev_alloc_skb(MAX_EVENT_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for EVENT buf.\n"); kfree(card->evtbd_ring_vbase); return -ENOMEM; } @@ -593,10 +595,9 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MAX_EVENT_SIZE); dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), + skb->len); card->evt_buf_list[i] = skb; card->evtbd_ring[i]->paddr = *buf_pa; @@ -645,8 +646,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) /* Allocate memory for receiving command response data */ skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for command " - "response data.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for command response data.\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -657,8 +658,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) /* Allocate memory for sending command to firmware */ skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for command " - "data.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for command data.\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -700,8 +701,8 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) /* Allocate memory for sleep cookie */ skb = dev_alloc_skb(sizeof(u32)); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for sleep " - "cookie!\n"); + dev_err(adapter->dev, + "Unable to allocate skb for sleep cookie!\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -711,7 +712,7 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) *(u32 *)skb->data = FW_AWAKE_COOKIE; dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", - *((u32 *)skb->data)); + *((u32 *)skb->data)); /* Save the sleep cookie */ card->sleep_cookie = skb; @@ -755,15 +756,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Read the TX ring read pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { - dev_err(adapter->dev, "SEND DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "SEND DATA: failed to read REG_TXBD_RDPTR\n"); return -1; } wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr, - card->txbd_wrptr); + card->txbd_wrptr); if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != (rdptr & MWIFIEX_TXBD_MASK)) || ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != @@ -795,32 +796,31 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, - card->txbd_wrptr)) { - dev_err(adapter->dev, "SEND DATA: failed to write " - "REG_TXBD_WRPTR\n"); + card->txbd_wrptr)) { + dev_err(adapter->dev, + "SEND DATA: failed to write REG_TXBD_WRPTR\n"); return 0; } /* Send the TX ready interrupt */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DNLD_RDY)) { - dev_err(adapter->dev, "SEND DATA: failed to assert " - "door-bell interrupt.\n"); + dev_err(adapter->dev, + "SEND DATA: failed to assert door-bell intr\n"); return -1; } dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " - "%#x> and sent packet to firmware " - "successfully\n", rdptr, - card->txbd_wrptr); + "%#x> and sent packet to firmware successfully\n", + rdptr, card->txbd_wrptr); } else { - dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore " - "packets to firmware\n"); + dev_dbg(adapter->dev, + "info: TX Ring full, can't send packets to fw\n"); adapter->data_sent = true; /* Send the TX ready interrupt */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DNLD_RDY)) - dev_err(adapter->dev, "SEND DATA: failed to assert " - "door-bell interrupt\n"); + dev_err(adapter->dev, + "SEND DATA: failed to assert door-bell intr\n"); return -EBUSY; } @@ -840,8 +840,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) /* Read the RX ring Write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "RECV DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to read REG_TXBD_RDPTR\n"); ret = -1; goto done; } @@ -859,12 +859,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) /* Get data length from interface header - first byte is len, second byte is type */ rx_len = *((u16 *)skb_data->data); - dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, " - "Len=%d\n", card->rxbd_rdptr, wrptr, rx_len); + dev_dbg(adapter->dev, + "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", + card->rxbd_rdptr, wrptr, rx_len); skb_tmp = dev_alloc_skb(rx_len); if (!skb_tmp) { - dev_dbg(adapter->dev, "info: Failed to alloc skb " - "for RX\n"); + dev_dbg(adapter->dev, + "info: Failed to alloc skb for RX\n"); ret = -EBUSY; goto done; } @@ -879,26 +880,26 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) MWIFIEX_BD_FLAG_ROLLOVER_IND); } dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n", - card->rxbd_rdptr, wrptr); + card->rxbd_rdptr, wrptr); /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr)) { - dev_err(adapter->dev, "RECV DATA: failed to " - "write REG_RXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to write REG_RXBD_RDPTR\n"); ret = -1; goto done; } /* Read the RX ring Write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "RECV DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to read REG_TXBD_RDPTR\n"); ret = -1; goto done; } - dev_dbg(adapter->dev, "info: RECV DATA: Received packet from " - "firmware successfully\n"); + dev_dbg(adapter->dev, + "info: RECV DATA: Rcvd packet from fw successfully\n"); mwifiex_handle_rx_packet(adapter, skb_tmp); } @@ -917,17 +918,19 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); if (!(skb->data && skb->len && *buf_pa)) { - dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, " - "%x>\n", __func__, skb->data, skb->len, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); + dev_err(adapter->dev, + "Invalid parameter in %s <%p, %#x:%x, %x>\n", + __func__, skb->data, skb->len, + (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); return -1; } /* Write the lower 32bits of the physical address to scratch * register 0 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { - dev_err(adapter->dev, "%s: failed to write download command " - "to boot code.\n", __func__); + dev_err(adapter->dev, + "%s: failed to write download command to boot code.\n", + __func__); return -1; } @@ -935,23 +938,25 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) * register 1 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, (u32)((u64)*buf_pa >> 32))) { - dev_err(adapter->dev, "%s: failed to write download command " - "to boot code.\n", __func__); + dev_err(adapter->dev, + "%s: failed to write download command to boot code.\n", + __func__); return -1; } /* Write the command length to scratch register 2 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { - dev_err(adapter->dev, "%s: failed to write command length to " - "scratch register 2\n", __func__); + dev_err(adapter->dev, + "%s: failed to write command len to scratch reg 2\n", + __func__); return -1; } /* Ring the door bell */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DOOR_BELL)) { - dev_err(adapter->dev, "%s: failed to assert door-bell " - "interrupt.\n", __func__); + dev_err(adapter->dev, + "%s: failed to assert door-bell intr\n", __func__); return -1; } @@ -971,14 +976,14 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) if (!(skb->data && skb->len)) { dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", - __func__, skb->data, skb->len); + __func__, skb->data, skb->len); return -1; } /* Make sure a command response buffer is available */ if (!card->cmdrsp_buf) { - dev_err(adapter->dev, "No response buffer available, send " - "command failed\n"); + dev_err(adapter->dev, + "No response buffer available, send command failed\n"); return -EBUSY; } @@ -1009,17 +1014,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Write the lower 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, - (u32)*cmdrsp_buf_pa)) { - dev_err(adapter->dev, "Failed to write download command to boot code.\n"); + (u32)*cmdrsp_buf_pa)) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the upper 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, - (u32)((u64)*cmdrsp_buf_pa >> 32))) { - dev_err(adapter->dev, "Failed to write download command" - " to boot code.\n"); + (u32)((u64)*cmdrsp_buf_pa >> 32))) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } @@ -1027,27 +1033,25 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ - if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, - (u32)*cmd_buf_pa)) { - dev_err(adapter->dev, "Failed to write download command " - "to boot code.\n"); + if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, - (u32)((u64)*cmd_buf_pa >> 32))) { - dev_err(adapter->dev, "Failed to write download command " - "to boot code.\n"); + (u32)((u64)*cmd_buf_pa >> 32))) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the command length to REG_CMD_SIZE */ - if (mwifiex_write_reg(adapter, REG_CMD_SIZE, - card->cmd_buf->len)) { - dev_err(adapter->dev, "Failed to write command length to " - "REG_CMD_SIZE\n"); + if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) { + dev_err(adapter->dev, + "Failed to write cmd len to REG_CMD_SIZE\n"); ret = -1; goto done; } @@ -1055,8 +1059,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Ring the door bell */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DOOR_BELL)) { - dev_err(adapter->dev, "Failed to assert door-bell " - "interrupt.\n"); + dev_err(adapter->dev, + "Failed to assert door-bell intr\n"); ret = -1; goto done; } @@ -1074,30 +1078,29 @@ done: static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + struct sk_buff *skb = card->cmdrsp_buf; int count = 0; dev_dbg(adapter->dev, "info: Rx CMD Response\n"); if (!adapter->curr_cmd) { - skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); + skb_pull(skb, INTF_HEADER_LEN); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { - mwifiex_process_sleep_confirm_resp(adapter, - card->cmdrsp_buf->data, - card->cmdrsp_buf->len); + mwifiex_process_sleep_confirm_resp(adapter, skb->data, + skb->len); while (mwifiex_pcie_ok_to_access_hw(adapter) && (count++ < 10)) - udelay(50); + usleep_range(50, 60); } else { - dev_err(adapter->dev, "There is no command but " - "got cmdrsp\n"); + dev_err(adapter->dev, + "There is no command but got cmdrsp\n"); } - memcpy(adapter->upld_buf, card->cmdrsp_buf->data, - min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, - card->cmdrsp_buf->len)); - skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); + memcpy(adapter->upld_buf, skb->data, + min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + skb_push(skb, INTF_HEADER_LEN); } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { - skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); - adapter->curr_cmd->resp_skb = card->cmdrsp_buf; + skb_pull(skb, INTF_HEADER_LEN); + adapter->curr_cmd->resp_skb = skb; adapter->cmd_resp_received = true; /* Take the pointer and set it to CMD node and will return in the response complete callback */ @@ -1107,15 +1110,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) will prevent firmware from writing to the same response buffer again. */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { - dev_err(adapter->dev, "cmd_done: failed to clear " - "cmd_rsp address.\n"); + dev_err(adapter->dev, + "cmd_done: failed to clear cmd_rsp_addr_lo\n"); return -1; } /* Write the upper 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { - dev_err(adapter->dev, "cmd_done: failed to clear " - "cmd_rsp address.\n"); + dev_err(adapter->dev, + "cmd_done: failed to clear cmd_rsp_addr_hi\n"); return -1; } } @@ -1149,8 +1152,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) u32 wrptr, event; if (adapter->event_received) { - dev_dbg(adapter->dev, "info: Event being processed, "\ - "do not process this interrupt just yet\n"); + dev_dbg(adapter->dev, "info: Event being processed, " + "do not process this interrupt just yet\n"); return 0; } @@ -1161,14 +1164,15 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) /* Read the event ring write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n"); + dev_err(adapter->dev, + "EventReady: failed to read REG_EVTBD_WRPTR\n"); return -1; } dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>", - card->evtbd_rdptr, wrptr); - if (((wrptr & MWIFIEX_EVTBD_MASK) != - (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) || + card->evtbd_rdptr, wrptr); + if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr + & MWIFIEX_EVTBD_MASK)) || ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { struct sk_buff *skb_cmd; @@ -1228,13 +1232,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, if (rdptr >= MWIFIEX_MAX_EVT_BD) { dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", - rdptr); + rdptr); return -EINVAL; } /* Read the event ring write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n"); + dev_err(adapter->dev, + "event_complete: failed to read REG_EVTBD_WRPTR\n"); return -1; } @@ -1247,9 +1252,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, card->evtbd_ring[rdptr]->flags = 0; skb = NULL; } else { - dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at " - "index %d, <%p, %p>\n", rdptr, - card->evt_buf_list[rdptr], skb); + dev_dbg(adapter->dev, + "info: ERROR: buf still valid at index %d, <%p, %p>\n", + rdptr, card->evt_buf_list[rdptr], skb); } if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { @@ -1259,11 +1264,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, } dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>", - card->evtbd_rdptr, wrptr); + card->evtbd_rdptr, wrptr); /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { - dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n"); + dev_err(adapter->dev, + "event_complete: failed to read REG_EVTBD_RDPTR\n"); return -1; } @@ -1297,17 +1303,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } if (!firmware || !firmware_len) { - dev_err(adapter->dev, "No firmware image found! " - "Terminating download\n"); + dev_err(adapter->dev, + "No firmware image found! Terminating download\n"); return -1; } dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n", - firmware_len); + firmware_len); if (mwifiex_pcie_disable_host_int(adapter)) { - dev_err(adapter->dev, "%s: Disabling interrupts" - " failed.\n", __func__); + dev_err(adapter->dev, + "%s: Disabling interrupts failed.\n", __func__); return -1; } @@ -1330,19 +1336,20 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, &len); if (ret) { - dev_warn(adapter->dev, "Failed reading length from boot code\n"); + dev_warn(adapter->dev, + "Failed reading len from boot code\n"); goto done; } if (len) break; - udelay(10); + usleep_range(10, 20); } if (!len) { break; } else if (len > MWIFIEX_UPLD_SIZE) { pr_err("FW download failure @ %d, invalid length %d\n", - offset, len); + offset, len); ret = -1; goto done; } @@ -1358,8 +1365,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, goto done; } dev_err(adapter->dev, "FW CRC error indicated by the " - "helper: len = 0x%04X, txlen = " - "%d\n", len, txlen); + "helper: len = 0x%04X, txlen = %d\n", + len, txlen); len &= ~BIT(0); /* Setting this to 0 to resend from same offset */ txlen = 0; @@ -1372,9 +1379,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "."); - tx_blocks = - (txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / - MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; + tx_blocks = (txlen + + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; /* Copy payload to buffer */ memmove(skb->data, &firmware[offset], txlen); @@ -1385,7 +1392,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, /* Send the boot command to device */ if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { - dev_err(adapter->dev, "Failed to send firmware download command\n"); + dev_err(adapter->dev, + "Failed to send firmware download command\n"); ret = -1; goto done; } @@ -1394,8 +1402,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, &ireg_intr)) { dev_err(adapter->dev, "%s: Failed to read " - "interrupt status during " - "fw dnld.\n", __func__); + "interrupt status during fw dnld.\n", + __func__); ret = -1; goto done; } @@ -1405,7 +1413,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } while (true); dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", - offset); + offset); ret = 0; @@ -1428,14 +1436,15 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) /* Mask spurios interrupts */ if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK, - HOST_INTR_MASK)) { + HOST_INTR_MASK)) { dev_warn(adapter->dev, "Write register failed\n"); return -1; } dev_dbg(adapter->dev, "Setting driver ready signature\n"); if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { - dev_err(adapter->dev, "Failed to write driver ready signature\n"); + dev_err(adapter->dev, + "Failed to write driver ready signature\n"); return -1; } @@ -1466,8 +1475,9 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) adapter->winner = 1; ret = -1; } else { - dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n", - ret, adapter->winner); + dev_err(adapter->dev, + "PCI-E is not the winner <%#x,%d>, exit dnld\n", + ret, adapter->winner); ret = 0; } } @@ -1510,10 +1520,11 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) (adapter->ps_state == PS_STATE_SLEEP)) { mwifiex_pcie_enable_host_int(adapter); if (mwifiex_write_reg(adapter, - PCIE_CPU_INT_EVENT, - CPU_INTR_SLEEP_CFM_DONE)) { - dev_warn(adapter->dev, "Write register" - " failed\n"); + PCIE_CPU_INT_EVENT, + CPU_INTR_SLEEP_CFM_DONE) + ) { + dev_warn(adapter->dev, + "Write register failed\n"); return; } @@ -1549,7 +1560,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context) card = (struct pcie_service_card *) pci_get_drvdata(pdev); if (!card || !card->adapter) { pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, - card ? card->adapter : NULL); + card ? card->adapter : NULL); goto exit; } adapter = card->adapter; @@ -1592,7 +1603,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (adapter->int_status & HOST_INTR_DNLD_DONE) { adapter->int_status &= ~HOST_INTR_DNLD_DONE; if (adapter->data_sent) { - dev_dbg(adapter->dev, "info: DATA sent Interrupt\n"); + dev_dbg(adapter->dev, "info: DATA sent intr\n"); adapter->data_sent = false; } } @@ -1614,7 +1625,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (adapter->int_status & HOST_INTR_CMD_DONE) { adapter->int_status &= ~HOST_INTR_CMD_DONE; if (adapter->cmd_sent) { - dev_dbg(adapter->dev, "info: CMD sent Interrupt\n"); + dev_dbg(adapter->dev, + "info: CMD sent Interrupt\n"); adapter->cmd_sent = false; } /* Handle command response */ @@ -1626,15 +1638,17 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (mwifiex_pcie_ok_to_access_hw(adapter)) { if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) { - dev_warn(adapter->dev, "Read register failed\n"); + dev_warn(adapter->dev, + "Read register failed\n"); return -1; } if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { if (mwifiex_write_reg(adapter, - PCIE_HOST_INT_STATUS, ~pcie_ireg)) { - dev_warn(adapter->dev, "Write register" - " failed\n"); + PCIE_HOST_INT_STATUS, + ~pcie_ireg)) { + dev_warn(adapter->dev, + "Write register failed\n"); return -1; } adapter->int_status |= pcie_ireg; @@ -1644,7 +1658,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) } } dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", - adapter->cmd_sent, adapter->data_sent); + adapter->cmd_sent, adapter->data_sent); mwifiex_pcie_enable_host_int(adapter); return 0; @@ -1735,8 +1749,9 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) goto err_iomap2; } - dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: " - "%p\n", card->pci_mmap, card->pci_mmap1); + dev_dbg(adapter->dev, + "PCI memory map Virt0: %p PCI memory map Virt2: %p\n", + card->pci_mmap, card->pci_mmap1); card->cmdrsp_buf = NULL; ret = mwifiex_pcie_create_txbd_ring(adapter); @@ -1806,7 +1821,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "Clearing driver ready signature\n"); if (user_rmmod) { if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) - dev_err(adapter->dev, "Failed to write driver not-ready signature\n"); + dev_err(adapter->dev, + "Failed to write driver not-ready signature\n"); } if (pdev) { diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index fd0302fe5bd8..aff9cd763f2b 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -125,7 +125,7 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) ieee_hdr.element_id == WLAN_EID_RSN))) { iebody = (struct ie_body *) (((u8 *) bss_desc->bcn_rsn_ie->data) + - RSN_GTK_OUI_OFFSET); + RSN_GTK_OUI_OFFSET); oui = &mwifiex_rsn_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); if (ret) @@ -148,8 +148,9 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) struct ie_body *iebody; u8 ret = MWIFIEX_OUI_NOT_PRESENT; - if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)). - vend_hdr.element_id == WLAN_EID_WPA))) { + if (((bss_desc->bcn_wpa_ie) && + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == + WLAN_EID_WPA))) { iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; oui = &mwifiex_wpa_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); @@ -175,8 +176,8 @@ mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wapi(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (priv->sec_info.wapi_enabled && (bss_desc->bcn_wapi_ie && @@ -192,18 +193,17 @@ mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, * scanned network is compatible with it. */ static bool -mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_no_sec(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != - WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || + WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != - WLAN_EID_RSN)) - && !priv->sec_info.encryption_mode - && !bss_desc->privacy) { + WLAN_EID_RSN)) && + !priv->sec_info.encryption_mode && !bss_desc->privacy) { return true; } return false; @@ -214,8 +214,8 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, * is compatible with it. */ static bool -mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_static_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && bss_desc->privacy) { @@ -229,8 +229,8 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wpa(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && @@ -264,17 +264,18 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wpa2(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && - priv->sec_info.wpa2_enabled && ((bss_desc->bcn_rsn_ie) && - ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN)) - /* - * Privacy bit may NOT be set in some APs like - * LinkSys WRT54G && bss_desc->privacy - */ - ) { + if (!priv->sec_info.wep_enabled && + !priv->sec_info.wpa_enabled && + priv->sec_info.wpa2_enabled && + ((bss_desc->bcn_rsn_ie) && + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) { + /* + * Privacy bit may NOT be set in some APs like + * LinkSys WRT54G && bss_desc->privacy + */ dev_dbg(priv->adapter->dev, "info: %s: WPA2: " " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " "EncMode=%#x privacy=%#x\n", __func__, @@ -299,16 +300,16 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && - !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || - ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id != WLAN_EID_RSN)) - && !priv->sec_info.encryption_mode - && bss_desc->privacy) { + !priv->sec_info.wpa2_enabled && + ((!bss_desc->bcn_wpa_ie) || + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && + !priv->sec_info.encryption_mode && bss_desc->privacy) { return true; } return false; @@ -319,16 +320,16 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, * is compatible with it. */ static bool -mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && - !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || - ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id != WLAN_EID_RSN)) - && priv->sec_info.encryption_mode - && bss_desc->privacy) { + !priv->sec_info.wpa2_enabled && + ((!bss_desc->bcn_wpa_ie) || + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && + priv->sec_info.encryption_mode && bss_desc->privacy) { dev_dbg(priv->adapter->dev, "info: %s: dynamic " "WEP: wpa_ie=%#x wpa2_ie=%#x " "EncMode=%#x privacy=%#x\n", @@ -373,8 +374,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, bss_desc->disable_11n = false; /* Don't check for compatibility if roaming */ - if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION) - && (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) + if (priv->media_connected && + (priv->bss_mode == NL80211_IFTYPE_STATION) && + (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) return 0; if (priv->wps.session_enable) { @@ -383,32 +385,30 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, return 0; } - if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) { + if (mwifiex_is_bss_wapi(priv, bss_desc)) { dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); return 0; } if (bss_desc->bss_mode == mode) { - if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) { + if (mwifiex_is_bss_no_sec(priv, bss_desc)) { /* No security */ return 0; - } else if (mwifiex_is_network_compatible_for_static_wep(priv, - bss_desc)) { + } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) { /* Static WEP enabled */ dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); bss_desc->disable_11n = true; return 0; - } else if (mwifiex_is_network_compatible_for_wpa(priv, - bss_desc)) { + } else if (mwifiex_is_bss_wpa(priv, bss_desc)) { /* WPA enabled */ - if (((priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && bss_desc->bcn_ht_cap) - && !mwifiex_is_wpa_oui_present(bss_desc, - CIPHER_SUITE_CCMP)) { - - if (mwifiex_is_wpa_oui_present(bss_desc, - CIPHER_SUITE_TKIP)) { + if (((priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + bss_desc->bcn_ht_cap) && + !mwifiex_is_wpa_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_wpa_oui_present + (bss_desc, CIPHER_SUITE_TKIP)) { dev_dbg(adapter->dev, "info: Disable 11n if AES " "is not supported by AP\n"); @@ -418,17 +418,16 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, } } return 0; - } else if (mwifiex_is_network_compatible_for_wpa2(priv, - bss_desc)) { + } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) { /* WPA2 enabled */ - if (((priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && bss_desc->bcn_ht_cap) - && !mwifiex_is_rsn_oui_present(bss_desc, - CIPHER_SUITE_CCMP)) { - - if (mwifiex_is_rsn_oui_present(bss_desc, - CIPHER_SUITE_TKIP)) { + if (((priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + bss_desc->bcn_ht_cap) && + !mwifiex_is_rsn_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_rsn_oui_present + (bss_desc, CIPHER_SUITE_TKIP)) { dev_dbg(adapter->dev, "info: Disable 11n if AES " "is not supported by AP\n"); @@ -438,31 +437,26 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, } } return 0; - } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv, - bss_desc)) { + } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) { /* Ad-hoc AES enabled */ return 0; - } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv, - bss_desc)) { + } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) { /* Dynamic WEP enabled */ return 0; } /* Security doesn't match */ - dev_dbg(adapter->dev, "info: %s: failed: " - "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode" - "=%#x privacy=%#x\n", - __func__, - (bss_desc->bcn_wpa_ie) ? - (*(bss_desc->bcn_wpa_ie)).vend_hdr. - element_id : 0, - (bss_desc->bcn_rsn_ie) ? - (*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id : 0, - (priv->sec_info.wep_enabled) ? "e" : "d", - (priv->sec_info.wpa_enabled) ? "e" : "d", - (priv->sec_info.wpa2_enabled) ? "e" : "d", - priv->sec_info.encryption_mode, bss_desc->privacy); + dev_dbg(adapter->dev, + "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s " + "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__, + (bss_desc->bcn_wpa_ie) ? + (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0, + (bss_desc->bcn_rsn_ie) ? + (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0, + (priv->sec_info.wep_enabled) ? "e" : "d", + (priv->sec_info.wpa_enabled) ? "e" : "d", + (priv->sec_info.wpa2_enabled) ? "e" : "d", + priv->sec_info.encryption_mode, bss_desc->privacy); return -1; } @@ -479,11 +473,11 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, */ static void mwifiex_scan_create_channel_list(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg - *user_scan_in, - struct mwifiex_chan_scan_param_set - *scan_chan_list, - u8 filtered_scan) + const struct mwifiex_user_scan_cfg + *user_scan_in, + struct mwifiex_chan_scan_param_set + *scan_chan_list, + u8 filtered_scan) { enum ieee80211_band band; struct ieee80211_supported_band *sband; @@ -505,7 +499,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, scan_chan_list[chan_idx].radio_type = band; if (user_scan_in && - user_scan_in->chan_list[0].scan_time) + user_scan_in->chan_list[0].scan_time) scan_chan_list[chan_idx].max_scan_time = cpu_to_le16((u16) user_scan_in-> chan_list[0].scan_time); @@ -594,19 +588,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, * - done_early is set (controlling individual scanning of * 1,6,11) */ - while (tlv_idx < max_chan_per_scan - && tmp_chan_list->chan_number && !done_early) { + while (tlv_idx < max_chan_per_scan && + tmp_chan_list->chan_number && !done_early) { dev_dbg(priv->adapter->dev, "info: Scan: Chan(%3d), Radio(%d)," " Mode(%d, %d), Dur(%d)\n", - tmp_chan_list->chan_number, - tmp_chan_list->radio_type, - tmp_chan_list->chan_scan_mode_bitmap - & MWIFIEX_PASSIVE_SCAN, - (tmp_chan_list->chan_scan_mode_bitmap - & MWIFIEX_DISABLE_CHAN_FILT) >> 1, - le16_to_cpu(tmp_chan_list->max_scan_time)); + tmp_chan_list->chan_number, + tmp_chan_list->radio_type, + tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_PASSIVE_SCAN, + (tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_DISABLE_CHAN_FILT) >> 1, + le16_to_cpu(tmp_chan_list->max_scan_time)); /* Copy the current channel TLV to the command being prepared */ @@ -648,9 +642,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, /* Stop the loop if the *current* channel is in the 1,6,11 set and we are not filtering on a BSSID or SSID. */ - if (!filtered_scan && (tmp_chan_list->chan_number == 1 - || tmp_chan_list->chan_number == 6 - || tmp_chan_list->chan_number == 11)) + if (!filtered_scan && + (tmp_chan_list->chan_number == 1 || + tmp_chan_list->chan_number == 6 || + tmp_chan_list->chan_number == 11)) done_early = true; /* Increment the tmp pointer to the next channel to @@ -660,9 +655,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, /* Stop the loop if the *next* channel is in the 1,6,11 set. This will cause it to be the only channel scanned on the next interation */ - if (!filtered_scan && (tmp_chan_list->chan_number == 1 - || tmp_chan_list->chan_number == 6 - || tmp_chan_list->chan_number == 11)) + if (!filtered_scan && + (tmp_chan_list->chan_number == 1 || + tmp_chan_list->chan_number == 6 || + tmp_chan_list->chan_number == 11)) done_early = true; } @@ -714,15 +710,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, * If the number of probes is not set, adapter default setting is used. */ static void -mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg *user_scan_in, - struct mwifiex_scan_cmd_config *scan_cfg_out, - struct mwifiex_ie_types_chan_list_param_set - **chan_list_out, - struct mwifiex_chan_scan_param_set - *scan_chan_list, - u8 *max_chan_per_scan, u8 *filtered_scan, - u8 *scan_current_only) +mwifiex_config_scan(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in, + struct mwifiex_scan_cmd_config *scan_cfg_out, + struct mwifiex_ie_types_chan_list_param_set **chan_list_out, + struct mwifiex_chan_scan_param_set *scan_chan_list, + u8 *max_chan_per_scan, u8 *filtered_scan, + u8 *scan_current_only) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_ie_types_num_probes *num_probes_tlv; @@ -840,9 +834,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, * truncate scan results. That is not an issue with an SSID * or BSSID filter applied to the scan results in the firmware. */ - if ((i && ssid_filter) - || memcmp(scan_cfg_out->specific_bssid, &zero_mac, - sizeof(zero_mac))) + if ((i && ssid_filter) || + memcmp(scan_cfg_out->specific_bssid, &zero_mac, + sizeof(zero_mac))) *filtered_scan = true; } else { scan_cfg_out->bss_mode = (u8) adapter->scan_mode; @@ -863,7 +857,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, if (num_probes) { dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", - num_probes); + num_probes); num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); @@ -889,9 +883,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size); - if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) { + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN)) { ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); @@ -920,8 +914,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); for (chan_idx = 0; - chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX - && user_scan_in->chan_list[chan_idx].chan_number; + chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX && + user_scan_in->chan_list[chan_idx].chan_number; chan_idx++) { channel = user_scan_in->chan_list[chan_idx].chan_number; @@ -961,9 +955,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, } /* Check if we are only scanning the current channel */ - if ((chan_idx == 1) - && (user_scan_in->chan_list[0].chan_number - == priv->curr_bss_params.bss_descriptor.channel)) { + if ((chan_idx == 1) && + (user_scan_in->chan_list[0].chan_number == + priv->curr_bss_params.bss_descriptor.channel)) { *scan_current_only = true; dev_dbg(adapter->dev, "info: Scan: Scanning current channel only\n"); @@ -971,7 +965,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, } else { dev_dbg(adapter->dev, - "info: Scan: Creating full region channel list\n"); + "info: Scan: Creating full region channel list\n"); mwifiex_scan_create_channel_list(priv, user_scan_in, scan_chan_list, *filtered_scan); @@ -1003,7 +997,7 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, *tlv_data = NULL; dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n", - tlv_buf_size); + tlv_buf_size); while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { @@ -1100,8 +1094,9 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->ssid.ssid_len = element_len; memcpy(bss_entry->ssid.ssid, (current_ptr + 2), element_len); - dev_dbg(adapter->dev, "info: InterpretIE: ssid: " - "%-32s\n", bss_entry->ssid.ssid); + dev_dbg(adapter->dev, + "info: InterpretIE: ssid: %-32s\n", + bss_entry->ssid.ssid); break; case WLAN_EID_SUPP_RATES: @@ -1189,13 +1184,13 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->bcn_wpa_ie = (struct ieee_types_vendor_specific *) current_ptr; - bss_entry->wpa_offset = (u16) (current_ptr - - bss_entry->beacon_buf); + bss_entry->wpa_offset = (u16) + (current_ptr - bss_entry->beacon_buf); } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, sizeof(wmm_oui))) { if (total_ie_len == - sizeof(struct ieee_types_wmm_parameter) - || total_ie_len == + sizeof(struct ieee_types_wmm_parameter) || + total_ie_len == sizeof(struct ieee_types_wmm_info)) /* * Only accept and copy the WMM IE if @@ -1316,14 +1311,14 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, } scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), - GFP_KERNEL); + GFP_KERNEL); if (!scan_cfg_out) { dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); return -ENOMEM; } buf_size = sizeof(struct mwifiex_chan_scan_param_set) * - MWIFIEX_USER_SCAN_CHAN_MAX; + MWIFIEX_USER_SCAN_CHAN_MAX; scan_chan_list = kzalloc(buf_size, GFP_KERNEL); if (!scan_chan_list) { dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); @@ -1331,10 +1326,9 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, return -ENOMEM; } - mwifiex_scan_setup_scan_config(priv, user_scan_in, - &scan_cfg_out->config, &chan_list_out, - scan_chan_list, &max_chan_per_scan, - &filtered_scan, &scan_current_chan_only); + mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config, + &chan_list_out, scan_chan_list, &max_chan_per_scan, + &filtered_scan, &scan_current_chan_only); ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, &scan_cfg_out->config, chan_list_out, @@ -1345,10 +1339,10 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); if (!list_empty(&adapter->scan_pending_q)) { cmd_node = list_first_entry(&adapter->scan_pending_q, - struct cmd_ctrl_node, list); + struct cmd_ctrl_node, list); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - flags); + flags); adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); @@ -1434,8 +1428,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv, if (!bss_desc) return -1; - if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - (u8) bss_desc->bss_band, (u16) bss_desc->channel))) { + if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band, + (u16) bss_desc->channel, 0))) { switch (priv->bss_mode) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: @@ -1514,7 +1508,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, - sizeof(priv->curr_bss_params.bss_descriptor)); + sizeof(priv->curr_bss_params.bss_descriptor)); mwifiex_save_curr_bcn(priv); spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); @@ -1565,7 +1559,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, struct cfg80211_bss *bss; is_bgscan_resp = (le16_to_cpu(resp->command) - == HostCmd_CMD_802_11_BG_SCAN_QUERY); + == HostCmd_CMD_802_11_BG_SCAN_QUERY); if (is_bgscan_resp) scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; else @@ -1574,20 +1568,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) { dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", - scan_rsp->number_of_sets); + scan_rsp->number_of_sets); ret = -1; goto done; } bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n", - bytes_left); + bytes_left); scan_resp_size = le16_to_cpu(resp->size); dev_dbg(adapter->dev, "info: SCAN_RESP: returned %d APs before parsing\n", - scan_rsp->number_of_sets); + scan_rsp->number_of_sets); bss_info = scan_rsp->bss_desc_and_tlv_buffer; @@ -1625,7 +1619,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, s32 rssi; const u8 *ie_buf; size_t ie_len; - int channel = -1; + u16 channel = 0; u64 network_tsf = 0; u16 beacon_size = 0; u32 curr_bcn_bytes; @@ -1663,7 +1657,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, * and capability information */ if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) { - dev_err(adapter->dev, "InterpretIE: not enough bytes left\n"); + dev_err(adapter->dev, + "InterpretIE: not enough bytes left\n"); continue; } bcn_param = (struct mwifiex_bcn_param *)current_ptr; @@ -1673,20 +1668,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, memcpy(bssid, bcn_param->bssid, ETH_ALEN); rssi = (s32) (bcn_param->rssi); - dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", - rssi); + dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", rssi); beacon_period = le16_to_cpu(bcn_param->beacon_period); cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", - cap_info_bitmap); + cap_info_bitmap); /* Rest of the current buffer are IE's */ ie_buf = current_ptr; ie_len = curr_bcn_bytes; - dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP" - " = %d\n", curr_bcn_bytes); + dev_dbg(adapter->dev, + "info: InterpretIE: IELength for this AP = %d\n", + curr_bcn_bytes); while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { u8 element_id, element_len; @@ -1695,8 +1690,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, element_len = *(current_ptr + 1); if (curr_bcn_bytes < element_len + sizeof(struct ieee_types_header)) { - dev_err(priv->adapter->dev, "%s: in processing" - " IE, bytes left < IE length\n", + dev_err(priv->adapter->dev, + "%s: bytes left < IE length\n", __func__); goto done; } @@ -1720,10 +1715,10 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, */ if (tsf_tlv) memcpy(&network_tsf, - &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], - sizeof(network_tsf)); + &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], + sizeof(network_tsf)); - if (channel != -1) { + if (channel) { struct ieee80211_channel *chan; u8 band; @@ -1736,8 +1731,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, & (BIT(0) | BIT(1))); } - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211( - priv, (u8)band, (u16)channel); + cfp = mwifiex_get_cfp(priv, band, channel, 0); freq = cfp ? cfp->freq : 0; @@ -1751,13 +1745,15 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, *(u8 *)bss->priv = band; cfg80211_put_bss(bss); - if (priv->media_connected && !memcmp(bssid, - priv->curr_bss_params.bss_descriptor - .mac_address, ETH_ALEN)) - mwifiex_update_curr_bss_params(priv, - bssid, rssi, ie_buf, - ie_len, beacon_period, - cap_info_bitmap, band); + if (priv->media_connected && + !memcmp(bssid, + priv->curr_bss_params.bss_descriptor + .mac_address, ETH_ALEN)) + mwifiex_update_curr_bss_params + (priv, bssid, rssi, + ie_buf, ie_len, + beacon_period, + cap_info_bitmap, band); } } else { dev_dbg(adapter->dev, "missing BSS channel IE\n"); @@ -1784,8 +1780,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, } if (priv->user_scan_cfg) { - dev_dbg(priv->adapter->dev, "info: %s: sending scan " - "results\n", __func__); + dev_dbg(priv->adapter->dev, + "info: %s: sending scan results\n", __func__); cfg80211_scan_done(priv->scan_request, 0); priv->scan_request = NULL; kfree(priv->user_scan_cfg); @@ -1901,7 +1897,7 @@ int mwifiex_request_scan(struct mwifiex_private *priv, if (down_interruptible(&priv->async_sem)) { dev_err(priv->adapter->dev, "%s: acquire semaphore\n", - __func__); + __func__); return -1; } priv->scan_pending_on_block = true; @@ -1986,21 +1982,21 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) /* allocate beacon buffer at 1st time; or if it's size has changed */ if (!priv->curr_bcn_buf || - priv->curr_bcn_size != curr_bss->beacon_buf_size) { + priv->curr_bcn_size != curr_bss->beacon_buf_size) { priv->curr_bcn_size = curr_bss->beacon_buf_size; kfree(priv->curr_bcn_buf); priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, - GFP_ATOMIC); + GFP_ATOMIC); if (!priv->curr_bcn_buf) { dev_err(priv->adapter->dev, - "failed to alloc curr_bcn_buf\n"); + "failed to alloc curr_bcn_buf\n"); return; } } memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, - curr_bss->beacon_buf_size); + curr_bss->beacon_buf_size); dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", priv->curr_bcn_size); diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 835902750231..f8012e2b7f7c 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -67,7 +67,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) struct sdio_mmc_card *card = NULL; pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", - func->vendor, func->device, func->class, func->num); + func->vendor, func->device, func->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); if (!card) @@ -110,6 +110,7 @@ mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; + struct mwifiex_private *priv; int i; pr_debug("info: SDIO func num=%d\n", func->num); @@ -129,15 +130,12 @@ mwifiex_sdio_remove(struct sdio_func *func) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) + adapter->priv[i]->media_connected) mwifiex_deauthenticate(adapter->priv[i], NULL); - mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY)); - - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + mwifiex_disable_auto_ds(priv); + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); @@ -167,7 +165,7 @@ static int mwifiex_sdio_suspend(struct device *dev) if (func) { pm_flag = sdio_get_host_pm_caps(func); pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", - sdio_func_id(func), pm_flag); + sdio_func_id(func), pm_flag); if (!(pm_flag & MMC_PM_KEEP_POWER)) { pr_err("%s: cannot remain alive while host is" " suspended\n", sdio_func_id(func)); @@ -361,12 +359,11 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, { struct sdio_mmc_card *card = adapter->card; int ret = -1; - u8 blk_mode = - (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; + u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE + : BLOCK_MODE; u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; - u32 blk_cnt = - (blk_mode == - BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len; + u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) + : len; u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); if (claim) @@ -470,8 +467,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, i++; dev_err(adapter->dev, "host_to_card, write iomem" " (%d) failed: %d\n", i, ret); - if (mwifiex_write_reg(adapter, - CONFIGURATION_REG, 0x04)) + if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) dev_err(adapter->dev, "write CFG reg failed\n"); ret = -1; @@ -505,11 +501,11 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); *port = CTRL_PORT; dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", - *port, card->mp_rd_bitmap); + *port, card->mp_rd_bitmap); } else { if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { - card->mp_rd_bitmap &= - (u16) (~(1 << card->curr_rd_port)); + card->mp_rd_bitmap &= (u16) + (~(1 << card->curr_rd_port)); *port = card->curr_rd_port; if (++card->curr_rd_port == MAX_PORT) @@ -520,7 +516,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", - *port, rd_bitmap, card->mp_rd_bitmap); + *port, rd_bitmap, card->mp_rd_bitmap); } return 0; } @@ -554,14 +550,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) if (*port == CTRL_PORT) { dev_err(adapter->dev, "invalid data port=%d cur port=%d" - " mp_wr_bitmap=0x%04x -> 0x%04x\n", - *port, card->curr_wr_port, wr_bitmap, - card->mp_wr_bitmap); + " mp_wr_bitmap=0x%04x -> 0x%04x\n", + *port, card->curr_wr_port, wr_bitmap, + card->mp_wr_bitmap); return -1; } dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", - *port, wr_bitmap, card->mp_wr_bitmap); + *port, wr_bitmap, card->mp_wr_bitmap); return 0; } @@ -581,11 +577,11 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) else if ((cs & bits) == bits) return 0; - udelay(10); + usleep_range(10, 20); } - dev_err(adapter->dev, "poll card status failed, tries = %d\n", - tries); + dev_err(adapter->dev, "poll card status failed, tries = %d\n", tries); + return -1; } @@ -668,14 +664,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, if (ret) { dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, - ret); + ret); return -1; } nb = le16_to_cpu(*(__le16 *) (buffer)); if (nb > npayload) { - dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n", - __func__, nb, npayload); + dev_err(adapter->dev, "%s: invalid packet, nb=%d npayload=%d\n", + __func__, nb, npayload); return -1; } @@ -705,19 +701,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, u32 i = 0; if (!firmware_len) { - dev_err(adapter->dev, "firmware image not found!" - " Terminating download\n"); + dev_err(adapter->dev, + "firmware image not found! Terminating download\n"); return -1; } dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", - firmware_len); + firmware_len); /* Assume that the allocated buffer is 8-byte aligned */ fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); if (!fwbuf) { - dev_err(adapter->dev, "unable to alloc buffer for firmware." - " Terminating download\n"); + dev_err(adapter->dev, + "unable to alloc buffer for FW. Terminating dnld\n"); return -ENOMEM; } @@ -729,7 +725,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, DN_LD_CARD_RDY); if (ret) { dev_err(adapter->dev, "FW download with helper:" - " poll status timeout @ %d\n", offset); + " poll status timeout @ %d\n", offset); goto done; } @@ -741,17 +737,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, &base0); if (ret) { - dev_err(adapter->dev, "dev BASE0 register read" - " failed: base0=0x%04X(%d). Terminating " - "download\n", base0, base0); + dev_err(adapter->dev, + "dev BASE0 register read failed: " + "base0=%#04X(%d). Terminating dnld\n", + base0, base0); goto done; } ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, &base1); if (ret) { - dev_err(adapter->dev, "dev BASE1 register read" - " failed: base1=0x%04X(%d). Terminating " - "download\n", base1, base1); + dev_err(adapter->dev, + "dev BASE1 register read failed: " + "base1=%#04X(%d). Terminating dnld\n", + base1, base1); goto done; } len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); @@ -759,14 +757,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (len) break; - udelay(10); + usleep_range(10, 20); } if (!len) { break; } else if (len > MWIFIEX_UPLD_SIZE) { - dev_err(adapter->dev, "FW download failed @ %d," - " invalid length %d\n", offset, len); + dev_err(adapter->dev, + "FW dnld failed @ %d, invalid length %d\n", + offset, len); ret = -1; goto done; } @@ -776,13 +775,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (len & BIT(0)) { i++; if (i > MAX_WRITE_IOMEM_RETRY) { - dev_err(adapter->dev, "FW download failed @" - " %d, over max retry count\n", offset); + dev_err(adapter->dev, + "FW dnld failed @ %d, over max retry\n", + offset); ret = -1; goto done; } dev_err(adapter->dev, "CRC indicated by the helper:" - " len = 0x%04X, txlen = %d\n", len, txlen); + " len = 0x%04X, txlen = %d\n", len, txlen); len &= ~BIT(0); /* Setting this to 0 to resend from same offset */ txlen = 0; @@ -794,8 +794,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (firmware_len - offset < txlen) txlen = firmware_len - offset; - tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - - 1) / MWIFIEX_SDIO_BLOCK_SIZE; + tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1) + / MWIFIEX_SDIO_BLOCK_SIZE; /* Copy payload to buffer */ memmove(fwbuf, &firmware[offset], txlen); @@ -805,8 +805,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, MWIFIEX_SDIO_BLOCK_SIZE, adapter->ioport); if (ret) { - dev_err(adapter->dev, "FW download, write iomem (%d)" - " failed @ %d\n", i, offset); + dev_err(adapter->dev, + "FW download, write iomem (%d) failed @ %d\n", + i, offset); if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) dev_err(adapter->dev, "write CFG reg failed\n"); @@ -818,7 +819,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } while (true); dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", - offset); + offset); ret = 0; done: @@ -910,7 +911,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) card = sdio_get_drvdata(func); if (!card || !card->adapter) { pr_debug("int: func=%p card=%p adapter=%p\n", - func, card, card ? card->adapter : NULL); + func, card, card ? card->adapter : NULL); return; } adapter = card->adapter; @@ -953,10 +954,12 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, if (adapter->ps_state == PS_STATE_SLEEP_CFM) mwifiex_process_sleep_confirm_resp(adapter, - skb->data, skb->len); + skb->data, + skb->len); - memcpy(cmd_buf, skb->data, min_t(u32, - MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + memcpy(cmd_buf, skb->data, + min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, + skb->len)); dev_kfree_skb_any(skb); } else { @@ -1014,7 +1017,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (port == CTRL_PORT) { /* Read the command Resp without aggr */ dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " - "response\n", __func__); + "response\n", __func__); f_do_rx_cur = 1; goto rx_curr_single; @@ -1022,7 +1025,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (!card->mpa_rx.enabled) { dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", - __func__); + __func__); f_do_rx_cur = 1; goto rx_curr_single; @@ -1069,7 +1072,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { dev_dbg(adapter->dev, "info: %s: aggregated packet " - "limit reached\n", __func__); + "limit reached\n", __func__); /* No more pkts allowed in Aggr buf, rx it */ f_do_rx_aggr = 1; } @@ -1078,7 +1081,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (f_do_rx_aggr) { /* do aggr RX now */ dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", - card->mpa_rx.pkt_cnt); + card->mpa_rx.pkt_cnt); if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, card->mpa_rx.buf_len, @@ -1192,7 +1195,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", - card->mp_wr_bitmap); + card->mp_wr_bitmap); if (adapter->data_sent && (card->mp_wr_bitmap & card->mp_data_port_mask)) { dev_dbg(adapter->dev, @@ -1214,12 +1217,12 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) } dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", - adapter->cmd_sent, adapter->data_sent); + adapter->cmd_sent, adapter->data_sent); if (sdio_ireg & UP_LD_HOST_INT_STATUS) { card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", - card->mp_rd_bitmap); + card->mp_rd_bitmap); while (true) { ret = mwifiex_get_rd_port(adapter, &port); @@ -1233,15 +1236,15 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; rx_len |= (u16) card->mp_regs[len_reg_l]; dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", - port, rx_len); + port, rx_len); rx_blocks = (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - 1) / MWIFIEX_SDIO_BLOCK_SIZE; - if (rx_len <= INTF_HEADER_LEN - || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > - MWIFIEX_RX_DATA_BUF_SIZE) { + if (rx_len <= INTF_HEADER_LEN || + (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > + MWIFIEX_RX_DATA_BUF_SIZE) { dev_err(adapter->dev, "invalid rx_len=%d\n", - rx_len); + rx_len); return -1; } rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); @@ -1250,42 +1253,42 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (!skb) { dev_err(adapter->dev, "%s: failed to alloc skb", - __func__); + __func__); return -1; } skb_put(skb, rx_len); dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", - rx_len, skb->len); + rx_len, skb->len); if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, port)) { u32 cr = 0; dev_err(adapter->dev, "card_to_host_mpa failed:" - " int status=%#x\n", sdio_ireg); + " int status=%#x\n", sdio_ireg); if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) dev_err(adapter->dev, - "read CFG reg failed\n"); + "read CFG reg failed\n"); dev_dbg(adapter->dev, - "info: CFG reg val = %d\n", cr); + "info: CFG reg val = %d\n", cr); if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04))) dev_err(adapter->dev, - "write CFG reg failed\n"); + "write CFG reg failed\n"); dev_dbg(adapter->dev, "info: write success\n"); if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) dev_err(adapter->dev, - "read CFG reg failed\n"); + "read CFG reg failed\n"); dev_dbg(adapter->dev, - "info: CFG reg val =%x\n", cr); + "info: CFG reg val =%x\n", cr); return -1; } } @@ -1321,7 +1324,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", - __func__); + __func__); f_send_cur_buf = 1; goto tx_curr_single; @@ -1330,7 +1333,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (next_pkt_len) { /* More pkt in TX queue */ dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", - __func__); + __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && @@ -1338,9 +1341,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, f_precopy_cur_buf = 1; if (!(card->mp_wr_bitmap & - (1 << card->curr_wr_port)) - || !MP_TX_AGGR_BUF_HAS_ROOM( - card, pkt_len + next_pkt_len)) + (1 << card->curr_wr_port)) || + !MP_TX_AGGR_BUF_HAS_ROOM( + card, pkt_len + next_pkt_len)) f_send_aggr_buf = 1; } else { /* No room in Aggr buf, send it */ @@ -1354,8 +1357,8 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, f_postcopy_cur_buf = 1; } } else { - if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) - && (card->mp_wr_bitmap & (1 << card->curr_wr_port))) + if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) && + (card->mp_wr_bitmap & (1 << card->curr_wr_port))) f_precopy_cur_buf = 1; else f_send_cur_buf = 1; @@ -1363,7 +1366,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, } else { /* Last pkt in TX queue */ dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", - __func__); + __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { /* some packs in Aggr buf already */ @@ -1381,7 +1384,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (f_precopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", - __func__); + __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || @@ -1392,7 +1395,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (f_send_aggr_buf) { dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", - __func__, + __func__, card->mpa_tx.start_port, card->mpa_tx.ports); ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, card->mpa_tx.buf_len, @@ -1406,14 +1409,14 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, tx_curr_single: if (f_send_cur_buf) { dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", - __func__, port); + __func__, port); ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, adapter->ioport + port); } if (f_postcopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", - __func__); + __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); } @@ -1458,7 +1461,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, ret = mwifiex_get_wr_port_data(adapter, &port); if (ret) { dev_err(adapter->dev, "%s: no wr_port available\n", - __func__); + __func__); return ret; } } else { @@ -1468,7 +1471,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, if (pkt_len <= INTF_HEADER_LEN || pkt_len > MWIFIEX_UPLD_SIZE) dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", - __func__, payload, pkt_len); + __func__, payload, pkt_len); } /* Transfer data to card */ @@ -1476,10 +1479,11 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, if (tx_param) ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, - port, tx_param->next_pkt_len); + port, tx_param->next_pkt_len + ); else ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, - port, 0); + port, 0); if (ret) { if (type == MWIFIEX_TYPE_CMD) @@ -1732,7 +1736,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) card->curr_wr_port = 1; dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", - port, card->mp_data_port_mask); + port, card->mp_data_port_mask); } static struct mwifiex_if_ops sdio_ops = { diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 324c651527cb..6c8e4594b48b 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -110,7 +110,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) - - 1 + S_DS_GEN); + - 1 + S_DS_GEN); snmp_mib->oid = cpu_to_le16((u16)cmd_oid); if (cmd_action == HostCmd_ACT_GEN_GET) { @@ -127,8 +127,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," " Value=0x%x\n", - cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), - le16_to_cpu(*(__le16 *) snmp_mib->value)); + cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), + le16_to_cpu(*(__le16 *) snmp_mib->value)); return 0; } @@ -174,8 +174,8 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg + sizeof(struct host_cmd_ds_tx_rate_cfg)); rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE); - rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) - - sizeof(struct mwifiex_ie_types_header)); + rate_scope->length = cpu_to_le16 + (sizeof(*rate_scope) - sizeof(struct mwifiex_ie_types_header)); if (pbitmap_rates != NULL) { rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]); rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]); @@ -197,7 +197,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, } rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + - sizeof(struct mwifiex_rate_scope)); + sizeof(struct mwifiex_rate_scope)); rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL); rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode)); rate_drop->rate_drop_mode = 0; @@ -284,22 +284,22 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); if (!hs_activate && - (hscfg_param->conditions - != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) - && ((adapter->arp_filter_size > 0) - && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { + (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && + ((adapter->arp_filter_size > 0) && + (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { dev_dbg(adapter->dev, "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n", - adapter->arp_filter_size); + adapter->arp_filter_size); memcpy(((u8 *) hs_cfg) + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh), adapter->arp_filter, adapter->arp_filter_size); - cmd->size = cpu_to_le16(adapter->arp_filter_size + - sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) - + S_DS_GEN); + cmd->size = cpu_to_le16 + (adapter->arp_filter_size + + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) + + S_DS_GEN); } else { cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct - host_cmd_ds_802_11_hs_cfg_enh)); + host_cmd_ds_802_11_hs_cfg_enh)); } if (hs_activate) { hs_cfg->action = cpu_to_le16(HS_ACTIVATE); @@ -467,7 +467,7 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, key_param_set = (struct mwifiex_ie_type_key_param_set *) ((u8 *)key_param_set + - cur_key_param_len); + cur_key_param_len); } else if (!priv->wep_key[i].key_length) { continue; } else { @@ -527,13 +527,13 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, if (enc_key->is_wapi_key) { dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_WAPI); + cpu_to_le16(KEY_TYPE_ID_WAPI); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_ENABLED); + cpu_to_le16(!KEY_ENABLED); key_material->key_param_set.key[0] = enc_key->key_index; if (!priv->sec_info.wapi_key_on) @@ -553,9 +553,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, } key_material->key_param_set.type = - cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); key_material->key_param_set.key_len = - cpu_to_le16(WAPI_KEY_LEN); + cpu_to_le16(WAPI_KEY_LEN); memcpy(&key_material->key_param_set.key[2], enc_key->key_material, enc_key->key_len); memcpy(&key_material->key_param_set.key[2 + enc_key->key_len], @@ -565,49 +565,49 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) + sizeof(struct mwifiex_ie_types_header); - cmd->size = cpu_to_le16(key_param_len + - sizeof(key_material->action) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(key_material->action) + + S_DS_GEN + key_param_len); return ret; } if (enc_key->key_len == WLAN_KEY_LEN_CCMP) { dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_AES); + cpu_to_le16(KEY_TYPE_ID_AES); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_ENABLED); + cpu_to_le16(!KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* AES pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* AES group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_MCAST); + cpu_to_le16(KEY_MCAST); } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_TKIP); + cpu_to_le16(KEY_TYPE_ID_TKIP); key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* TKIP pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* TKIP group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_MCAST); + cpu_to_le16(KEY_MCAST); } if (key_material->key_param_set.key_type_id) { key_material->key_param_set.type = - cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); key_material->key_param_set.key_len = - cpu_to_le16((u16) enc_key->key_len); + cpu_to_le16((u16) enc_key->key_len); memcpy(key_material->key_param_set.key, enc_key->key_material, enc_key->key_len); key_material->key_param_set.length = @@ -615,10 +615,10 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, KEYPARAMSET_FIXED_LEN); key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) - + sizeof(struct mwifiex_ie_types_header); + + sizeof(struct mwifiex_ie_types_header); - cmd->size = cpu_to_le16(key_param_len + - sizeof(key_material->action) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN + + key_param_len); } return ret; @@ -655,21 +655,22 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, /* Set domain info fields */ domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY); memcpy(domain->country_code, adapter->domain_reg.country_code, - sizeof(domain->country_code)); + sizeof(domain->country_code)); - domain->header.len = cpu_to_le16((no_of_triplet * - sizeof(struct ieee80211_country_ie_triplet)) + - sizeof(domain->country_code)); + domain->header.len = + cpu_to_le16((no_of_triplet * + sizeof(struct ieee80211_country_ie_triplet)) + + sizeof(domain->country_code)); if (no_of_triplet) { memcpy(domain->triplet, adapter->domain_reg.triplet, - no_of_triplet * - sizeof(struct ieee80211_country_ie_triplet)); + no_of_triplet * sizeof(struct + ieee80211_country_ie_triplet)); cmd->size = cpu_to_le16(sizeof(domain_info->action) + - le16_to_cpu(domain->header.len) + - sizeof(struct mwifiex_ie_types_header) - + S_DS_GEN); + le16_to_cpu(domain->header.len) + + sizeof(struct mwifiex_ie_types_header) + + S_DS_GEN); } else { cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN); } @@ -698,8 +699,8 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, + S_DS_GEN); if (cmd_action == HostCmd_ACT_GEN_SET) { - if ((priv->adapter->adhoc_start_band & BAND_A) - || (priv->adapter->adhoc_start_band & BAND_AN)) + if ((priv->adapter->adhoc_start_band & BAND_A) || + (priv->adapter->adhoc_start_band & BAND_AN)) rf_chan->rf_type = cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); @@ -777,7 +778,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> - params.mac_reg; + params.mac_reg; mac_reg->action = cpu_to_le16(cmd_action); mac_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -789,8 +790,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_bbp_reg_access *bbp_reg; cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); - bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd-> - params.bbp_reg; + bbp_reg = (struct host_cmd_ds_bbp_reg_access *) + &cmd->params.bbp_reg; bbp_reg->action = cpu_to_le16(cmd_action); bbp_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -802,11 +803,10 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *rf_reg; cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); - rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> - params.rf_reg; + rf_reg = (struct host_cmd_ds_rf_reg_access *) + &cmd->params.rf_reg; rf_reg->action = cpu_to_le16(cmd_action); - rf_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); rf_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -819,7 +819,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, params.pmic_reg; pmic_reg->action = cpu_to_le16(cmd_action); pmic_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -828,11 +828,11 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *cau_reg; cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); - cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> - params.rf_reg; + cau_reg = (struct host_cmd_ds_rf_reg_access *) + &cmd->params.rf_reg; cau_reg->action = cpu_to_le16(cmd_action); cau_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); cau_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -868,7 +868,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, */ static int mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, u16 action) + struct host_cmd_ds_command *cmd, u16 action) { struct host_cmd_ds_pcie_details *host_spec = &cmd->params.pcie_host_spec; @@ -882,29 +882,25 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details)); - if (action == HostCmd_ACT_GEN_SET) { - /* Send the ring base addresses and count to firmware */ - host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); - host_spec->txbd_addr_hi = - (u32)(((u64)card->txbd_ring_pbase)>>32); - host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; - host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); - host_spec->rxbd_addr_hi = - (u32)(((u64)card->rxbd_ring_pbase)>>32); - host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; - host_spec->evtbd_addr_lo = - (u32)(card->evtbd_ring_pbase); - host_spec->evtbd_addr_hi = - (u32)(((u64)card->evtbd_ring_pbase)>>32); - host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; - if (card->sleep_cookie) { - buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); - host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; - host_spec->sleep_cookie_addr_hi = - (u32) (((u64)*buf_pa) >> 32); - dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: " - "0x%x\n", host_spec->sleep_cookie_addr_lo); - } + if (action != HostCmd_ACT_GEN_SET) + return 0; + + /* Send the ring base addresses and count to firmware */ + host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); + host_spec->txbd_addr_hi = (u32)(((u64)card->txbd_ring_pbase)>>32); + host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; + host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); + host_spec->rxbd_addr_hi = (u32)(((u64)card->rxbd_ring_pbase)>>32); + host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; + host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase); + host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32); + host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; + if (card->sleep_cookie) { + buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); + host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; + host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32); + dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n", + host_spec->sleep_cookie_addr_lo); } return 0; @@ -1036,12 +1032,12 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, break; case HostCmd_CMD_802_11_KEY_MATERIAL: ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr, - cmd_action, cmd_oid, - data_buf); + cmd_action, cmd_oid, + data_buf); break; case HostCmd_CMD_802_11D_DOMAIN_INFO: ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr, - cmd_action); + cmd_action); break; case HostCmd_CMD_RECONFIGURE_TX_BUFF: ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action, @@ -1052,8 +1048,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, - data_buf); + ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: dev_dbg(priv->adapter->dev, @@ -1131,8 +1126,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (first_sta) { if (priv->adapter->iface_type == MWIFIEX_PCIE) { ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_PCIE_DESC_DETAILS, - HostCmd_ACT_GEN_SET, 0, NULL); + HostCmd_CMD_PCIE_DESC_DETAILS, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) return -1; } diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 0d8618a8443f..4da19ed0f078 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -49,7 +49,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, unsigned long flags; dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", - resp->command, resp->result); + resp->command, resp->result); if (adapter->curr_cmd->wait_q_enabled) adapter->cmd_wait_q.status = -1; @@ -57,13 +57,13 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, switch (le16_to_cpu(resp->command)) { case HostCmd_CMD_802_11_PS_MODE_ENH: pm = &resp->params.psmode_enh; - dev_err(adapter->dev, "PS_MODE_ENH cmd failed: " - "result=0x%x action=0x%X\n", - resp->result, le16_to_cpu(pm->action)); + dev_err(adapter->dev, + "PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n", + resp->result, le16_to_cpu(pm->action)); /* We do not re-try enter-ps command in ad-hoc mode. */ if (le16_to_cpu(pm->action) == EN_AUTO_PS && - (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && - priv->bss_mode == NL80211_IFTYPE_ADHOC) + (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && + priv->bss_mode == NL80211_IFTYPE_ADHOC) adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; break; @@ -123,7 +123,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, struct mwifiex_ds_get_signal *signal) { struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = - &resp->params.rssi_info_rsp; + &resp->params.rssi_info_rsp; priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); @@ -191,8 +191,8 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, u32 ul_temp; dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," - " query_type = %#x, buf size = %#x\n", - oid, query_type, le16_to_cpu(smib->buf_size)); + " query_type = %#x, buf size = %#x\n", + oid, query_type, le16_to_cpu(smib->buf_size)); if (query_type == HostCmd_ACT_GEN_GET) { ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); if (data_buf) @@ -327,31 +327,26 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, HostCmd_CMD_802_11_TX_RATE_QUERY, HostCmd_ACT_GEN_GET, 0, NULL); - if (ds_rate) { - if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { - if (priv->is_data_rate_auto) { - ds_rate->is_rate_auto = 1; - } else { - ds_rate->rate = mwifiex_get_rate_index(priv-> - bitmap_rates, - sizeof(priv-> - bitmap_rates)); - if (ds_rate->rate >= - MWIFIEX_RATE_BITMAP_OFDM0 - && ds_rate->rate <= - MWIFIEX_RATE_BITMAP_OFDM7) - ds_rate->rate -= - (MWIFIEX_RATE_BITMAP_OFDM0 - - MWIFIEX_RATE_INDEX_OFDM0); - if (ds_rate->rate >= - MWIFIEX_RATE_BITMAP_MCS0 - && ds_rate->rate <= - MWIFIEX_RATE_BITMAP_MCS127) - ds_rate->rate -= - (MWIFIEX_RATE_BITMAP_MCS0 - - MWIFIEX_RATE_INDEX_MCS0); - } - } + if (!ds_rate) + return ret; + + if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { + if (priv->is_data_rate_auto) { + ds_rate->is_rate_auto = 1; + return ret; + } + ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates, + sizeof(priv->bitmap_rates)); + + if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 && + ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7) + ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 - + MWIFIEX_RATE_INDEX_OFDM0); + + if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 && + ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127) + ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 - + MWIFIEX_RATE_INDEX_MCS0); } return ret; @@ -369,34 +364,32 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) struct mwifiex_types_power_group *pg_tlv_hdr; struct mwifiex_power_group *pg; - if (data_buf) { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) data_buf - + sizeof(struct host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + - sizeof(struct mwifiex_types_power_group)); - length = pg_tlv_hdr->length; - if (length > 0) { + if (!data_buf) + return -1; + + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg)); + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); + length = pg_tlv_hdr->length; + if (length > 0) { + max_power = pg->power_max; + min_power = pg->power_min; + length -= sizeof(struct mwifiex_power_group); + } + while (length) { + pg++; + if (max_power < pg->power_max) max_power = pg->power_max; - min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - } - while (length) { - pg++; - if (max_power < pg->power_max) - max_power = pg->power_max; - if (min_power > pg->power_min) - min_power = pg->power_min; + if (min_power > pg->power_min) + min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - } - if (pg_tlv_hdr->length > 0) { - priv->min_tx_power_level = (u8) min_power; - priv->max_tx_power_level = (u8) max_power; - } - } else { - return -1; + length -= sizeof(struct mwifiex_power_group); + } + if (pg_tlv_hdr->length > 0) { + priv->min_tx_power_level = (u8) min_power; + priv->max_tx_power_level = (u8) max_power; } return 0; @@ -420,42 +413,38 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, switch (action) { case HostCmd_ACT_GEN_GET: - { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) - txp_cfg + - sizeof - (struct - host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) - pg_tlv_hdr + - sizeof(struct - mwifiex_types_power_group)); - if (adapter->hw_status == - MWIFIEX_HW_STATUS_INITIALIZING) - mwifiex_get_power_level(priv, txp_cfg); - priv->tx_power_level = (u16) pg->power_min; - break; - } + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); + + if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) + mwifiex_get_power_level(priv, txp_cfg); + + priv->tx_power_level = (u16) pg->power_min; + break; + case HostCmd_ACT_GEN_SET: - if (le32_to_cpu(txp_cfg->mode)) { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) - txp_cfg + - sizeof - (struct - host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr - + - sizeof(struct - mwifiex_types_power_group)); - if (pg->power_max == pg->power_min) - priv->tx_power_level = (u16) pg->power_min; - } + if (!le32_to_cpu(txp_cfg->mode)) + break; + + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); + + if (pg->power_max == pg->power_min) + priv->tx_power_level = (u16) pg->power_min; break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n", - action); + action); return 0; } dev_dbg(adapter->dev, @@ -475,7 +464,7 @@ static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_mac_address *cmd_mac_addr = - &resp->params.mac_addr; + &resp->params.mac_addr; memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN); @@ -560,7 +549,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_key_material *key = - &resp->params.key_material; + &resp->params.key_material; if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { @@ -591,17 +580,18 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, u16 action = le16_to_cpu(domain_info->action); u8 no_of_triplet; - no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) - - IEEE80211_COUNTRY_STRING_LEN) / - sizeof(struct ieee80211_country_ie_triplet)); + no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) + - IEEE80211_COUNTRY_STRING_LEN) + / sizeof(struct ieee80211_country_ie_triplet)); - dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:" - " no_of_triplet=%d\n", no_of_triplet); + dev_dbg(priv->adapter->dev, + "info: 11D Domain Info Resp: no_of_triplet=%d\n", + no_of_triplet); if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) { dev_warn(priv->adapter->dev, - "11D: invalid number of triplets %d " - "returned!!\n", no_of_triplet); + "11D: invalid number of triplets %d returned\n", + no_of_triplet); return -1; } @@ -635,8 +625,8 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", - priv->curr_bss_params.bss_descriptor.channel, - new_channel); + priv->curr_bss_params.bss_descriptor.channel, + new_channel); /* Update the channel again */ priv->curr_bss_params.bss_descriptor.channel = new_channel; } @@ -679,90 +669,70 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, { struct mwifiex_ds_reg_rw *reg_rw; struct mwifiex_ds_read_eeprom *eeprom; + union reg { + struct host_cmd_ds_mac_reg_access *mac; + struct host_cmd_ds_bbp_reg_access *bbp; + struct host_cmd_ds_rf_reg_access *rf; + struct host_cmd_ds_pmic_reg_access *pmic; + struct host_cmd_ds_802_11_eeprom_access *eeprom; + } r; + + if (!data_buf) + return 0; - if (data_buf) { - reg_rw = data_buf; - eeprom = data_buf; - switch (type) { - case HostCmd_CMD_MAC_REG_ACCESS: - { - struct host_cmd_ds_mac_reg_access *reg; - reg = (struct host_cmd_ds_mac_reg_access *) - &resp->params.mac_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = reg->value; - break; - } - case HostCmd_CMD_BBP_REG_ACCESS: - { - struct host_cmd_ds_bbp_reg_access *reg; - reg = (struct host_cmd_ds_bbp_reg_access *) - &resp->params.bbp_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - - case HostCmd_CMD_RF_REG_ACCESS: - { - struct host_cmd_ds_rf_reg_access *reg; - reg = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_PMIC_REG_ACCESS: - { - struct host_cmd_ds_pmic_reg_access *reg; - reg = (struct host_cmd_ds_pmic_reg_access *) - &resp->params.pmic_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_CAU_REG_ACCESS: - { - struct host_cmd_ds_rf_reg_access *reg; - reg = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_802_11_EEPROM_ACCESS: - { - struct host_cmd_ds_802_11_eeprom_access - *cmd_eeprom = - (struct host_cmd_ds_802_11_eeprom_access - *) &resp->params.eeprom; - pr_debug("info: EEPROM read len=%x\n", - cmd_eeprom->byte_count); - if (le16_to_cpu(eeprom->byte_count) < - le16_to_cpu( - cmd_eeprom->byte_count)) { - eeprom->byte_count = cpu_to_le16(0); - pr_debug("info: EEPROM read " - "length is too big\n"); - return -1; - } - eeprom->offset = cmd_eeprom->offset; - eeprom->byte_count = cmd_eeprom->byte_count; - if (le16_to_cpu(eeprom->byte_count) > 0) - memcpy(&eeprom->value, - &cmd_eeprom->value, - le16_to_cpu(eeprom->byte_count)); - - break; - } - default: + reg_rw = data_buf; + eeprom = data_buf; + switch (type) { + case HostCmd_CMD_MAC_REG_ACCESS: + r.mac = (struct host_cmd_ds_mac_reg_access *) + &resp->params.mac_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); + reg_rw->value = r.mac->value; + break; + case HostCmd_CMD_BBP_REG_ACCESS: + r.bbp = (struct host_cmd_ds_bbp_reg_access *) + &resp->params.bbp_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); + reg_rw->value = cpu_to_le32((u32) r.bbp->value); + break; + + case HostCmd_CMD_RF_REG_ACCESS: + r.rf = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); + reg_rw->value = cpu_to_le32((u32) r.bbp->value); + break; + case HostCmd_CMD_PMIC_REG_ACCESS: + r.pmic = (struct host_cmd_ds_pmic_reg_access *) + &resp->params.pmic_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); + reg_rw->value = cpu_to_le32((u32) r.pmic->value); + break; + case HostCmd_CMD_CAU_REG_ACCESS: + r.rf = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); + reg_rw->value = cpu_to_le32((u32) r.rf->value); + break; + case HostCmd_CMD_802_11_EEPROM_ACCESS: + r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *) + &resp->params.eeprom; + pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); + if (le16_to_cpu(eeprom->byte_count) < + le16_to_cpu(r.eeprom->byte_count)) { + eeprom->byte_count = cpu_to_le16(0); + pr_debug("info: EEPROM read length is too big\n"); return -1; } + eeprom->offset = r.eeprom->offset; + eeprom->byte_count = r.eeprom->byte_count; + if (le16_to_cpu(eeprom->byte_count) > 0) + memcpy(&eeprom->value, &r.eeprom->value, + le16_to_cpu(r.eeprom->byte_count)); + + break; + default: + return -1; } return 0; } @@ -778,7 +748,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp = - &(resp->params.ibss_coalescing); + &(resp->params.ibss_coalescing); u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET) @@ -918,20 +888,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_RECONFIGURE_TX_BUFF: adapter->tx_buf_size = (u16) le16_to_cpu(resp->params. tx_buf.buff_size); - adapter->tx_buf_size = (adapter->tx_buf_size / - MWIFIEX_SDIO_BLOCK_SIZE) * - MWIFIEX_SDIO_BLOCK_SIZE; + adapter->tx_buf_size = (adapter->tx_buf_size + / MWIFIEX_SDIO_BLOCK_SIZE) + * MWIFIEX_SDIO_BLOCK_SIZE; adapter->curr_tx_buf_size = adapter->tx_buf_size; dev_dbg(adapter->dev, "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", - adapter->max_tx_buf_size, adapter->tx_buf_size); + adapter->max_tx_buf_size, adapter->tx_buf_size); if (adapter->if_ops.update_mp_end_port) adapter->if_ops.update_mp_end_port(adapter, - le16_to_cpu(resp-> - params. - tx_buf. - mp_end_port)); + le16_to_cpu(resp->params.tx_buf.mp_end_port)); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); @@ -959,7 +926,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", - resp->command); + resp->command); break; } diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index b9b59db60454..cc531b536a56 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -93,11 +93,11 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) */ dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n", - priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); + priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid, - priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + priv->curr_bss_params.bss_descriptor.ssid.ssid, + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); memcpy(&priv->prev_ssid, &priv->curr_bss_params.bss_descriptor.ssid, @@ -115,9 +115,9 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) if (adapter->num_cmd_timeout && adapter->curr_cmd) return; priv->media_connected = false; - dev_dbg(adapter->dev, "info: successfully disconnected from" - " %pM: reason code %d\n", priv->cfg_bssid, - WLAN_REASON_DEAUTH_LEAVING); + dev_dbg(adapter->dev, + "info: successfully disconnected from %pM: reason code %d\n", + priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING); if (priv->bss_mode == NL80211_IFTYPE_STATION) { cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING, NULL, 0, GFP_KERNEL); @@ -192,8 +192,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) switch (eventcause) { case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: - dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL," - " ignoring it\n"); + dev_err(adapter->dev, + "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n"); break; case EVENT_LINK_SENSED: dev_dbg(adapter->dev, "event: LINK_SENSED\n"); @@ -235,8 +235,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_PS_AWAKE: dev_dbg(adapter->dev, "info: EVENT: AWAKE\n"); if (!adapter->pps_uapsd_mode && - priv->media_connected && - adapter->sleep_period.period) { + priv->media_connected && adapter->sleep_period.period) { adapter->pps_uapsd_mode = true; dev_dbg(adapter->dev, "event: PPS/UAPSD mode activated\n"); @@ -244,15 +243,19 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) adapter->tx_lock_flag = false; if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { if (mwifiex_check_last_packet_indication(priv)) { - if (!adapter->data_sent) { - if (!mwifiex_send_null_packet(priv, - MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET - | - MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) + if (adapter->data_sent) { + adapter->ps_state = PS_STATE_AWAKE; + adapter->pm_wakeup_card_req = false; + adapter->pm_wakeup_fw_try = false; + break; + } + if (!mwifiex_send_null_packet + (priv, + MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | + MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) adapter->ps_state = PS_STATE_SLEEP; return 0; - } } } adapter->ps_state = PS_STATE_AWAKE; @@ -371,12 +374,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_AMSDU_AGGR_CTRL: dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", - *(u16 *) adapter->event_body); + *(u16 *) adapter->event_body); adapter->tx_buf_size = min(adapter->curr_tx_buf_size, le16_to_cpu(*(__le16 *) adapter->event_body)); dev_dbg(adapter->dev, "event: tx_buf_size %d\n", - adapter->tx_buf_size); + adapter->tx_buf_size); break; case EVENT_WEP_ICV_ERR: @@ -392,7 +395,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; default: dev_dbg(adapter->dev, "event: unknown event id: %#x\n", - eventcause); + eventcause); break; } diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 0ae1209646c1..d7b11defafe0 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -71,7 +71,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) /* Wait for completion */ wait_event_interruptible(adapter->cmd_wait_q.wait, - *(cmd_queued->condition)); + *(cmd_queued->condition)); if (!*(cmd_queued->condition)) cancel_flag = true; @@ -266,9 +266,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, /* Adhoc mode */ /* If the requested SSID matches current SSID, return */ if (bss_desc && bss_desc->ssid.ssid_len && - (!mwifiex_ssid_cmp - (&priv->curr_bss_params.bss_descriptor.ssid, - &bss_desc->ssid))) { + (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. + ssid, &bss_desc->ssid))) { kfree(bss_desc); kfree(beacon_ie); return 0; @@ -350,9 +349,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; if (hs_cfg->gap) adapter->hs_cfg.gap = (u8)hs_cfg->gap; - } else if (adapter->hs_cfg.conditions == - cpu_to_le32( - HOST_SLEEP_CFG_CANCEL)) { + } else if (adapter->hs_cfg.conditions + == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { /* Return failure if no parameters for HS enable */ status = -1; @@ -374,7 +372,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, cpu_to_le32(prev_cond); } else { adapter->hs_cfg.conditions = - cpu_to_le32(hs_cfg->conditions); + cpu_to_le32(hs_cfg->conditions); adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; adapter->hs_cfg.gap = (u8)hs_cfg->gap; } @@ -427,11 +425,11 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) adapter->hs_activate_wait_q_woken = false; - memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); + memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); hscfg.is_invoke_hostcmd = true; if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_STA), + MWIFIEX_BSS_ROLE_STA), HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, &hscfg)) { dev_err(adapter->dev, "IOCTL request HS enable failed\n"); @@ -439,7 +437,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) } wait_event_interruptible(adapter->hs_activate_wait_q, - adapter->hs_activate_wait_q_woken); + adapter->hs_activate_wait_q_woken); return true; } @@ -529,30 +527,27 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, adapter->adhoc_start_band = BAND_G | BAND_B; if (chan->channel) { if (chan->channel <= MAX_CHANNEL_BAND_BG) - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, 0, (u16) chan->channel); + cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0); if (!cfp) { - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, BAND_A, (u16) chan->channel); + cfp = mwifiex_get_cfp(priv, BAND_A, + (u16) chan->channel, 0); if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A - | BAND_AN; + | BAND_AN; else adapter->adhoc_start_band = BAND_A; } } } else { if (chan->freq <= MAX_FREQUENCY_BAND_BG) - cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211( - priv, 0, chan->freq); + cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq); if (!cfp) { - cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211 - (priv, BAND_A, chan->freq); + cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq); if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A - | BAND_AN; + | BAND_AN; else adapter->adhoc_start_band = BAND_A; } @@ -588,7 +583,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, } return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, - action, 0, channel); + action, 0, channel); } /* @@ -634,7 +629,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) goto done; } dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", - curr_chan, channel); + curr_chan, channel); if (!bss_info.media_connected) { ret = 0; @@ -656,7 +651,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); chan = __ieee80211_get_channel(priv->wdev->wiphy, - ieee80211_channel_to_frequency(channel, band)); + ieee80211_channel_to_frequency(channel, + band)); /* Find the BSS we want using available scan results */ bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, @@ -664,7 +660,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); if (!bss) wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n", - bss_info.bssid); + bss_info.bssid); ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); done: @@ -793,7 +789,9 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, if (!ret) { if (rate->is_rate_auto) rate->rate = mwifiex_index_to_data_rate(priv, - priv->tx_rate, priv->tx_htinfo); + priv->tx_rate, + priv->tx_htinfo + ); else rate->rate = priv->data_rate; } else { @@ -830,16 +828,16 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, if ((dbm < priv->min_tx_power_level) || (dbm > priv->max_tx_power_level)) { dev_err(priv->adapter->dev, "txpower value %d dBm" - " is out of range (%d dBm-%d dBm)\n", - dbm, priv->min_tx_power_level, - priv->max_tx_power_level); + " is out of range (%d dBm-%d dBm)\n", + dbm, priv->min_tx_power_level, + priv->max_tx_power_level); return -1; } } buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); if (!buf) { dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", - __func__); + __func__); return -ENOMEM; } @@ -847,13 +845,13 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); if (!power_cfg->is_power_auto) { txp_cfg->mode = cpu_to_le32(1); - pg_tlv = (struct mwifiex_types_power_group *) (buf + - sizeof(struct host_cmd_ds_txpwr_cfg)); + pg_tlv = (struct mwifiex_types_power_group *) + (buf + sizeof(struct host_cmd_ds_txpwr_cfg)); pg_tlv->type = TLV_TYPE_POWER_GROUP; pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); - pg = (struct mwifiex_power_group *) (buf + - sizeof(struct host_cmd_ds_txpwr_cfg) + - sizeof(struct mwifiex_types_power_group)); + pg = (struct mwifiex_power_group *) + (buf + sizeof(struct host_cmd_ds_txpwr_cfg) + + sizeof(struct mwifiex_types_power_group)); /* Power group for modulation class HR/DSSS */ pg->first_rate_code = 0x00; pg->last_rate_code = 0x03; @@ -916,8 +914,8 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) sub_cmd, BITMAP_STA_PS, NULL); if ((!ret) && (sub_cmd == DIS_AUTO_PS)) ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, - 0, NULL); + HostCmd_CMD_802_11_PS_MODE_ENH, + GET_PS, 0, NULL); return ret; } @@ -941,7 +939,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, memcpy(priv->wpa_ie, ie_data_ptr, ie_len); priv->wpa_ie_len = (u8) ie_len; dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", - priv->wpa_ie_len, priv->wpa_ie[0]); + priv->wpa_ie_len, priv->wpa_ie[0]); if (priv->wpa_ie[0] == WLAN_EID_WPA) { priv->sec_info.wpa_enabled = true; @@ -982,7 +980,7 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, memcpy(priv->wapi_ie, ie_data_ptr, ie_len); priv->wapi_ie_len = ie_len; dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n", - priv->wapi_ie_len, priv->wapi_ie[0]); + priv->wapi_ie_len, priv->wapi_ie[0]); if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) priv->sec_info.wapi_enabled = true; @@ -1008,8 +1006,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, { return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); } /* @@ -1103,9 +1101,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, /* Send the key as PTK to firmware */ encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + KEY_INFO_ENABLED, encrypt_key); if (ret) return ret; @@ -1130,14 +1128,14 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, if (remove_key) ret = mwifiex_send_cmd_sync(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + !KEY_INFO_ENABLED, encrypt_key); else ret = mwifiex_send_cmd_sync(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + KEY_INFO_ENABLED, encrypt_key); return ret; } @@ -1256,7 +1254,7 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv) memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, - HostCmd_ACT_GEN_GET, 0, &ver_ext)) + HostCmd_ACT_GEN_GET, 0, &ver_ext)) return -1; return 0; @@ -1273,7 +1271,7 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, struct mwifiex_ds_get_stats *log) { return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, - HostCmd_ACT_GEN_GET, 0, log); + HostCmd_ACT_GEN_GET, 0, log); } /* @@ -1413,9 +1411,9 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, } pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; /* Test to see if it is a WPA IE, if not, then it is a gen IE */ - if (((pvendor_ie->element_id == WLAN_EID_WPA) - && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) - || (pvendor_ie->element_id == WLAN_EID_RSN)) { + if (((pvendor_ie->element_id == WLAN_EID_WPA) && + (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || + (pvendor_ie->element_id == WLAN_EID_RSN)) { /* IE is a WPA/WPA2 IE so call set_wpa function */ ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len); @@ -1438,9 +1436,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, * wps session flag */ pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; - if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) - && (!memcmp(pvendor_ie->oui, wps_oui, - sizeof(wps_oui)))) { + if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && + (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { priv->wps.session_enable = true; dev_dbg(priv->adapter->dev, "info: WPS Session Enabled.\n"); @@ -1449,7 +1446,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, /* Append the passed data to the end of the genIeBuffer */ memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr, - ie_len); + ie_len); /* Increment the stored buffer length by the size passed */ priv->gen_ie_buf_len += ie_len; @@ -1493,7 +1490,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv, return -1; } else { memcpy(adapter->arp_filter, gen_ie->ie_data, - gen_ie->len); + gen_ie->len); adapter->arp_filter_size = gen_ie->len; } break; diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index d7a5d7616f22..750b695aca12 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -43,8 +43,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, { int ret; struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); - struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, - rx_info->bss_num, rx_info->bss_type); + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); struct rx_packet_hdr *rx_pkt_hdr; struct rxpd *local_rx_pd; int hdr_chop; @@ -125,8 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, struct rx_packet_hdr *rx_pkt_hdr; u8 ta[ETH_ALEN]; u16 rx_pkt_type; - struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, - rx_info->bss_num, rx_info->bss_type); + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); if (!priv) return -1; @@ -157,7 +159,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, skb_trim(skb, local_rx_pd->rx_pkt_length); ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, - priv->wdev->iftype, 0, false); + priv->wdev->iftype, 0, false); while (!skb_queue_empty(&list)) { rx_skb = __skb_dequeue(&list); diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index 94d31a94620a..7af534feb420 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -50,8 +50,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, u8 pad; if (!skb->len) { - dev_err(adapter->dev, "Tx: bad packet length: %d\n", - skb->len); + dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); tx_info->status_code = -1; return skb->data; } @@ -60,19 +59,20 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN - + pad)); + + pad)); skb_push(skb, sizeof(*local_tx_pd) + pad); local_tx_pd = (struct txpd *) skb->data; memset(local_tx_pd, 0, sizeof(struct txpd)); local_tx_pd->bss_num = priv->bss_num; local_tx_pd->bss_type = priv->bss_type; - local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - - (sizeof(struct txpd) + pad))); + local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len - + (sizeof(struct txpd) + + pad))); local_tx_pd->priority = (u8) skb->priority; local_tx_pd->pkt_delay_2ms = - mwifiex_wmm_compute_drv_pkt_delay(priv, skb); + mwifiex_wmm_compute_drv_pkt_delay(priv, skb); if (local_tx_pd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) @@ -82,7 +82,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, */ local_tx_pd->tx_control = cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd-> - priority]); + priority]); if (adapter->pps_uapsd_mode) { if (mwifiex_check_last_packet_indication(priv)) { @@ -160,13 +160,13 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) case -1: dev_kfree_skb_any(skb); dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n", - __func__, ret); + __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; break; case 0: dev_kfree_skb_any(skb); dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n", - __func__); + __func__); adapter->tx_lock_flag = true; break; case -EINPROGRESS: @@ -192,8 +192,8 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv) if (mwifiex_wmm_lists_empty(adapter)) ret = true; - if (ret && !adapter->cmd_sent && !adapter->curr_cmd - && !is_command_pending(adapter)) { + if (ret && !adapter->cmd_sent && !adapter->curr_cmd && + !is_command_pending(adapter)) { adapter->delay_null_pkt = false; ret = true; } else { diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 9a6eacc9d6f9..d2af8cb98541 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -85,8 +85,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, switch (ret) { case -EBUSY: if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (adapter->pps_uapsd_mode) && - (adapter->tx_lock_flag)) { + (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) { priv->adapter->tx_lock_flag = false; if (local_tx_pd) local_tx_pd->flags = 0; @@ -96,7 +95,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, case -1: adapter->data_sent = false; dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", - ret); + ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb, ret); break; @@ -132,7 +131,7 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, tx_info = MWIFIEX_SKB_TXCB(skb); priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, - tx_info->bss_type); + tx_info->bss_type); if (!priv) goto done; @@ -151,11 +150,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, tpriv = adapter->priv[i]; - if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) - && (tpriv->media_connected)) { + if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && + (tpriv->media_connected)) { if (netif_queue_stopped(tpriv->netdev)) mwifiex_wake_up_net_dev_queue(tpriv->netdev, - adapter); + adapter); } } done: diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 9c48f37069f7..6b399976d6c8 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -93,10 +93,10 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, sizeof(priv->wmm.packets_out)); info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; info->tx_buf_size = (u32) adapter->tx_buf_size; - info->rx_tbl_num = mwifiex_get_rx_reorder_tbl( - priv, info->rx_tbl); - info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl( - priv, info->tx_tbl); + info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(priv, + info->rx_tbl); + info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(priv, + info->tx_tbl); info->ps_mode = adapter->ps_mode; info->ps_state = adapter->ps_state; info->is_deep_sleep = adapter->is_deep_sleep; @@ -105,19 +105,19 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, info->is_hs_configured = adapter->is_hs_configured; info->hs_activated = adapter->hs_activated; info->num_cmd_host_to_card_failure - = adapter->dbg.num_cmd_host_to_card_failure; + = adapter->dbg.num_cmd_host_to_card_failure; info->num_cmd_sleep_cfm_host_to_card_failure = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure; info->num_tx_host_to_card_failure - = adapter->dbg.num_tx_host_to_card_failure; + = adapter->dbg.num_tx_host_to_card_failure; info->num_event_deauth = adapter->dbg.num_event_deauth; info->num_event_disassoc = adapter->dbg.num_event_disassoc; info->num_event_link_lost = adapter->dbg.num_event_link_lost; info->num_cmd_deauth = adapter->dbg.num_cmd_deauth; info->num_cmd_assoc_success = - adapter->dbg.num_cmd_assoc_success; + adapter->dbg.num_cmd_assoc_success; info->num_cmd_assoc_failure = - adapter->dbg.num_cmd_assoc_failure; + adapter->dbg.num_cmd_assoc_failure; info->num_tx_timeout = adapter->dbg.num_tx_timeout; info->num_cmd_timeout = adapter->dbg.num_cmd_timeout; info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; @@ -160,7 +160,7 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) rx_info = MWIFIEX_SKB_RXCB(skb); priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, - rx_info->bss_type); + rx_info->bss_type); if (!priv) return -1; @@ -191,7 +191,7 @@ int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, { atomic_dec(&adapter->cmd_pending); dev_dbg(adapter->dev, "cmd completed: status=%d\n", - adapter->cmd_wait_q.status); + adapter->cmd_wait_q.status); *(cmd_node->condition) = true; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 75f79ef9f6cf..5a7316c6f125 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -87,15 +87,15 @@ mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param) const char *ac_str[] = { "BK", "BE", "VI", "VO" }; pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, " - "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", - ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap - & MWIFIEX_ACI) >> 5]], - (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, - (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, - ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, - ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, - (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, - le16_to_cpu(ac_param->tx_op_limit)); + "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", + ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap + & MWIFIEX_ACI) >> 5]], + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, + ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, + ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, + (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, + le16_to_cpu(ac_param->tx_op_limit)); } /* @@ -112,7 +112,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) if (!ra_list) { dev_err(adapter->dev, "%s: failed to alloc ra_list\n", - __func__); + __func__); return NULL; } INIT_LIST_HEAD(&ra_list->list); @@ -154,7 +154,7 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) ra_list, ra_list->is_11n_enabled); list_add_tail(&ra_list->list, - &priv->wmm.tid_tbl_ptr[i].ra_list); + &priv->wmm.tid_tbl_ptr[i].ra_list); if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; @@ -217,22 +217,19 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, wmm_ie->reserved); for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) { - cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap & - MWIFIEX_ECW_MIN)) - 1; - avg_back_off = (cw_min >> 1) + - (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap & - MWIFIEX_AIFSN); - - ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac]. - aci_aifsn_bitmap & - MWIFIEX_ACI) >> 5]; + u8 ecw = wmm_ie->ac_params[num_ac].ecw_bitmap; + u8 aci_aifsn = wmm_ie->ac_params[num_ac].aci_aifsn_bitmap; + cw_min = (1 << (ecw & MWIFIEX_ECW_MIN)) - 1; + avg_back_off = (cw_min >> 1) + (aci_aifsn & MWIFIEX_AIFSN); + + ac_idx = wmm_aci_to_qidx_map[(aci_aifsn & MWIFIEX_ACI) >> 5]; priv->wmm.queue_priority[ac_idx] = ac_idx; tmp[ac_idx] = avg_back_off; - dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", - (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap & - MWIFIEX_ECW_MAX) >> 4)) - 1, - cw_min, avg_back_off); + dev_dbg(priv->adapter->dev, + "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", + (1 << ((ecw & MWIFIEX_ECW_MAX) >> 4)) - 1, + cw_min, avg_back_off); mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]); } @@ -312,13 +309,14 @@ mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv) /* WMM is not enabled, default priorities */ for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) priv->wmm.ac_down_graded_vals[ac_val] = - (enum mwifiex_wmm_ac_e) ac_val; + (enum mwifiex_wmm_ac_e) ac_val; } else { for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) { priv->wmm.ac_down_graded_vals[ac_val] = mwifiex_wmm_eval_downgrade_ac(priv, (enum mwifiex_wmm_ac_e) ac_val); - dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n", + dev_dbg(priv->adapter->dev, + "info: WMM: AC PRIO %d maps to %d\n", ac_val, priv->wmm.ac_down_graded_vals[ac_val]); } } @@ -394,13 +392,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) } priv->aggr_prio_tbl[6].amsdu - = priv->aggr_prio_tbl[6].ampdu_ap - = priv->aggr_prio_tbl[6].ampdu_user - = BA_STREAM_NOT_ALLOWED; + = priv->aggr_prio_tbl[6].ampdu_ap + = priv->aggr_prio_tbl[6].ampdu_user + = BA_STREAM_NOT_ALLOWED; priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap - = priv->aggr_prio_tbl[7].ampdu_user - = BA_STREAM_NOT_ALLOWED; + = priv->aggr_prio_tbl[7].ampdu_user + = BA_STREAM_NOT_ALLOWED; priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; @@ -472,7 +470,7 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) for (i = 0; i < MAX_NUM_TID; i++) mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. - ra_list); + ra_list); atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); @@ -488,9 +486,10 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) for (i = 0; i < MAX_NUM_TID; ++i) { dev_dbg(priv->adapter->dev, - "info: ra_list: freeing buf for tid %d\n", i); + "info: ra_list: freeing buf for tid %d\n", i); list_for_each_entry_safe(ra_list, tmp_node, - &priv->wmm.tid_tbl_ptr[i].ra_list, list) { + &priv->wmm.tid_tbl_ptr[i].ra_list, + list) { list_del(&ra_list->list); kfree(ra_list); } @@ -652,7 +651,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, if (atomic_read(&priv->wmm.highest_queued_prio) < tos_to_tid_inv[tid_down]) atomic_set(&priv->wmm.highest_queued_prio, - tos_to_tid_inv[tid_down]); + tos_to_tid_inv[tid_down]); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } @@ -681,7 +680,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, struct mwifiex_wmm_ac_status *ac_status; dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n", - resp_len); + resp_len); while ((resp_len >= sizeof(tlv_hdr->header)) && valid) { tlv_hdr = (struct mwifiex_ie_types_data *) curr; @@ -695,15 +694,15 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: CMD_RESP: WMM_GET_STATUS:" " QSTATUS TLV: %d, %d, %d\n", - tlv_wmm_qstatus->queue_index, - tlv_wmm_qstatus->flow_required, - tlv_wmm_qstatus->disabled); + tlv_wmm_qstatus->queue_index, + tlv_wmm_qstatus->flow_required, + tlv_wmm_qstatus->disabled); ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus-> queue_index]; ac_status->disabled = tlv_wmm_qstatus->disabled; ac_status->flow_required = - tlv_wmm_qstatus->flow_required; + tlv_wmm_qstatus->flow_required; ac_status->flow_created = tlv_wmm_qstatus->flow_created; break; @@ -772,29 +771,27 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, if (!wmm_ie) return 0; - dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:" - "bss->wmmIe=0x%x\n", - wmm_ie->vend_hdr.element_id); + dev_dbg(priv->adapter->dev, + "info: WMM: process assoc req: bss->wmm_ie=%#x\n", + wmm_ie->vend_hdr.element_id); - if ((priv->wmm_required - || (ht_cap && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) - ) - && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { + if ((priv->wmm_required || + (ht_cap && (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN))) && + wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf; wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]); wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]); memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2], - le16_to_cpu(wmm_tlv->header.len)); + le16_to_cpu(wmm_tlv->header.len)); if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) memcpy((u8 *) (wmm_tlv->wmm_ie - + le16_to_cpu(wmm_tlv->header.len) - - sizeof(priv->wmm_qosinfo)), - &priv->wmm_qosinfo, - sizeof(priv->wmm_qosinfo)); + + le16_to_cpu(wmm_tlv->header.len) + - sizeof(priv->wmm_qosinfo)), + &priv->wmm_qosinfo, sizeof(priv->wmm_qosinfo)); ret_len = sizeof(wmm_tlv->header) - + le16_to_cpu(wmm_tlv->header.len); + + le16_to_cpu(wmm_tlv->header.len); *assoc_buf += ret_len; } @@ -813,7 +810,7 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, */ u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, - const struct sk_buff *skb) + const struct sk_buff *skb) { u8 ret_val; struct timeval out_tstamp, in_tstamp; @@ -850,17 +847,18 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, struct mwifiex_ra_list_tbl *ptr, *head; struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; struct mwifiex_tid_tbl *tid_ptr; + atomic_t *hqp; int is_list_empty; unsigned long flags; int i, j; for (j = adapter->priv_num - 1; j >= 0; --j) { spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); + flags); is_list_empty = list_empty(&adapter->bss_prio_tbl[j] - .bss_prio_head); + .bss_prio_head); spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); + flags); if (is_list_empty) continue; @@ -879,12 +877,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } do { - atomic_t *hqp; - spinlock_t *lock; - priv_tmp = bssprio_node->priv; hqp = &priv_tmp->wmm.highest_queued_prio; - lock = &priv_tmp->wmm.ra_list_spinlock; for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { @@ -923,16 +917,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, do { is_list_empty = skb_queue_empty(&ptr->skb_head); - if (!is_list_empty) { - spin_lock_irqsave(lock, flags); - if (atomic_read(hqp) > i) - atomic_set(hqp, i); - spin_unlock_irqrestore(lock, - flags); - *priv = priv_tmp; - *tid = tos_to_tid[i]; - return ptr; - } + + if (!is_list_empty) + goto found; + /* Get next ra */ ptr = list_first_entry(&ptr->list, struct mwifiex_ra_list_tbl, @@ -969,6 +957,17 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } while (bssprio_node != bssprio_head); } return NULL; + +found: + spin_lock_irqsave(&priv_tmp->wmm.ra_list_spinlock, flags); + if (atomic_read(hqp) > i) + atomic_set(hqp, i); + spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags); + + *priv = priv_tmp; + *tid = tos_to_tid[i]; + + return ptr; } /* @@ -1208,25 +1207,24 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) return 0; } - if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) - || ((priv->sec_info.wpa_enabled - || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set) - ) { + if (!ptr->is_11n_enabled || + mwifiex_is_ba_stream_setup(priv, ptr, tid) || + ((priv->sec_info.wpa_enabled || + priv->sec_info.wpa2_enabled) && + !priv->wpa_is_gtk_set)) { mwifiex_send_single_packet(priv, ptr, ptr_index, flags); /* ra_list_spinlock has been freed in mwifiex_send_single_packet() */ } else { if (mwifiex_is_ampdu_allowed(priv, tid)) { if (mwifiex_space_avail_for_new_ba_stream(adapter)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - ptr->ra, tid, - BA_STREAM_SETUP_INPROGRESS); + mwifiex_create_ba_tbl(priv, ptr->ra, tid, + BA_SETUP_INPROGRESS); mwifiex_send_addba(priv, tid, ptr->ra); } else if (mwifiex_find_stream_to_delete (priv, tid, &tid_del, ra)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - ptr->ra, tid, - BA_STREAM_SETUP_INPROGRESS); + mwifiex_create_ba_tbl(priv, ptr->ra, tid, + BA_SETUP_INPROGRESS); mwifiex_send_delba(priv, tid_del, ra, 1); } } diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index e5c05d8c7448..063bfa8b91f4 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2475,6 +2475,12 @@ struct mac_iveiv_entry { #define EIRP_MAX_TX_POWER_LIMIT 0x50 /* + * Number of TBTT intervals after which we have to adjust + * the hw beacon timer. + */ +#define BCN_TBTT_OFFSET 64 + +/* * RT2800 driver data structure */ struct rt2800_drv_data { @@ -2484,6 +2490,7 @@ struct rt2800_drv_data { u8 bbp26; u8 txmixer_gain_24g; u8 txmixer_gain_5g; + unsigned int tbtt_tick; }; #endif /* RT2800_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 474b5b9e6238..6c0a12ea6a15 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4500,7 +4500,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_AMPDU_AGGREGATION; + IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_REPORTS_TX_ACK_STATUS; + /* * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices * unless we are capable of sending the buffered frames out after the diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 9375db455456..0397bbf0ce01 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -809,7 +809,33 @@ static void rt2800pci_pretbtt_tasklet(unsigned long data) static void rt2800pci_tbtt_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u32 reg; + rt2x00lib_beacondone(rt2x00dev); + + if (rt2x00dev->intf_ap_count) { + /* + * The rt2800pci hardware tbtt timer is off by 1us per tbtt + * causing beacon skew and as a result causing problems with + * some powersaving clients over time. Shorten the beacon + * interval every 64 beacons by 64us to mitigate this effect. + */ + if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16) - 1); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16)); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } + drv_data->tbtt_tick++; + drv_data->tbtt_tick %= BCN_TBTT_OFFSET; + } + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); } diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 2c11137c1eb0..cd490abced91 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -114,45 +114,103 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) return false; } +static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) +{ + bool tout; + + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + return false; + + tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); + if (unlikely(tout)) + WARNING(entry->queue->rt2x00dev, + "TX status timeout for entry %d in queue %d\n", + entry->entry_idx, entry->queue->qid); + return tout; + +} + +static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + + tx_queue_for_each(rt2x00dev, queue) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800usb_entry_txstatus_timeout(entry)) + return true; + } + return false; +} + static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, int urb_status, u32 tx_status) { + bool valid; + if (urb_status) { - WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); - return false; + WARNING(rt2x00dev, "TX status read failed %d\n", urb_status); + + goto stop_reading; } - /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ - if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) { - if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) { - WARNING(rt2x00dev, "TX status FIFO overrun, " - "drop tx status report.\n"); - queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); - } else - return true; - } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { + valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); + if (valid) { + if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) + WARNING(rt2x00dev, "TX status FIFO overrun\n"); + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + + /* Reschedule urb to read TX status again instantly */ + return true; } else if (rt2800usb_txstatus_pending(rt2x00dev)) { - mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); + /* Read register after 250 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), + HRTIMER_MODE_REL); + return false; } - return false; +stop_reading: + clear_bit(TX_STATUS_READING, &rt2x00dev->flags); + /* + * There is small race window above, between txstatus pending check and + * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck + * here again if status reading is needed. + */ + if (rt2800usb_txstatus_pending(rt2x00dev) && + test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return true; + else + return false; +} + +static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) +{ + + if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return; + + /* Read TX_STA_FIFO register after 500 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000), + HRTIMER_MODE_REL); } static void rt2800usb_tx_dma_done(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, - rt2800usb_tx_sta_fifo_read_completed); + rt2800usb_async_read_tx_status(rt2x00dev); } -static void rt2800usb_tx_sta_fifo_timeout(unsigned long data) +static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer) { - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + struct rt2x00_dev *rt2x00dev = + container_of(timer, struct rt2x00_dev, txstatus_timer); rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, rt2800usb_tx_sta_fifo_read_completed); + + return HRTIMER_NORESTART; } /* @@ -438,35 +496,26 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) /* * TX control handlers */ -static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) +static enum txdone_entry_desc_flags +rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) { __le32 *txwi; u32 word; int wcid, ack, pid; - int tx_wcid, tx_ack, tx_pid; - - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { - WARNING(entry->queue->rt2x00dev, - "Data pending for entry %u in queue %u\n", - entry->entry_idx, entry->queue->qid); - cond_resched(); - return false; - } - - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + int tx_wcid, tx_ack, tx_pid, is_agg; /* * This frames has returned with an IO error, * so the status report is not intended for this * frame. */ - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - return false; - } + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + return TXDONE_FAILURE; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); /* * Validate if this TX status report is intended for @@ -479,15 +528,14 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { + if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { WARNING(entry->queue->rt2x00dev, "TX status report missed for queue %d entry %d\n", - entry->queue->qid, entry->entry_idx); - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); - return false; + entry->queue->qid, entry->entry_idx); + return TXDONE_UNKNOWN; } - return true; + return TXDONE_SUCCESS; } static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) @@ -496,47 +544,44 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) struct queue_entry *entry; u32 reg; u8 qid; + enum txdone_entry_desc_flags done_status; while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { - - /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus - * qid is guaranteed to be one of the TX QIDs + /* + * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is + * guaranteed to be one of the TX QIDs . */ qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); - if (unlikely(!queue)) { - WARNING(rt2x00dev, "Got TX status for an unavailable " + + if (unlikely(rt2x00queue_empty(queue))) { + WARNING(rt2x00dev, "Got TX status for an empty " "queue %u, dropping\n", qid); - continue; + break; } - /* - * Inside each queue, we process each entry in a chronological - * order. We first check that the queue is not empty. - */ - entry = NULL; - while (!rt2x00queue_empty(queue)) { - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (rt2800usb_txdone_entry_check(entry, reg)) - break; - entry = NULL; + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { + WARNING(rt2x00dev, "Data pending for entry %u " + "in queue %u\n", entry->entry_idx, qid); + break; } - if (entry) - rt2800_txdone_entry(entry, reg, - rt2800usb_get_txwi(entry)); + done_status = rt2800usb_txdone_entry_check(entry, reg); + if (likely(done_status == TXDONE_SUCCESS)) + rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry)); + else + rt2x00lib_txdone_noinfo(entry, done_status); } } -static void rt2800usb_work_txdone(struct work_struct *work) +static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) { - struct rt2x00_dev *rt2x00dev = - container_of(work, struct rt2x00_dev, txdone_work); struct data_queue *queue; struct queue_entry *entry; - rt2800usb_txdone(rt2x00dev); - /* * Process any trailing TX status reports for IO failures, * we loop until we find the first non-IO error entry. This @@ -554,20 +599,34 @@ static void rt2800usb_work_txdone(struct work_struct *work) if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - else if (rt2x00queue_status_timeout(entry)) + else if (rt2800usb_entry_txstatus_timeout(entry)) rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); else break; } } +} - /* - * The hw may delay sending the packet after DMA complete - * if the medium is busy, thus the TX_STA_FIFO entry is - * also delayed -> use a timer to retrieve it. - */ - if (rt2800usb_txstatus_pending(rt2x00dev)) - mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); +static void rt2800usb_work_txdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || + rt2800usb_txstatus_timeout(rt2x00dev)) { + + rt2800usb_txdone(rt2x00dev); + + rt2800usb_txdone_nostatus(rt2x00dev); + + /* + * The hw may delay sending the packet after DMA complete + * if the medium is busy, thus the TX_STA_FIFO entry is + * also delayed -> use a timer to retrieve it. + */ + if (rt2800usb_txstatus_pending(rt2x00dev)) + rt2800usb_async_read_tx_status(rt2x00dev); + } } /* @@ -709,9 +768,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); - setup_timer(&rt2x00dev->txstatus_timer, - rt2800usb_tx_sta_fifo_timeout, - (unsigned long) rt2x00dev); + rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout, /* * Set the rssi offset. @@ -813,7 +870,7 @@ static const struct data_queue_desc rt2800usb_queue_rx = { }; static const struct data_queue_desc rt2800usb_queue_tx = { - .entry_num = 64, + .entry_num = 16, .data_size = AGGREGATION_SIZE, .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 65275efcf279..471f87cab4ab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -38,7 +38,7 @@ #include <linux/etherdevice.h> #include <linux/input-polldev.h> #include <linux/kfifo.h> -#include <linux/timer.h> +#include <linux/hrtimer.h> #include <net/mac80211.h> @@ -692,6 +692,12 @@ enum rt2x00_state_flags { */ CONFIG_CHANNEL_HT40, CONFIG_POWERSAVING, + + /* + * Mark we currently are sequentially reading TX_STA_FIFO register + * FIXME: this is for only rt2800usb, should go to private data + */ + TX_STATUS_READING, }; /* @@ -974,7 +980,7 @@ struct rt2x00_dev { /* * Timer to ensure tx status reports are read (rt2800usb). */ - struct timer_list txstatus_timer; + struct hrtimer txstatus_timer; /* * Tasklet for processing tx status reports (rt2800pci). diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index d7c0f86c9e43..293676bfa571 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -102,7 +102,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, /* Update the AID, this is needed for dynamic PS support */ rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; - rt2x00dev->last_beacon = bss_conf->timestamp; + rt2x00dev->last_beacon = bss_conf->last_tsf; /* Update global beacon interval time, this is needed for PS support */ rt2x00dev->beacon_int = bss_conf->beacon_int; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 49a51b4195ef..fc9901e027c1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -430,10 +430,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, /* * If the data queue was below the threshold before the txdone * handler we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. + * is reenabled when the txdone handler has finished. This has to be + * serialized with rt2x00mac_tx(), otherwise we can wake up queue + * before it was stopped. */ + spin_lock_bh(&entry->queue->tx_lock); if (!rt2x00queue_threshold(entry->queue)) rt2x00queue_unpause_queue(entry->queue); + spin_unlock_bh(&entry->queue->tx_lock); } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); @@ -1232,7 +1236,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); cancel_work_sync(&rt2x00dev->sleep_work); if (rt2x00_is_usb(rt2x00dev)) { - del_timer_sync(&rt2x00dev->txstatus_timer); + hrtimer_cancel(&rt2x00dev->txstatus_timer); cancel_work_sync(&rt2x00dev->rxdone_work); cancel_work_sync(&rt2x00dev->txdone_work); } diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index ede3c58e6783..2df2eb6d3e06 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -152,13 +152,22 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) goto exit_fail; + /* + * Pausing queue has to be serialized with rt2x00lib_txdone(). Note + * we should not use spin_lock_bh variant as bottom halve was already + * disabled before ieee80211_xmit() call. + */ + spin_lock(&queue->tx_lock); if (rt2x00queue_threshold(queue)) rt2x00queue_pause_queue(queue); + spin_unlock(&queue->tx_lock); return; exit_fail: + spin_lock(&queue->tx_lock); rt2x00queue_pause_queue(queue); + spin_unlock(&queue->tx_lock); exit_free_skb: ieee80211_free_txskb(hw, skb); } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 5adfb3eab9cd..9b1b2b7a7807 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -619,6 +619,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) rt2x00queue_align_frame(skb); + /* + * That function must be called with bh disabled. + */ spin_lock(&queue->tx_lock); if (unlikely(rt2x00queue_full(queue))) { diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 349008d1fb28..5f1392c72673 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -636,18 +636,6 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) { return rt2x00queue_available(queue) < queue->threshold; } - -/** - * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports - * @entry: Queue entry to check. - */ -static inline int rt2x00queue_status_timeout(struct queue_entry *entry) -{ - if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) - return false; - return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); -} - /** * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers * @entry: Queue entry to check. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 2eea3866504d..66094eb21b61 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -526,22 +526,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) rt2x00queue_flush_queue(queue, true); } -static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) -{ - WARNING(queue->rt2x00dev, "TX queue %d status timed out," - " invoke forced tx handler\n", queue->qid); - - queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); -} - -static int rt2x00usb_status_timeout(struct data_queue *queue) -{ - struct queue_entry *entry; - - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - return rt2x00queue_status_timeout(entry); -} - static int rt2x00usb_dma_timeout(struct data_queue *queue) { struct queue_entry *entry; @@ -558,8 +542,6 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) if (!rt2x00queue_empty(queue)) { if (rt2x00usb_dma_timeout(queue)) rt2x00usb_watchdog_tx_dma(queue); - if (rt2x00usb_status_timeout(queue)) - rt2x00usb_watchdog_tx_status(queue); } } } @@ -829,7 +811,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); - init_timer(&rt2x00dev->txstatus_timer); + hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); retval = rt2x00usb_alloc_reg(rt2x00dev); if (retval) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 1cfbf228fbb1..24f049e73952 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -500,6 +500,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) int pos; u32 reg32; + if (aspm_disabled) + return 0; + /* * Some functions in a slot might not all be PCIe functions, * very strange. Disable ASPM for the whole slot diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index f995e6e2f78c..15dbd8cc445f 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -143,6 +143,30 @@ config FUJITSU_LAPTOP_DEBUG If you are not sure, say N here. +config FUJITSU_TABLET + tristate "Fujitsu Tablet Extras" + depends on ACPI + depends on INPUT + ---help--- + This is a driver for tablets built by Fujitsu: + + * Lifebook P1510/P1610/P1620/Txxxx + * Stylistic ST5xxx + * Possibly other Fujitsu tablet models + + It adds support for the panel buttons, docking station detection, + tablet/notebook mode detection for convertible and + orientation detection for docked slates. + + If you have a Fujitsu convertible or slate, say Y or M here. + +config AMILO_RFKILL + tristate "Fujitsu-Siemens Amilo rfkill support" + depends on RFKILL + ---help--- + This is a driver for enabling wifi on some Fujitsu-Siemens Amilo + laptops. + config TC1100_WMI tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" depends on !X86_64 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 293a320d9faa..d328f21e9fdd 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -17,12 +17,14 @@ obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_ACERHDF) += acerhdf.o obj-$(CONFIG_HP_ACCEL) += hp_accel.o obj-$(CONFIG_HP_WMI) += hp-wmi.o +obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o +obj-$(CONFIG_FUJITSU_TABLET) += fujitsu-tablet.o obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o obj-$(CONFIG_ACPI_WMI) += wmi.o diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index b848277171a4..1e5290b5396d 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -679,6 +679,32 @@ static acpi_status AMW0_find_mailled(void) return AE_OK; } +static int AMW0_set_cap_acpi_check_device_found; + +static acpi_status AMW0_set_cap_acpi_check_device_cb(acpi_handle handle, + u32 level, void *context, void **retval) +{ + AMW0_set_cap_acpi_check_device_found = 1; + return AE_OK; +} + +static const struct acpi_device_id norfkill_ids[] = { + { "VPC2004", 0}, + { "IBM0068", 0}, + { "LEN0068", 0}, + { "", 0}, +}; + +static int AMW0_set_cap_acpi_check_device(void) +{ + const struct acpi_device_id *id; + + for (id = norfkill_ids; id->id[0]; id++) + acpi_get_devices(id->id, AMW0_set_cap_acpi_check_device_cb, + NULL, NULL); + return AMW0_set_cap_acpi_check_device_found; +} + static acpi_status AMW0_set_capabilities(void) { struct wmab_args args; @@ -692,7 +718,9 @@ static acpi_status AMW0_set_capabilities(void) * work. */ if (wmi_has_guid(AMW0_GUID2)) { - interface->capability |= ACER_CAP_WIRELESS; + if ((quirks != &quirk_unknown) || + !AMW0_set_cap_acpi_check_device()) + interface->capability |= ACER_CAP_WIRELESS; return AE_OK; } diff --git a/drivers/platform/x86/amilo-rfkill.c b/drivers/platform/x86/amilo-rfkill.c new file mode 100644 index 000000000000..19170bb7700b --- /dev/null +++ b/drivers/platform/x86/amilo-rfkill.c @@ -0,0 +1,173 @@ +/* + * Support for rfkill on some Fujitsu-Siemens Amilo laptops. + * Copyright 2011 Ben Hutchings. + * + * Based in part on the fsam7440 driver, which is: + * Copyright 2005 Alejandro Vidal Mata & Javier Vidal Mata. + * and on the fsaa1655g driver, which is: + * Copyright 2006 Martin Večeřa. + * + * 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. + */ + +#include <linux/module.h> +#include <linux/dmi.h> +#include <linux/i8042.h> +#include <linux/io.h> +#include <linux/moduleparam.h> +#include <linux/platform_device.h> +#include <linux/rfkill.h> + +/* + * These values were obtained from disassembling and debugging the + * PM.exe program installed in the Fujitsu-Siemens AMILO A1655G + */ +#define A1655_WIFI_COMMAND 0x10C5 +#define A1655_WIFI_ON 0x25 +#define A1655_WIFI_OFF 0x45 + +static int amilo_a1655_rfkill_set_block(void *data, bool blocked) +{ + u8 param = blocked ? A1655_WIFI_OFF : A1655_WIFI_ON; + int rc; + + i8042_lock_chip(); + rc = i8042_command(¶m, A1655_WIFI_COMMAND); + i8042_unlock_chip(); + return rc; +} + +static const struct rfkill_ops amilo_a1655_rfkill_ops = { + .set_block = amilo_a1655_rfkill_set_block +}; + +/* + * These values were obtained from disassembling the PM.exe program + * installed in the Fujitsu-Siemens AMILO M 7440 + */ +#define M7440_PORT1 0x118f +#define M7440_PORT2 0x118e +#define M7440_RADIO_ON1 0x12 +#define M7440_RADIO_ON2 0x80 +#define M7440_RADIO_OFF1 0x10 +#define M7440_RADIO_OFF2 0x00 + +static int amilo_m7440_rfkill_set_block(void *data, bool blocked) +{ + u8 val1 = blocked ? M7440_RADIO_OFF1 : M7440_RADIO_ON1; + u8 val2 = blocked ? M7440_RADIO_OFF2 : M7440_RADIO_ON2; + + outb(val1, M7440_PORT1); + outb(val2, M7440_PORT2); + + /* Check whether the state has changed correctly */ + if (inb(M7440_PORT1) != val1 || inb(M7440_PORT2) != val2) + return -EIO; + + return 0; +} + +static const struct rfkill_ops amilo_m7440_rfkill_ops = { + .set_block = amilo_m7440_rfkill_set_block +}; + +static const struct dmi_system_id __devinitdata amilo_rfkill_id_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_BOARD_NAME, "AMILO A1655"), + }, + .driver_data = (void *)&amilo_a1655_rfkill_ops + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_BOARD_NAME, "AMILO M7440"), + }, + .driver_data = (void *)&amilo_m7440_rfkill_ops + }, + {} +}; + +static struct platform_device *amilo_rfkill_pdev; +static struct rfkill *amilo_rfkill_dev; + +static int __devinit amilo_rfkill_probe(struct platform_device *device) +{ + const struct dmi_system_id *system_id = + dmi_first_match(amilo_rfkill_id_table); + int rc; + + amilo_rfkill_dev = rfkill_alloc(KBUILD_MODNAME, &device->dev, + RFKILL_TYPE_WLAN, + system_id->driver_data, NULL); + if (!amilo_rfkill_dev) + return -ENOMEM; + + rc = rfkill_register(amilo_rfkill_dev); + if (rc) + goto fail; + + return 0; + +fail: + rfkill_destroy(amilo_rfkill_dev); + return rc; +} + +static int amilo_rfkill_remove(struct platform_device *device) +{ + rfkill_unregister(amilo_rfkill_dev); + rfkill_destroy(amilo_rfkill_dev); + return 0; +} + +static struct platform_driver amilo_rfkill_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + }, + .probe = amilo_rfkill_probe, + .remove = amilo_rfkill_remove, +}; + +static int __init amilo_rfkill_init(void) +{ + int rc; + + if (dmi_first_match(amilo_rfkill_id_table) == NULL) + return -ENODEV; + + rc = platform_driver_register(&amilo_rfkill_driver); + if (rc) + return rc; + + amilo_rfkill_pdev = platform_device_register_simple(KBUILD_MODNAME, -1, + NULL, 0); + if (IS_ERR(amilo_rfkill_pdev)) { + rc = PTR_ERR(amilo_rfkill_pdev); + goto fail; + } + + return 0; + +fail: + platform_driver_unregister(&amilo_rfkill_driver); + return rc; +} + +static void __exit amilo_rfkill_exit(void) +{ + platform_device_unregister(amilo_rfkill_pdev); + platform_driver_unregister(&amilo_rfkill_driver); +} + +MODULE_AUTHOR("Ben Hutchings <[email protected]>"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(dmi, amilo_rfkill_id_table); + +module_init(amilo_rfkill_init); +module_exit(amilo_rfkill_exit); diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c new file mode 100644 index 000000000000..580d80a73c3a --- /dev/null +++ b/drivers/platform/x86/fujitsu-tablet.c @@ -0,0 +1,478 @@ +/* + * Copyright (C) 2006-2012 Robert Gerlach <[email protected]> + * Copyright (C) 2005-2006 Jan Rychter <[email protected]> + * + * You can redistribute and/or modify this program under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation. + * + * 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, write to the Free Software Foundation, Inc., + * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/acpi.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/input.h> +#include <linux/delay.h> +#include <linux/dmi.h> + +#define MODULENAME "fujitsu-tablet" + +#define ACPI_FUJITSU_CLASS "fujitsu" + +#define INVERT_TABLET_MODE_BIT 0x01 +#define FORCE_TABLET_MODE_IF_UNDOCK 0x02 + +#define KEYMAP_LEN 16 + +static const struct acpi_device_id fujitsu_ids[] = { + { .id = "FUJ02BD" }, + { .id = "FUJ02BF" }, + { .id = "" } +}; + +struct fujitsu_config { + unsigned short keymap[KEYMAP_LEN]; + unsigned int quirks; +}; + +static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initconst = { + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_SCROLLDOWN, + KEY_SCROLLUP, + KEY_DIRECTION, + KEY_LEFTCTRL, + KEY_BRIGHTNESSUP, + KEY_BRIGHTNESSDOWN, + KEY_BRIGHTNESS_ZERO, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_LEFTALT +}; + +static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initconst = { + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_PROG1, + KEY_PROG2, + KEY_DIRECTION, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_UP, + KEY_DOWN, + KEY_RESERVED, + KEY_RESERVED, + KEY_LEFTCTRL, + KEY_LEFTALT +}; + +static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initconst = { + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_PRINT, + KEY_BACKSPACE, + KEY_SPACE, + KEY_ENTER, + KEY_BRIGHTNESSUP, + KEY_BRIGHTNESSDOWN, + KEY_DOWN, + KEY_UP, + KEY_SCROLLUP, + KEY_SCROLLDOWN, + KEY_LEFTCTRL, + KEY_LEFTALT +}; + +static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initconst = { + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + KEY_MAIL, + KEY_DIRECTION, + KEY_ESC, + KEY_ENTER, + KEY_BRIGHTNESSUP, + KEY_BRIGHTNESSDOWN, + KEY_DOWN, + KEY_UP, + KEY_SCROLLUP, + KEY_SCROLLDOWN, + KEY_LEFTCTRL, + KEY_LEFTALT +}; + +static struct { + struct input_dev *idev; + struct fujitsu_config config; + unsigned long prev_keymask; + + char phys[21]; + + int irq; + int io_base; + int io_length; +} fujitsu; + +static u8 fujitsu_ack(void) +{ + return inb(fujitsu.io_base + 2); +} + +static u8 fujitsu_status(void) +{ + return inb(fujitsu.io_base + 6); +} + +static u8 fujitsu_read_register(const u8 addr) +{ + outb(addr, fujitsu.io_base); + return inb(fujitsu.io_base + 4); +} + +static void fujitsu_send_state(void) +{ + int state; + int dock, tablet_mode; + + state = fujitsu_read_register(0xdd); + + dock = state & 0x02; + + if ((fujitsu.config.quirks & FORCE_TABLET_MODE_IF_UNDOCK) && (!dock)) { + tablet_mode = 1; + } else{ + tablet_mode = state & 0x01; + if (fujitsu.config.quirks & INVERT_TABLET_MODE_BIT) + tablet_mode = !tablet_mode; + } + + input_report_switch(fujitsu.idev, SW_DOCK, dock); + input_report_switch(fujitsu.idev, SW_TABLET_MODE, tablet_mode); + input_sync(fujitsu.idev); +} + +static void fujitsu_reset(void) +{ + int timeout = 50; + + fujitsu_ack(); + + while ((fujitsu_status() & 0x02) && (--timeout)) + msleep(20); + + fujitsu_send_state(); +} + +static int __devinit input_fujitsu_setup(struct device *parent, + const char *name, const char *phys) +{ + struct input_dev *idev; + int error; + int i; + + idev = input_allocate_device(); + if (!idev) + return -ENOMEM; + + idev->dev.parent = parent; + idev->phys = phys; + idev->name = name; + idev->id.bustype = BUS_HOST; + idev->id.vendor = 0x1734; /* Fujitsu Siemens Computer GmbH */ + idev->id.product = 0x0001; + idev->id.version = 0x0101; + + idev->keycode = fujitsu.config.keymap; + idev->keycodesize = sizeof(fujitsu.config.keymap[0]); + idev->keycodemax = ARRAY_SIZE(fujitsu.config.keymap); + + __set_bit(EV_REP, idev->evbit); + + for (i = 0; i < ARRAY_SIZE(fujitsu.config.keymap); i++) + if (fujitsu.config.keymap[i]) + input_set_capability(idev, EV_KEY, fujitsu.config.keymap[i]); + + input_set_capability(idev, EV_MSC, MSC_SCAN); + + input_set_capability(idev, EV_SW, SW_DOCK); + input_set_capability(idev, EV_SW, SW_TABLET_MODE); + + input_set_capability(idev, EV_SW, SW_DOCK); + input_set_capability(idev, EV_SW, SW_TABLET_MODE); + + error = input_register_device(idev); + if (error) { + input_free_device(idev); + return error; + } + + fujitsu.idev = idev; + return 0; +} + +static void input_fujitsu_remove(void) +{ + input_unregister_device(fujitsu.idev); +} + +static irqreturn_t fujitsu_interrupt(int irq, void *dev_id) +{ + unsigned long keymask, changed; + unsigned int keycode; + int pressed; + int i; + + if (unlikely(!(fujitsu_status() & 0x01))) + return IRQ_NONE; + + fujitsu_send_state(); + + keymask = fujitsu_read_register(0xde); + keymask |= fujitsu_read_register(0xdf) << 8; + keymask ^= 0xffff; + + changed = keymask ^ fujitsu.prev_keymask; + if (changed) { + fujitsu.prev_keymask = keymask; + + for_each_set_bit(i, &changed, KEYMAP_LEN) { + keycode = fujitsu.config.keymap[i]; + pressed = keymask & changed & BIT(i); + + if (pressed) + input_event(fujitsu.idev, EV_MSC, MSC_SCAN, i); + + input_report_key(fujitsu.idev, keycode, pressed); + input_sync(fujitsu.idev); + } + } + + fujitsu_ack(); + return IRQ_HANDLED; +} + +static int __devinit fujitsu_dmi_default(const struct dmi_system_id *dmi) +{ + printk(KERN_INFO MODULENAME ": %s\n", dmi->ident); + memcpy(fujitsu.config.keymap, dmi->driver_data, + sizeof(fujitsu.config.keymap)); + return 1; +} + +static int __devinit fujitsu_dmi_stylistic(const struct dmi_system_id *dmi) +{ + fujitsu_dmi_default(dmi); + fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK; + fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT; + return 1; +} + +static struct dmi_system_id dmi_ids[] __initconst = { + { + .callback = fujitsu_dmi_default, + .ident = "Fujitsu Siemens P/T Series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK") + }, + .driver_data = keymap_Lifebook_Tseries + }, + { + .callback = fujitsu_dmi_default, + .ident = "Fujitsu Lifebook T Series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook T") + }, + .driver_data = keymap_Lifebook_Tseries + }, + { + .callback = fujitsu_dmi_stylistic, + .ident = "Fujitsu Siemens Stylistic T Series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic T") + }, + .driver_data = keymap_Stylistic_Tseries + }, + { + .callback = fujitsu_dmi_default, + .ident = "Fujitsu LifeBook U810", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook U810") + }, + .driver_data = keymap_Lifebook_U810 + }, + { + .callback = fujitsu_dmi_stylistic, + .ident = "Fujitsu Siemens Stylistic ST5xxx Series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "STYLISTIC ST5") + }, + .driver_data = keymap_Stylistic_ST5xxx + }, + { + .callback = fujitsu_dmi_stylistic, + .ident = "Fujitsu Siemens Stylistic ST5xxx Series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic ST5") + }, + .driver_data = keymap_Stylistic_ST5xxx + }, + { + .callback = fujitsu_dmi_default, + .ident = "Unknown (using defaults)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, ""), + DMI_MATCH(DMI_PRODUCT_NAME, "") + }, + .driver_data = keymap_Lifebook_Tseries + }, + { NULL } +}; + +static acpi_status __devinit +fujitsu_walk_resources(struct acpi_resource *res, void *data) +{ + switch (res->type) { + case ACPI_RESOURCE_TYPE_IRQ: + fujitsu.irq = res->data.irq.interrupts[0]; + return AE_OK; + + case ACPI_RESOURCE_TYPE_IO: + fujitsu.io_base = res->data.io.minimum; + fujitsu.io_length = res->data.io.address_length; + return AE_OK; + + case ACPI_RESOURCE_TYPE_END_TAG: + if (fujitsu.irq && fujitsu.io_base) + return AE_OK; + else + return AE_NOT_FOUND; + + default: + return AE_ERROR; + } +} + +static int __devinit acpi_fujitsu_add(struct acpi_device *adev) +{ + acpi_status status; + int error; + + if (!adev) + return -EINVAL; + + status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, + fujitsu_walk_resources, NULL); + if (ACPI_FAILURE(status) || !fujitsu.irq || !fujitsu.io_base) + return -ENODEV; + + sprintf(acpi_device_name(adev), "Fujitsu %s", acpi_device_hid(adev)); + sprintf(acpi_device_class(adev), "%s", ACPI_FUJITSU_CLASS); + + snprintf(fujitsu.phys, sizeof(fujitsu.phys), + "%s/input0", acpi_device_hid(adev)); + + error = input_fujitsu_setup(&adev->dev, + acpi_device_name(adev), fujitsu.phys); + if (error) + return error; + + if (!request_region(fujitsu.io_base, fujitsu.io_length, MODULENAME)) { + input_fujitsu_remove(); + return -EBUSY; + } + + fujitsu_reset(); + + error = request_irq(fujitsu.irq, fujitsu_interrupt, + IRQF_SHARED, MODULENAME, fujitsu_interrupt); + if (error) { + release_region(fujitsu.io_base, fujitsu.io_length); + input_fujitsu_remove(); + return error; + } + + return 0; +} + +static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type) +{ + free_irq(fujitsu.irq, fujitsu_interrupt); + release_region(fujitsu.io_base, fujitsu.io_length); + input_fujitsu_remove(); + return 0; +} + +static int acpi_fujitsu_resume(struct acpi_device *adev) +{ + fujitsu_reset(); + return 0; +} + +static struct acpi_driver acpi_fujitsu_driver = { + .name = MODULENAME, + .class = "hotkey", + .ids = fujitsu_ids, + .ops = { + .add = acpi_fujitsu_add, + .remove = acpi_fujitsu_remove, + .resume = acpi_fujitsu_resume, + } +}; + +static int __init fujitsu_module_init(void) +{ + int error; + + dmi_check_system(dmi_ids); + + error = acpi_bus_register_driver(&acpi_fujitsu_driver); + if (error) + return error; + + return 0; +} + +static void __exit fujitsu_module_exit(void) +{ + acpi_bus_unregister_driver(&acpi_fujitsu_driver); +} + +module_init(fujitsu_module_init); +module_exit(fujitsu_module_exit); + +MODULE_AUTHOR("Robert Gerlach <[email protected]>"); +MODULE_DESCRIPTION("Fujitsu tablet pc extras driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("2.4"); + +MODULE_DEVICE_TABLE(acpi, fujitsu_ids); diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 05be30ee158b..ffff8b4b4949 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -562,8 +562,8 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) num_sifr = acpi_pcc_get_sqty(device); - if (num_sifr > 255) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large")); + if (num_sifr < 0 || num_sifr > 255) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr out of range")); return -ENODEV; } diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 10451a15e828..f519a131238d 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -340,6 +340,6 @@ no_region: subsys_initcall(ptp_init); module_exit(ptp_exit); -MODULE_AUTHOR("Richard Cochran <[email protected]>"); +MODULE_AUTHOR("Richard Cochran <[email protected]>"); MODULE_DESCRIPTION("PTP clocks support"); MODULE_LICENSE("GPL"); diff --git a/drivers/ptp/ptp_ixp46x.c b/drivers/ptp/ptp_ixp46x.c index 803d665b15ef..6f2782bb5f41 100644 --- a/drivers/ptp/ptp_ixp46x.c +++ b/drivers/ptp/ptp_ixp46x.c @@ -327,6 +327,6 @@ no_master: module_init(ptp_ixp_init); module_exit(ptp_ixp_exit); -MODULE_AUTHOR("Richard Cochran <[email protected]>"); +MODULE_AUTHOR("Richard Cochran <[email protected]>"); MODULE_DESCRIPTION("PTP clock using the IXP46X timer"); MODULE_LICENSE("GPL"); diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index 822e54c394d5..1c226b31af13 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h @@ -118,34 +118,34 @@ #define TSI721_IDB_ENTRY_SIZE 64 -#define TSI721_IDQ_CTL(x) (0x20000 + (x) * 1000) +#define TSI721_IDQ_CTL(x) (0x20000 + (x) * 0x1000) #define TSI721_IDQ_SUSPEND 0x00000002 #define TSI721_IDQ_INIT 0x00000001 -#define TSI721_IDQ_STS(x) (0x20004 + (x) * 1000) +#define TSI721_IDQ_STS(x) (0x20004 + (x) * 0x1000) #define TSI721_IDQ_RUN 0x00200000 -#define TSI721_IDQ_MASK(x) (0x20008 + (x) * 1000) +#define TSI721_IDQ_MASK(x) (0x20008 + (x) * 0x1000) #define TSI721_IDQ_MASK_MASK 0xffff0000 #define TSI721_IDQ_MASK_PATT 0x0000ffff -#define TSI721_IDQ_RP(x) (0x2000c + (x) * 1000) +#define TSI721_IDQ_RP(x) (0x2000c + (x) * 0x1000) #define TSI721_IDQ_RP_PTR 0x0007ffff -#define TSI721_IDQ_WP(x) (0x20010 + (x) * 1000) +#define TSI721_IDQ_WP(x) (0x20010 + (x) * 0x1000) #define TSI721_IDQ_WP_PTR 0x0007ffff -#define TSI721_IDQ_BASEL(x) (0x20014 + (x) * 1000) +#define TSI721_IDQ_BASEL(x) (0x20014 + (x) * 0x1000) #define TSI721_IDQ_BASEL_ADDR 0xffffffc0 -#define TSI721_IDQ_BASEU(x) (0x20018 + (x) * 1000) -#define TSI721_IDQ_SIZE(x) (0x2001c + (x) * 1000) +#define TSI721_IDQ_BASEU(x) (0x20018 + (x) * 0x1000) +#define TSI721_IDQ_SIZE(x) (0x2001c + (x) * 0x1000) #define TSI721_IDQ_SIZE_VAL(size) (__fls(size) - 4) #define TSI721_IDQ_SIZE_MIN 512 #define TSI721_IDQ_SIZE_MAX (512 * 1024) -#define TSI721_SR_CHINT(x) (0x20040 + (x) * 1000) -#define TSI721_SR_CHINTE(x) (0x20044 + (x) * 1000) -#define TSI721_SR_CHINTSET(x) (0x20048 + (x) * 1000) +#define TSI721_SR_CHINT(x) (0x20040 + (x) * 0x1000) +#define TSI721_SR_CHINTE(x) (0x20044 + (x) * 0x1000) +#define TSI721_SR_CHINTSET(x) (0x20048 + (x) * 0x1000) #define TSI721_SR_CHINT_ODBOK 0x00000020 #define TSI721_SR_CHINT_IDBQRCV 0x00000010 #define TSI721_SR_CHINT_SUSP 0x00000008 @@ -156,7 +156,7 @@ #define TSI721_IBWIN_NUM 8 -#define TSI721_IBWINLB(x) (0x29000 + (x) * 20) +#define TSI721_IBWINLB(x) (0x29000 + (x) * 0x20) #define TSI721_IBWINLB_BA 0xfffff000 #define TSI721_IBWINLB_WEN 0x00000001 @@ -187,13 +187,13 @@ */ #define TSI721_OBWIN_NUM TSI721_PC2SR_WINS -#define TSI721_OBWINLB(x) (0x40000 + (x) * 20) +#define TSI721_OBWINLB(x) (0x40000 + (x) * 0x20) #define TSI721_OBWINLB_BA 0xffff8000 #define TSI721_OBWINLB_WEN 0x00000001 -#define TSI721_OBWINUB(x) (0x40004 + (x) * 20) +#define TSI721_OBWINUB(x) (0x40004 + (x) * 0x20) -#define TSI721_OBWINSZ(x) (0x40008 + (x) * 20) +#define TSI721_OBWINSZ(x) (0x40008 + (x) * 0x20) #define TSI721_OBWINSZ_SIZE 0x00001f00 #define TSI721_OBWIN_SIZE(size) (__fls(size) - 15) diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index ea4d8f575ac6..09915e89705d 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -226,7 +226,7 @@ static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev, if (min_uV < info->min_uV) min_uV = info->min_uV; - *selector = (min_uV - info->min_uV) / info->step_uV; + *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); ret = da9052_list_voltage(rdev, *selector); if (ret < 0) @@ -318,10 +318,10 @@ static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV, if ((regulator->da9052->chip_id == DA9052) && (min_uV >= DA9052_CONST_3uV)) *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV + - ((min_uV - DA9052_CONST_3uV) / - (DA9052_BUCK_PERI_3uV_STEP)); + DIV_ROUND_UP(min_uV - DA9052_CONST_3uV, + DA9052_BUCK_PERI_3uV_STEP); else - *selector = (min_uV - info->min_uV) / info->step_uV; + *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); ret = da9052_list_buckperi_voltage(rdev, *selector); if (ret < 0) @@ -400,6 +400,7 @@ static struct regulator_ops da9052_ldo_ops = { .ops = &da9052_ldo5_6_ops,\ .type = REGULATOR_VOLTAGE,\ .id = _id,\ + .n_voltages = (max - min) / step + 1, \ .owner = THIS_MODULE,\ },\ .min_uV = (min) * 1000,\ @@ -417,6 +418,7 @@ static struct regulator_ops da9052_ldo_ops = { .ops = &da9052_ldo_ops,\ .type = REGULATOR_VOLTAGE,\ .id = _id,\ + .n_voltages = (max - min) / step + 1, \ .owner = THIS_MODULE,\ },\ .min_uV = (min) * 1000,\ @@ -434,6 +436,7 @@ static struct regulator_ops da9052_ldo_ops = { .ops = &da9052_dcdc_ops,\ .type = REGULATOR_VOLTAGE,\ .id = _id,\ + .n_voltages = (max - min) / step + 1, \ .owner = THIS_MODULE,\ },\ .min_uV = (min) * 1000,\ @@ -451,6 +454,7 @@ static struct regulator_ops da9052_ldo_ops = { .ops = &da9052_buckperi_ops,\ .type = REGULATOR_VOLTAGE,\ .id = _id,\ + .n_voltages = (max - min) / step + 1, \ .owner = THIS_MODULE,\ },\ .min_uV = (min) * 1000,\ diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 70b7b1f4f000..2e94686b6fe6 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -481,7 +481,7 @@ static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, if (i >= info->n_voltages) i = info->n_voltages - 1; - *selector = info->voltages[i]; + *selector = i; return write_field(hw, &info->voltage, i); } diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 44262908def5..501b27c18145 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1028,7 +1028,7 @@ done: return iscsit_add_reject_from_cmd( ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1, 1, buf, cmd); - } else if (transport_ret == -EINVAL) { + } else if (transport_ret < 0) { /* * Unsupported SAM Opcode. CHECK_CONDITION will be sent * in iscsit_execute_cmd() during the CmdSN OOO Execution diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index b7c779389eea..63e703bb6ac9 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -117,7 +117,7 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, struct se_node_acl *, struct se_session *); static void core_scsi3_put_pr_reg(struct t10_pr_registration *); -static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) +static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) { struct se_session *se_sess = cmd->se_sess; struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; @@ -127,7 +127,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) int conflict = 0; if (!crh) - return false; + return -EINVAL; pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, se_sess); @@ -155,16 +155,14 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) */ if (pr_reg->pr_res_holder) { core_scsi3_put_pr_reg(pr_reg); - *ret = 0; - return false; + return 1; } if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) || (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { core_scsi3_put_pr_reg(pr_reg); - *ret = 0; - return true; + return 1; } core_scsi3_put_pr_reg(pr_reg); conflict = 1; @@ -189,10 +187,10 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) " while active SPC-3 registrations exist," " returning RESERVATION_CONFLICT\n"); cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; - return true; + return -EBUSY; } - return false; + return 0; } int target_scsi2_reservation_release(struct se_task *task) @@ -201,12 +199,18 @@ int target_scsi2_reservation_release(struct se_task *task) struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; struct se_portal_group *tpg = sess->se_tpg; - int ret = 0; + int ret = 0, rc; if (!sess || !tpg) goto out; - if (target_check_scsi2_reservation_conflict(cmd, &ret)) + rc = target_check_scsi2_reservation_conflict(cmd); + if (rc == 1) + goto out; + else if (rc < 0) { + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; + ret = -EINVAL; goto out; + } ret = 0; spin_lock(&dev->dev_reservation_lock); @@ -243,7 +247,7 @@ int target_scsi2_reservation_reserve(struct se_task *task) struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; struct se_portal_group *tpg = sess->se_tpg; - int ret = 0; + int ret = 0, rc; if ((cmd->t_task_cdb[1] & 0x01) && (cmd->t_task_cdb[1] & 0x02)) { @@ -259,8 +263,14 @@ int target_scsi2_reservation_reserve(struct se_task *task) */ if (!sess || !tpg) goto out; - if (target_check_scsi2_reservation_conflict(cmd, &ret)) + rc = target_check_scsi2_reservation_conflict(cmd); + if (rc == 1) goto out; + else if (rc < 0) { + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; + ret = -EINVAL; + goto out; + } ret = 0; spin_lock(&dev->dev_reservation_lock); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 58cea07b12fb..cd5cd95812bb 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2539,6 +2539,7 @@ static int transport_generic_cmd_sequencer( cmd, cdb, pr_reg_type) != 0) { cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; + cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; return -EBUSY; } diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 75085795528e..61b7fd2729cd 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1710,6 +1710,8 @@ static int sci_startup(struct uart_port *port) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + pm_runtime_put_noidle(port->dev); + sci_port_enable(s); ret = sci_request_irq(s); @@ -1737,6 +1739,8 @@ static void sci_shutdown(struct uart_port *port) sci_free_irq(s); sci_port_disable(s); + + pm_runtime_get_noresume(port->dev); } static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, @@ -2075,6 +2079,7 @@ static int __devinit sci_init_single(struct platform_device *dev, sci_init_gpios(sci_port); pm_runtime_irq_safe(&dev->dev); + pm_runtime_get_noresume(&dev->dev); pm_runtime_enable(&dev->dev); } diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c index e132157d8545..516db703dd24 100644 --- a/drivers/video/backlight/s6e63m0.c +++ b/drivers/video/backlight/s6e63m0.c @@ -690,7 +690,7 @@ static ssize_t s6e63m0_sysfs_store_gamma_mode(struct device *dev, struct backlight_device *bd = NULL; int brightness, rc; - rc = strict_strtoul(buf, 0, (unsigned long *)&lcd->gamma_mode); + rc = kstrtouint(buf, 0, &lcd->gamma_mode); if (rc < 0) return rc; diff --git a/fs/afs/internal.h b/fs/afs/internal.h index d2b0888126d4..a306bb6d88d9 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -109,7 +109,7 @@ struct afs_call { unsigned reply_size; /* current size of reply */ unsigned first_offset; /* offset into mapping[first] */ unsigned last_to; /* amount of mapping[last] */ - unsigned short offset; /* offset into received data store */ + unsigned offset; /* offset into received data store */ unsigned char unmarshall; /* unmarshalling phase */ bool incoming; /* T if incoming call */ bool send_pages; /* T if data from mapping should be sent */ diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index e45a323aebb4..8ad8c2a0703a 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -314,6 +314,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, struct msghdr msg; struct kvec iov[1]; int ret; + struct sk_buff *skb; _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); @@ -380,6 +381,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, error_do_abort: rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); + while ((skb = skb_dequeue(&call->rx_queue))) + afs_free_skb(skb); rxrpc_kernel_end_call(rxcall); call->rxcall = NULL; error_kill_call: @@ -228,12 +228,6 @@ static void __put_ioctx(struct kioctx *ctx) call_rcu(&ctx->rcu_head, ctx_rcu_free); } -static inline void get_ioctx(struct kioctx *kioctx) -{ - BUG_ON(atomic_read(&kioctx->users) <= 0); - atomic_inc(&kioctx->users); -} - static inline int try_get_ioctx(struct kioctx *kioctx) { return atomic_inc_not_zero(&kioctx->users); @@ -273,7 +267,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) mm = ctx->mm = current->mm; atomic_inc(&mm->mm_count); - atomic_set(&ctx->users, 1); + atomic_set(&ctx->users, 2); spin_lock_init(&ctx->ctx_lock); spin_lock_init(&ctx->ring_info.ring_lock); init_waitqueue_head(&ctx->wait); @@ -609,11 +603,16 @@ static void aio_fput_routine(struct work_struct *data) fput(req->ki_filp); /* Link the iocb into the context's free list */ + rcu_read_lock(); spin_lock_irq(&ctx->ctx_lock); really_put_req(ctx, req); + /* + * at that point ctx might've been killed, but actual + * freeing is RCU'd + */ spin_unlock_irq(&ctx->ctx_lock); + rcu_read_unlock(); - put_ioctx(ctx); spin_lock_irq(&fput_lock); } spin_unlock_irq(&fput_lock); @@ -644,7 +643,6 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) * this function will be executed w/out any aio kthread wakeup. */ if (unlikely(!fput_atomic(req->ki_filp))) { - get_ioctx(ctx); spin_lock(&fput_lock); list_add(&req->ki_list, &fput_head); spin_unlock(&fput_lock); @@ -1338,10 +1336,10 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) ret = PTR_ERR(ioctx); if (!IS_ERR(ioctx)) { ret = put_user(ioctx->user_id, ctxp); - if (!ret) + if (!ret) { + put_ioctx(ioctx); return 0; - - get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */ + } io_destroy(ioctx); } diff --git a/fs/block_dev.c b/fs/block_dev.c index 0e575d1304b4..5e9f198f7712 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1183,8 +1183,12 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) * The latter is necessary to prevent ghost * partitions on a removed medium. */ - if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) - rescan_partitions(disk, bdev); + if (bdev->bd_invalidated) { + if (!ret) + rescan_partitions(disk, bdev); + else if (ret == -ENOMEDIUM) + invalidate_partitions(disk, bdev); + } if (ret) goto out_clear; } else { @@ -1214,8 +1218,12 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) if (bdev->bd_disk->fops->open) ret = bdev->bd_disk->fops->open(bdev, mode); /* the same as first opener case, read comment there */ - if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) - rescan_partitions(bdev->bd_disk, bdev); + if (bdev->bd_invalidated) { + if (!ret) + rescan_partitions(bdev->bd_disk, bdev); + else if (ret == -ENOMEDIUM) + invalidate_partitions(bdev->bd_disk, bdev); + } if (ret) goto out_unlock_bdev; } diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 98f6bf10bbd4..0436c12da8c2 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -583,7 +583,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, struct btrfs_path *path; struct btrfs_key info_key = { 0 }; struct btrfs_delayed_ref_root *delayed_refs = NULL; - struct btrfs_delayed_ref_head *head = NULL; + struct btrfs_delayed_ref_head *head; int info_level = 0; int ret; struct list_head prefs_delayed; @@ -607,6 +607,8 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, * at a specified point in time */ again: + head = NULL; + ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); if (ret < 0) goto out; @@ -635,8 +637,10 @@ again: goto again; } ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); - if (ret) + if (ret) { + spin_unlock(&delayed_refs->lock); goto out; + } } spin_unlock(&delayed_refs->lock); diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index 2373b39a132b..22db04550f6a 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c @@ -305,7 +305,7 @@ again: spin_lock(&fs_info->reada_lock); ret = radix_tree_insert(&dev->reada_zones, - (unsigned long)zone->end >> PAGE_CACHE_SHIFT, + (unsigned long)(zone->end >> PAGE_CACHE_SHIFT), zone); spin_unlock(&fs_info->reada_lock); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 4dd9283885e7..5e64748a2917 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -920,16 +920,26 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) for (lockp = &inode->i_flock; *lockp != NULL; \ lockp = &(*lockp)->fl_next) +struct lock_to_push { + struct list_head llist; + __u64 offset; + __u64 length; + __u32 pid; + __u16 netfid; + __u8 type; +}; + static int cifs_push_posix_locks(struct cifsFileInfo *cfile) { struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); struct file_lock *flock, **before; - struct cifsLockInfo *lck, *tmp; + unsigned int count = 0, i = 0; int rc = 0, xid, type; + struct list_head locks_to_send, *el; + struct lock_to_push *lck, *tmp; __u64 length; - struct list_head locks_to_send; xid = GetXid(); @@ -940,29 +950,55 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) return rc; } + lock_flocks(); + cifs_for_each_lock(cfile->dentry->d_inode, before) { + if ((*before)->fl_flags & FL_POSIX) + count++; + } + unlock_flocks(); + INIT_LIST_HEAD(&locks_to_send); + /* + * Allocating count locks is enough because no locks can be added to + * the list while we are holding cinode->lock_mutex that protects + * locking operations of this inode. + */ + for (; i < count; i++) { + lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); + if (!lck) { + rc = -ENOMEM; + goto err_out; + } + list_add_tail(&lck->llist, &locks_to_send); + } + + i = 0; + el = locks_to_send.next; lock_flocks(); cifs_for_each_lock(cfile->dentry->d_inode, before) { + if (el == &locks_to_send) { + /* something is really wrong */ + cERROR(1, "Can't push all brlocks!"); + break; + } flock = *before; + if ((flock->fl_flags & FL_POSIX) == 0) + continue; length = 1 + flock->fl_end - flock->fl_start; if (flock->fl_type == F_RDLCK || flock->fl_type == F_SHLCK) type = CIFS_RDLCK; else type = CIFS_WRLCK; - - lck = cifs_lock_init(flock->fl_start, length, type, - cfile->netfid); - if (!lck) { - rc = -ENOMEM; - goto send_locks; - } + lck = list_entry(el, struct lock_to_push, llist); lck->pid = flock->fl_pid; - - list_add_tail(&lck->llist, &locks_to_send); + lck->netfid = cfile->netfid; + lck->length = length; + lck->type = type; + lck->offset = flock->fl_start; + i++; + el = el->next; } - -send_locks: unlock_flocks(); list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { @@ -979,11 +1015,18 @@ send_locks: kfree(lck); } +out: cinode->can_cache_brlcks = false; mutex_unlock(&cinode->lock_mutex); FreeXid(xid); return rc; +err_out: + list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) { + list_del(&lck->llist); + kfree(lck); + } + goto out; } static int diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 45f07c46f3ed..10d92cf57ab6 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -105,7 +105,6 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, struct cifs_tcon *pTcon; struct super_block *sb; char *full_path; - struct cifs_ntsd *pacl; if (direntry == NULL) return -EIO; @@ -164,23 +163,24 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, strlen(CIFS_XATTR_CIFS_ACL)) == 0) { +#ifdef CONFIG_CIFS_ACL + struct cifs_ntsd *pacl; pacl = kmalloc(value_size, GFP_KERNEL); if (!pacl) { cFYI(1, "%s: Can't allocate memory for ACL", __func__); rc = -ENOMEM; } else { -#ifdef CONFIG_CIFS_ACL memcpy(pacl, ea_value, value_size); rc = set_cifs_acl(pacl, value_size, direntry->d_inode, full_path, CIFS_ACL_DACL); if (rc == 0) /* force revalidate of the inode */ CIFS_I(direntry->d_inode)->time = 0; kfree(pacl); + } #else cFYI(1, "Set CIFS ACL not supported yet"); #endif /* CONFIG_CIFS_ACL */ - } } else { int temp; temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS, diff --git a/fs/eventpoll.c b/fs/eventpoll.c index ea54cdef04dd..4d9d3a45e356 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -988,6 +988,10 @@ static int path_count[PATH_ARR_SIZE]; static int path_count_inc(int nests) { + /* Allow an arbitrary number of depth 1 paths */ + if (nests == 0) + return 0; + if (++path_count[nests] > path_limits[nests]) return -1; return 0; diff --git a/fs/inode.c b/fs/inode.c index d3ebdbe723d0..83ab215baab1 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -938,8 +938,7 @@ void lockdep_annotate_inode_mutex_key(struct inode *inode) struct file_system_type *type = inode->i_sb->s_type; /* Set new key only if filesystem hasn't already changed it */ - if (!lockdep_match_class(&inode->i_mutex, - &type->i_mutex_key)) { + if (lockdep_match_class(&inode->i_mutex, &type->i_mutex_key)) { /* * ensure nobody is actually holding i_mutex */ @@ -966,6 +965,7 @@ void unlock_new_inode(struct inode *inode) spin_lock(&inode->i_lock); WARN_ON(!(inode->i_state & I_NEW)); inode->i_state &= ~I_NEW; + smp_mb(); wake_up_bit(&inode->i_state, __I_NEW); spin_unlock(&inode->i_lock); } diff --git a/fs/namei.c b/fs/namei.c index e2ba62820a0f..46ea9cc16647 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2162,7 +2162,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, /* sayonara */ error = complete_walk(nd); if (error) - return ERR_PTR(-ECHILD); + return ERR_PTR(error); error = -ENOTDIR; if (nd->flags & LOOKUP_DIRECTORY) { @@ -2261,7 +2261,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ error = complete_walk(nd); if (error) - goto exit; + return ERR_PTR(error); error = -EISDIR; if (S_ISDIR(nd->inode->i_mode)) goto exit; diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index d32714094375..501b7f8b739f 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -409,6 +409,12 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs, nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block); nilfs->ns_r_segments_percentage = le32_to_cpu(sbp->s_r_segments_percentage); + if (nilfs->ns_r_segments_percentage < 1 || + nilfs->ns_r_segments_percentage > 99) { + printk(KERN_ERR "NILFS: invalid reserved segments percentage.\n"); + return -EINVAL; + } + nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments)); nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed); return 0; @@ -515,6 +521,7 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, brelse(sbh[1]); sbh[1] = NULL; sbp[1] = NULL; + valid[1] = 0; swp = 0; } if (!valid[swp]) { diff --git a/fs/udf/file.c b/fs/udf/file.c index dca0c3881e82..d567b8448dfc 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -201,12 +201,10 @@ out: static int udf_release_file(struct inode *inode, struct file *filp) { if (filp->f_mode & FMODE_WRITE) { - mutex_lock(&inode->i_mutex); down_write(&UDF_I(inode)->i_data_sem); udf_discard_prealloc(inode); udf_truncate_tail_extent(inode); up_write(&UDF_I(inode)->i_data_sem); - mutex_unlock(&inode->i_mutex); } return 0; } diff --git a/include/linux/genhd.h b/include/linux/genhd.h index fe23ee768589..e61d3192448e 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -596,6 +596,7 @@ extern char *disk_name (struct gendisk *hd, int partno, char *buf); extern int disk_expand_part_tbl(struct gendisk *disk, int target); extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); +extern int invalidate_partitions(struct gendisk *disk, struct block_device *bdev); extern struct hd_struct * __must_check add_partition(struct gendisk *disk, int partno, sector_t start, sector_t len, int flags, diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 5f8146695b7f..597f4a9f3240 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -139,6 +139,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS))) #define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER) +#define IN_DEV_ARP_ACCEPT(in_dev) IN_DEV_ORCONF((in_dev), ARP_ACCEPT) #define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE) #define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE) #define IN_DEV_ARP_NOTIFY(in_dev) IN_DEV_MAXCONF((in_dev), ARP_NOTIFY) diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index 119773eebe31..1a3018063034 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h @@ -6,8 +6,11 @@ #include <linux/workqueue.h> enum { - ICQ_IOPRIO_CHANGED, - ICQ_CGROUP_CHANGED, + ICQ_IOPRIO_CHANGED = 1 << 0, + ICQ_CGROUP_CHANGED = 1 << 1, + ICQ_EXITED = 1 << 2, + + ICQ_CHANGED_MASK = ICQ_IOPRIO_CHANGED | ICQ_CGROUP_CHANGED, }; /* @@ -88,7 +91,7 @@ struct io_cq { struct rcu_head __rcu_head; }; - unsigned long changed; + unsigned int flags; }; /* @@ -139,6 +142,7 @@ struct io_context *get_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node); void ioc_ioprio_changed(struct io_context *ioc, int ioprio); void ioc_cgroup_changed(struct io_context *ioc); +unsigned int icq_get_changed(struct io_cq *icq); #else struct io_context; static inline void put_io_context(struct io_context *ioc) { } diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c37d67add090..e474f6e780cc 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -369,6 +369,11 @@ * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. + * Background scan period can optionally be + * specified in %NL80211_ATTR_BG_SCAN_PERIOD, + * if not specified default background scan configuration + * in driver is used and if period value is 0, bg scan will be disabled. + * This attribute is ignored if driver does not support roam scan. * It is also sent as an event, with the BSSID and response IEs when the * connection is established or failed to be established. This can be * determined by the STATUS_CODE attribute. @@ -1207,6 +1212,9 @@ enum nl80211_commands { * this attribute is (depending on the driver capabilities) added to * received frames indicated with %NL80211_CMD_FRAME. * + * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds + * or 0 to disable background scan. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1456,6 +1464,8 @@ enum nl80211_attrs { NL80211_ATTR_RX_SIGNAL_DBM, + NL80211_ATTR_BG_SCAN_PERIOD, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index eb8b9f15f2e0..af155450cabb 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -289,12 +289,16 @@ enum { * * system_freezable_wq is equivalent to system_wq except that it's * freezable. + * + * system_nrt_freezable_wq is equivalent to system_nrt_wq except that + * it's freezable. */ extern struct workqueue_struct *system_wq; extern struct workqueue_struct *system_long_wq; extern struct workqueue_struct *system_nrt_wq; extern struct workqueue_struct *system_unbound_wq; extern struct workqueue_struct *system_freezable_wq; +extern struct workqueue_struct *system_nrt_freezable_wq; extern struct workqueue_struct * __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 57c9fddc2acf..69b7ad3a9925 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1203,6 +1203,8 @@ struct cfg80211_ibss_params { * @key_idx: index of WEP key for shared key authentication * @key: WEP key for shared key authentication * @flags: See &enum cfg80211_assoc_req_flags + * @bg_scan_period: Background scan period in seconds + * or -1 to indicate that default value is to be used. * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask * will be used in ht_capa. Un-supported values will be ignored. * @ht_capa_mask: The bits of ht_capa which are to be used. @@ -1220,6 +1222,7 @@ struct cfg80211_connect_params { const u8 *key; u8 key_len, key_idx; u32 flags; + int bg_scan_period; struct ieee80211_ht_cap ht_capa; struct ieee80211_ht_cap ht_capa_mask; }; @@ -2694,7 +2697,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, * @wiphy: the wiphy reporting the BSS * @channel: The channel the frame was received on * @bssid: the BSSID of the BSS - * @timestamp: the TSF timestamp sent by the peer + * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) * @capability: the capability field sent by the peer * @beacon_interval: the beacon interval announced by the peer * @ie: additional IEs sent by the peer @@ -2710,9 +2713,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, struct cfg80211_bss * __must_check cfg80211_inform_bss(struct wiphy *wiphy, struct ieee80211_channel *channel, - const u8 *bssid, - u64 timestamp, u16 capability, u16 beacon_interval, - const u8 *ie, size_t ielen, + const u8 *bssid, u64 tsf, u16 capability, + u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp); struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f7917f765cbc..9a012be615ff 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -229,7 +229,8 @@ enum ieee80211_rssi_event { * valid in station mode only while @assoc is true and if also * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf * @ps_dtim_period) - * @timestamp: beacon timestamp + * @last_tsf: last beacon's/probe response's TSF timestamp (could be old + * as it may have been received during scanning long ago) * @beacon_int: beacon interval * @assoc_capability: capabilities taken from assoc resp * @basic_rates: bitmap of basic rates, each bit stands for an @@ -276,7 +277,7 @@ struct ieee80211_bss_conf { u8 dtim_period; u16 beacon_int; u16 assoc_capability; - u64 timestamp; + u64 last_tsf; u32 basic_rates; int mcast_rate[IEEE80211_NUM_BANDS]; u16 ht_operation_mode; @@ -1766,20 +1767,6 @@ enum ieee80211_ampdu_mlme_action { }; /** - * enum ieee80211_tx_sync_type - TX sync type - * @IEEE80211_TX_SYNC_AUTH: sync TX for authentication - * (and possibly also before direct probe) - * @IEEE80211_TX_SYNC_ASSOC: sync TX for association - * @IEEE80211_TX_SYNC_ACTION: sync TX for action frame - * (not implemented yet) - */ -enum ieee80211_tx_sync_type { - IEEE80211_TX_SYNC_AUTH, - IEEE80211_TX_SYNC_ASSOC, - IEEE80211_TX_SYNC_ACTION, -}; - -/** * enum ieee80211_frame_release_type - frame release reason * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to @@ -1889,26 +1876,6 @@ enum ieee80211_frame_release_type { * of the bss parameters has changed when a call is made. The callback * can sleep. * - * @tx_sync: Called before a frame is sent to an AP/GO. In the GO case, the - * driver should sync with the GO's powersaving so the device doesn't - * transmit the frame while the GO is asleep. In the regular AP case - * it may be used by drivers for devices implementing other restrictions - * on talking to APs, e.g. due to regulatory enforcement or just HW - * restrictions. - * This function is called for every authentication, association and - * action frame separately since applications might attempt to auth - * with multiple APs before chosing one to associate to. If it returns - * an error, the corresponding authentication, association or frame - * transmission is aborted and reported as having failed. It is always - * called after tuning to the correct channel. - * The callback might be called multiple times before @finish_tx_sync - * (but @finish_tx_sync will be called once for each) but in practice - * this is unlikely to happen. It can also refuse in that case if the - * driver cannot handle that situation. - * This callback can sleep. - * @finish_tx_sync: Called as a counterpart to @tx_sync, unless that returned - * an error. This callback can sleep. - * * @prepare_multicast: Prepare for multicast filter configuration. * This callback is optional, and its return value is passed * to configure_filter(). This callback must be atomic. @@ -2180,13 +2147,6 @@ struct ieee80211_ops { struct ieee80211_bss_conf *info, u32 changed); - int (*tx_sync)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - const u8 *bssid, enum ieee80211_tx_sync_type type); - void (*finish_tx_sync)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - const u8 *bssid, - enum ieee80211_tx_sync_type type); - u64 (*prepare_multicast)(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list); void (*configure_filter)(struct ieee80211_hw *hw, diff --git a/kernel/sys.c b/kernel/sys.c index 40701538fbd1..888d227fd195 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1706,7 +1706,7 @@ static int prctl_set_mm(int opt, unsigned long addr, if (arg4 | arg5) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_RESOURCE)) return -EPERM; if (addr >= TASK_SIZE) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index bec7b5b53e03..f2c5638bb5ab 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -253,11 +253,13 @@ struct workqueue_struct *system_long_wq __read_mostly; struct workqueue_struct *system_nrt_wq __read_mostly; struct workqueue_struct *system_unbound_wq __read_mostly; struct workqueue_struct *system_freezable_wq __read_mostly; +struct workqueue_struct *system_nrt_freezable_wq __read_mostly; EXPORT_SYMBOL_GPL(system_wq); EXPORT_SYMBOL_GPL(system_long_wq); EXPORT_SYMBOL_GPL(system_nrt_wq); EXPORT_SYMBOL_GPL(system_unbound_wq); EXPORT_SYMBOL_GPL(system_freezable_wq); +EXPORT_SYMBOL_GPL(system_nrt_freezable_wq); #define CREATE_TRACE_POINTS #include <trace/events/workqueue.h> @@ -3833,8 +3835,11 @@ static int __init init_workqueues(void) WQ_UNBOUND_MAX_ACTIVE); system_freezable_wq = alloc_workqueue("events_freezable", WQ_FREEZABLE, 0); + system_nrt_freezable_wq = alloc_workqueue("events_nrt_freezable", + WQ_NON_REENTRANT | WQ_FREEZABLE, 0); BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq || - !system_unbound_wq || !system_freezable_wq); + !system_unbound_wq || !system_freezable_wq || + !system_nrt_freezable_wq); return 0; } early_initcall(init_workqueues); diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c index 3d1bdcdd7db4..6ab4587d052b 100644 --- a/lib/dynamic_queue_limits.c +++ b/lib/dynamic_queue_limits.c @@ -7,6 +7,7 @@ #include <linux/types.h> #include <linux/ctype.h> #include <linux/kernel.h> +#include <linux/jiffies.h> #include <linux/dynamic_queue_limits.h> #define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 5585dc3d3646..58a08fc7414a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -230,10 +230,30 @@ struct mem_cgroup { * the counter to account for memory usage */ struct res_counter res; - /* - * the counter to account for mem+swap usage. - */ - struct res_counter memsw; + + union { + /* + * the counter to account for mem+swap usage. + */ + struct res_counter memsw; + + /* + * rcu_freeing is used only when freeing struct mem_cgroup, + * so put it into a union to avoid wasting more memory. + * It must be disjoint from the css field. It could be + * in a union with the res field, but res plays a much + * larger part in mem_cgroup life than memsw, and might + * be of interest, even at time of free, when debugging. + * So share rcu_head with the less interesting memsw. + */ + struct rcu_head rcu_freeing; + /* + * But when using vfree(), that cannot be done at + * interrupt time, so we must then queue the work. + */ + struct work_struct work_freeing; + }; + /* * Per cgroup active and inactive list, similar to the * per zone LRU lists. @@ -4780,6 +4800,27 @@ out_free: } /* + * Helpers for freeing a vzalloc()ed mem_cgroup by RCU, + * but in process context. The work_freeing structure is overlaid + * on the rcu_freeing structure, which itself is overlaid on memsw. + */ +static void vfree_work(struct work_struct *work) +{ + struct mem_cgroup *memcg; + + memcg = container_of(work, struct mem_cgroup, work_freeing); + vfree(memcg); +} +static void vfree_rcu(struct rcu_head *rcu_head) +{ + struct mem_cgroup *memcg; + + memcg = container_of(rcu_head, struct mem_cgroup, rcu_freeing); + INIT_WORK(&memcg->work_freeing, vfree_work); + schedule_work(&memcg->work_freeing); +} + +/* * At destroying mem_cgroup, references from swap_cgroup can remain. * (scanning all at force_empty is too costly...) * @@ -4802,9 +4843,9 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg) free_percpu(memcg->stat); if (sizeof(struct mem_cgroup) < PAGE_SIZE) - kfree(memcg); + kfree_rcu(memcg, rcu_freeing); else - vfree(memcg); + call_rcu(&memcg->rcu_freeing, vfree_rcu); } static void mem_cgroup_get(struct mem_cgroup *memcg) @@ -5075,7 +5116,7 @@ static struct page *mc_handle_present_pte(struct vm_area_struct *vma, return NULL; if (PageAnon(page)) { /* we don't move shared anon */ - if (!move_anon() || page_mapcount(page) > 1) + if (!move_anon() || page_mapcount(page) > 2) return NULL; } else if (!move_file()) /* we ignore mapcount for file pages */ diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 63e49890ad31..73f46d691abc 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -889,7 +889,7 @@ static int arp_process(struct sk_buff *skb) n = __neigh_lookup(&arp_tbl, &sip, dev, 0); - if (IPV4_DEVCONF_ALL(dev_net(dev), ARP_ACCEPT)) { + if (IN_DEV_ARP_ACCEPT(in_dev)) { /* Unsolicited ARP is not accepted by default. It is possible, that this option should be enabled for some devices (strip is candidate) diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 51fdbb490437..eab2a7fb15d1 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -278,6 +278,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct rtable *rt; __u8 rcv_wscale; bool ecn_ok = false; + struct flowi4 fl4; if (!sysctl_tcp_syncookies || !th->ack || th->rst) goto out; @@ -346,20 +347,16 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, * hasn't changed since we received the original syn, but I see * no easy way to do this. */ - { - struct flowi4 fl4; - - flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), - RT_SCOPE_UNIVERSE, IPPROTO_TCP, - inet_sk_flowi_flags(sk), - (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, - ireq->loc_addr, th->source, th->dest); - security_req_classify_flow(req, flowi4_to_flowi(&fl4)); - rt = ip_route_output_key(sock_net(sk), &fl4); - if (IS_ERR(rt)) { - reqsk_free(req); - goto out; - } + flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), + RT_SCOPE_UNIVERSE, IPPROTO_TCP, + inet_sk_flowi_flags(sk), + (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, + ireq->loc_addr, th->source, th->dest); + security_req_classify_flow(req, flowi4_to_flowi(&fl4)); + rt = ip_route_output_key(sock_net(sk), &fl4); + if (IS_ERR(rt)) { + reqsk_free(req); + goto out; } /* Try to redo what tcp_v4_send_synack did. */ @@ -373,5 +370,10 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ireq->rcv_wscale = rcv_wscale; ret = get_cookie_sock(sk, skb, req, &rt->dst); + /* ip_queue_xmit() depends on our flow being setup + * Normal sockets get it right from inet_csk_route_child_sock() + */ + if (ret) + inet_sk(ret)->cork.fl.u.ip4 = fl4; out: return ret; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index fe9f604ed1e2..3a25cf743f8b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1470,9 +1470,13 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; newinet->inet_id = newtp->write_seq ^ jiffies; - if (!dst && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL) - goto put_and_exit; - + if (!dst) { + dst = inet_csk_route_child_sock(sk, newsk, req); + if (!dst) + goto put_and_exit; + } else { + /* syncookie case : see end of cookie_v4_check() */ + } sk_setup_caps(newsk, dst); tcp_mtup_init(newsk); diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index b853f06cc148..16c33e308121 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -257,7 +257,6 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, if (rt) { dev = rt->dst.dev; - dev_hold(dev); dst_release(&rt->dst); } } else diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 92be12bb8d23..24c456e8aa1d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1090,7 +1090,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct net *net = dev_net(dev); if (unlikely(!idev)) - return NULL; + return ERR_PTR(-ENODEV); rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); if (unlikely(!rt)) { diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index d1f7abddb182..e00ce8c3e28e 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -3,6 +3,7 @@ */ #include <linux/nl80211.h> +#include <net/cfg80211.h> #include "ieee80211_i.h" static enum ieee80211_chan_mode @@ -134,3 +135,29 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local, return result; } + +/* + * ieee80211_get_tx_channel_type returns the channel type we should + * use for packet transmission, given the channel capability and + * whatever regulatory flags we have been given. + */ +enum nl80211_channel_type ieee80211_get_tx_channel_type( + struct ieee80211_local *local, + enum nl80211_channel_type channel_type) +{ + switch (channel_type) { + case NL80211_CHAN_HT40PLUS: + if (local->hw.conf.channel->flags & + IEEE80211_CHAN_NO_HT40PLUS) + return NL80211_CHAN_HT20; + break; + case NL80211_CHAN_HT40MINUS: + if (local->hw.conf.channel->flags & + IEEE80211_CHAN_NO_HT40MINUS) + return NL80211_CHAN_HT20; + break; + default: + break; + } + return channel_type; +} diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 483e96ed95c1..cc5b7a6e7e0b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -97,85 +97,6 @@ static const struct file_operations reset_ops = { .llseek = noop_llseek, }; -static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", - local->uapsd_queues); -} - -static ssize_t uapsd_queues_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - u8 val; - int ret; - - ret = kstrtou8_from_user(user_buf, count, 0, &val); - if (ret) - return ret; - - if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) - return -ERANGE; - - local->uapsd_queues = val; - - return count; -} - -static const struct file_operations uapsd_queues_ops = { - .read = uapsd_queues_read, - .write = uapsd_queues_write, - .open = mac80211_open_file_generic, - .llseek = default_llseek, -}; - -static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - - return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", - local->uapsd_max_sp_len); -} - -static ssize_t uapsd_max_sp_len_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ieee80211_local *local = file->private_data; - unsigned long val; - char buf[10]; - size_t len; - int ret; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - - ret = kstrtoul(buf, 0, &val); - - if (ret) - return -EINVAL; - - if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) - return -ERANGE; - - local->uapsd_max_sp_len = val; - - return count; -} - -static const struct file_operations uapsd_max_sp_len_ops = { - .read = uapsd_max_sp_len_read, - .write = uapsd_max_sp_len_write, - .open = mac80211_open_file_generic, - .llseek = default_llseek, -}; - static ssize_t channel_type_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -362,8 +283,6 @@ void debugfs_hw_add(struct ieee80211_local *local) DEBUGFS_ADD(wep_iv); DEBUGFS_ADD(queues); DEBUGFS_ADD_MODE(reset, 0200); - DEBUGFS_ADD(uapsd_queues); - DEBUGFS_ADD(uapsd_max_sp_len); DEBUGFS_ADD(channel_type); DEBUGFS_ADD(hwflags); DEBUGFS_ADD(user_power); diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index f6de8a65f402..a32eeda04aa3 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -49,16 +49,15 @@ static ssize_t ieee80211_if_write( size_t count, loff_t *ppos, ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) { - u8 *buf; + char buf[64]; ssize_t ret; - buf = kmalloc(count, GFP_KERNEL); - if (!buf) - return -ENOMEM; + if (count >= sizeof(buf)) + return -E2BIG; - ret = -EFAULT; if (copy_from_user(buf, userbuf, count)) - goto freebuf; + return -EFAULT; + buf[count] = '\0'; ret = -ENODEV; rtnl_lock(); @@ -66,8 +65,6 @@ static ssize_t ieee80211_if_write( ret = (*write)(sdata, buf, count); rtnl_unlock(); -freebuf: - kfree(buf); return ret; } @@ -340,6 +337,62 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( __IEEE80211_IF_FILE_W(tkip_mic_test); +static ssize_t ieee80211_if_fmt_uapsd_queues( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_queues); +} + +static ssize_t ieee80211_if_parse_uapsd_queues( + struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + u8 val; + int ret; + + ret = kstrtou8(buf, 0, &val); + if (ret) + return ret; + + if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) + return -ERANGE; + + ifmgd->uapsd_queues = val; + + return buflen; +} +__IEEE80211_IF_FILE_W(uapsd_queues); + +static ssize_t ieee80211_if_fmt_uapsd_max_sp_len( + const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) +{ + const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_max_sp_len); +} + +static ssize_t ieee80211_if_parse_uapsd_max_sp_len( + struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 0, &val); + if (ret) + return -EINVAL; + + if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) + return -ERANGE; + + ifmgd->uapsd_max_sp_len = val; + + return buflen; +} +__IEEE80211_IF_FILE_W(uapsd_max_sp_len); + /* AP attributes */ IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC); IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); @@ -472,6 +525,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) DEBUGFS_ADD(ave_beacon); DEBUGFS_ADD_MODE(smps, 0600); DEBUGFS_ADD_MODE(tkip_mic_test, 0200); + DEBUGFS_ADD_MODE(uapsd_queues, 0600); + DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); } static void add_ap_files(struct ieee80211_sub_if_data *sdata) diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 70dfb6415c20..af4691fed645 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -168,41 +168,6 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, trace_drv_return_void(local); } -static inline int drv_tx_sync(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - int ret = 0; - - might_sleep(); - - check_sdata_in_driver(sdata); - - trace_drv_tx_sync(local, sdata, bssid, type); - if (local->ops->tx_sync) - ret = local->ops->tx_sync(&local->hw, &sdata->vif, - bssid, type); - trace_drv_return_int(local, ret); - return ret; -} - -static inline void drv_finish_tx_sync(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - might_sleep(); - - check_sdata_in_driver(sdata); - - trace_drv_finish_tx_sync(local, sdata, bssid, type); - if (local->ops->finish_tx_sync) - local->ops->finish_tx_sync(&local->hw, &sdata->vif, - bssid, type); - trace_drv_return_void(local); -} - static inline u64 drv_prepare_multicast(struct ieee80211_local *local, struct netdev_hw_addr_list *mc_list) { diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 384e2f08c187..21d6f5290a1c 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -296,7 +296,7 @@ TRACE_EVENT(drv_bss_info_changed, __entry->dtimper = info->dtim_period; __entry->bcnint = info->beacon_int; __entry->assoc_cap = info->assoc_capability; - __entry->timestamp = info->timestamp; + __entry->timestamp = info->last_tsf; __entry->basic_rates = info->basic_rates; __entry->enable_beacon = info->enable_beacon; __entry->ht_operation_mode = info->ht_operation_mode; @@ -308,49 +308,6 @@ TRACE_EVENT(drv_bss_info_changed, ) ); -DECLARE_EVENT_CLASS(tx_sync_evt, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type), - TP_ARGS(local, sdata, bssid, type), - - TP_STRUCT__entry( - LOCAL_ENTRY - VIF_ENTRY - __array(char, bssid, ETH_ALEN) - __field(u32, sync_type) - ), - - TP_fast_assign( - LOCAL_ASSIGN; - VIF_ASSIGN; - memcpy(__entry->bssid, bssid, ETH_ALEN); - __entry->sync_type = type; - ), - - TP_printk( - LOCAL_PR_FMT VIF_PR_FMT " bssid:%pM type:%d", - LOCAL_PR_ARG, VIF_PR_ARG, __entry->bssid, __entry->sync_type - ) -); - -DEFINE_EVENT(tx_sync_evt, drv_tx_sync, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type), - TP_ARGS(local, sdata, bssid, type) -); - -DEFINE_EVENT(tx_sync_evt, drv_finish_tx_sync, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - const u8 *bssid, - enum ieee80211_tx_sync_type type), - TP_ARGS(local, sdata, bssid, type) -); - TRACE_EVENT(drv_prepare_multicast, TP_PROTO(struct ieee80211_local *local, int mc_count), diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 796b13bfc953..d9798a307f20 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -388,7 +388,6 @@ struct ieee80211_mgd_auth_data { u8 key[WLAN_KEY_LEN_WEP104]; u8 key_len, key_idx; - bool synced; bool done; size_t ie_len; @@ -408,7 +407,7 @@ struct ieee80211_mgd_assoc_data { u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 ssid_len; u8 supp_rates_len; - bool wmm_used, uapsd_used; + bool wmm, uapsd; bool have_beacon; bool sent_assoc; bool synced; @@ -460,6 +459,20 @@ struct ieee80211_if_managed { IEEE80211_MFP_REQUIRED } mfp; /* management frame protection */ + /* + * Bitmask of enabled u-apsd queues, + * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association + * to take effect. + */ + unsigned int uapsd_queues; + + /* + * Maximum number of buffered frames AP can deliver during a + * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. + * Needs a new association to take effect. + */ + unsigned int uapsd_max_sp_len; + int wmm_last_param_set; u8 use_4addr; @@ -1018,20 +1031,6 @@ struct ieee80211_local { */ unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ - /* - * Bitmask of enabled u-apsd queues, - * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association - * to take effect. - */ - unsigned int uapsd_queues; - - /* - * Maximum number of buffered frames AP can deliver during a - * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. - * Needs a new association to take effect. - */ - unsigned int uapsd_max_sp_len; - bool pspolling; bool offchannel_ps_enabled; /* @@ -1503,6 +1502,9 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local, enum nl80211_channel_type chantype); enum nl80211_channel_type ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info); +enum nl80211_channel_type ieee80211_get_tx_channel_type( + struct ieee80211_local *local, + enum nl80211_channel_type channel_type); #ifdef CONFIG_MAC80211_NOINLINE #define debug_noinline noinline diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 36fa8051296c..b581a24fa15c 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -595,8 +595,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; local->user_power_level = -1; - local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; - local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; INIT_LIST_HEAD(&local->interfaces); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c08924aeac00..576fb25456dd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -189,40 +189,35 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, u16 ht_opmode; bool enable_ht = true; enum nl80211_channel_type prev_chantype; - enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; + enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT; + enum nl80211_channel_type tx_channel_type; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - prev_chantype = sdata->vif.bss_conf.channel_type; - /* HT is not supported */ - if (!sband->ht_cap.ht_supported) - enable_ht = false; - if (enable_ht) { - hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, - sband->band); - /* check that channel matches the right operating channel */ - if (local->hw.conf.channel->center_freq != hti_cfreq) { - /* Some APs mess this up, evidently. - * Netgear WNDR3700 sometimes reports 4 higher than - * the actual channel, for instance. - */ - printk(KERN_DEBUG - "%s: Wrong control channel in association" - " response: configured center-freq: %d" - " hti-cfreq: %d hti->control_chan: %d" - " band: %d. Disabling HT.\n", - sdata->name, - local->hw.conf.channel->center_freq, - hti_cfreq, hti->control_chan, - sband->band); - enable_ht = false; - } + hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, + sband->band); + /* check that channel matches the right operating channel */ + if (local->hw.conf.channel->center_freq != hti_cfreq) { + /* Some APs mess this up, evidently. + * Netgear WNDR3700 sometimes reports 4 higher than + * the actual channel, for instance. + */ + printk(KERN_DEBUG + "%s: Wrong control channel in association" + " response: configured center-freq: %d" + " hti-cfreq: %d hti->control_chan: %d" + " band: %d. Disabling HT.\n", + sdata->name, + local->hw.conf.channel->center_freq, + hti_cfreq, hti->control_chan, + sband->band); + enable_ht = false; } if (enable_ht) { - channel_type = NL80211_CHAN_HT20; + rx_channel_type = NL80211_CHAN_HT20; if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && !ieee80111_cfg_override_disables_ht40(sdata) && @@ -230,29 +225,28 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - if (!(local->hw.conf.channel->flags & - IEEE80211_CHAN_NO_HT40PLUS)) - channel_type = NL80211_CHAN_HT40PLUS; + rx_channel_type = NL80211_CHAN_HT40PLUS; break; case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - if (!(local->hw.conf.channel->flags & - IEEE80211_CHAN_NO_HT40MINUS)) - channel_type = NL80211_CHAN_HT40MINUS; + rx_channel_type = NL80211_CHAN_HT40MINUS; break; } } } + tx_channel_type = ieee80211_get_tx_channel_type(local, rx_channel_type); + if (local->tmp_channel) - local->tmp_channel_type = channel_type; + local->tmp_channel_type = rx_channel_type; - if (!ieee80211_set_channel_type(local, sdata, channel_type)) { + if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) { /* can only fail due to HT40+/- mismatch */ - channel_type = NL80211_CHAN_HT20; - WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); + rx_channel_type = NL80211_CHAN_HT20; + WARN_ON(!ieee80211_set_channel_type(local, sdata, + rx_channel_type)); } - if (beacon_htcap_ie && (prev_chantype != channel_type)) { + if (beacon_htcap_ie && (prev_chantype != rx_channel_type)) { /* * Whenever the AP announces the HT mode change that can be * 40MHz intolerant or etc., it would be safer to stop tx @@ -270,13 +264,13 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, /* channel_type change automatically detected */ ieee80211_hw_config(local, 0); - if (prev_chantype != channel_type) { + if (prev_chantype != tx_channel_type) { rcu_read_lock(); sta = sta_info_get(sdata, bssid); if (sta) rate_control_rate_update(local, sband, sta, IEEE80211_RC_HT_CHANGED, - channel_type); + tx_channel_type); rcu_read_unlock(); if (beacon_htcap_ie) @@ -289,7 +283,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, /* if bss configuration changed store the new one */ if (sdata->ht_opmode_valid != enable_ht || sdata->vif.bss_conf.ht_operation_mode != ht_opmode || - prev_chantype != channel_type) { + prev_chantype != rx_channel_type) { changed |= BSS_CHANGED_HT; sdata->vif.bss_conf.ht_operation_mode = ht_opmode; sdata->ht_opmode_valid = enable_ht; @@ -335,9 +329,6 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); - if (!sband->ht_cap.ht_supported) - return; - if (!ht_info_ie) return; @@ -405,7 +396,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) u16 capab; struct ieee80211_supported_band *sband; u32 rates = 0; - struct ieee80211_bss *bss = (void *)assoc_data->bss->priv; lockdep_assert_held(&ifmgd->mtx); @@ -566,8 +556,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) offset = noffset; } - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) && - bss->wmm_used && local->hw.queues >= 4) + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie, sband, local->oper_channel, ifmgd->ap_smps); @@ -581,10 +570,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) offset = noffset; } - if (assoc_data->wmm_used && local->hw.queues >= 4) { - if (assoc_data->uapsd_used) { - qos_info = local->uapsd_queues; - qos_info |= (local->uapsd_max_sp_len << + if (assoc_data->wmm) { + if (assoc_data->uapsd) { + qos_info = ifmgd->uapsd_queues; + qos_info |= (ifmgd->uapsd_max_sp_len << IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); } else { qos_info = 0; @@ -1203,7 +1192,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, return; if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) - uapsd_queues = local->uapsd_queues; + uapsd_queues = ifmgd->uapsd_queues; count = wmm_param[6] & 0x0f; if (count == ifmgd->wmm_last_param_set) @@ -1329,7 +1318,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_ASSOC; /* set timing information */ bss_conf->beacon_int = cbss->beacon_interval; - bss_conf->timestamp = cbss->tsf; + bss_conf->last_tsf = cbss->tsf; bss_info_changed |= BSS_CHANGED_BEACON_INT; bss_info_changed |= ieee80211_handle_bss_capability(sdata, @@ -1355,15 +1344,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_conf->dtim_period = 0; bss_conf->assoc = 1; - /* - * For now just always ask the driver to update the basic rateset - * when we have associated, we aren't checking whether it actually - * changed or not. - */ - bss_info_changed |= BSS_CHANGED_BASIC_RATES; - - /* And the BSSID changed - we're associated now */ - bss_info_changed |= BSS_CHANGED_BSSID; /* Tell the driver to monitor connection quality (if supported) */ if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && @@ -1394,7 +1374,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - u32 changed = 0, config_changed = 0; + u32 changed = 0; u8 bssid[ETH_ALEN]; ASSERT_MGD_MTX(ifmgd); @@ -1454,9 +1434,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_ASSOC; sdata->vif.bss_conf.assoc = false; - /* channel(_type) changes are handled by ieee80211_hw_config */ - WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); - /* on the next assoc, re-program HT parameters */ sdata->ht_opmode_valid = false; memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); @@ -1469,12 +1446,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, if (local->hw.conf.flags & IEEE80211_CONF_PS) { local->hw.conf.flags &= ~IEEE80211_CONF_PS; - config_changed |= IEEE80211_CONF_CHANGE_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); } local->ps_sdata = NULL; - ieee80211_hw_config(local, config_changed); - /* Disable ARP filtering */ if (sdata->vif.bss_conf.arp_filter_enabled) { sdata->vif.bss_conf.arp_filter_enabled = false; @@ -1488,6 +1463,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; ieee80211_bss_info_change_notify(sdata, changed); + /* channel(_type) changes are handled by ieee80211_hw_config */ + WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); + ieee80211_hw_config(local, 0); + /* disassociated - set to defaults now */ ieee80211_set_wmm_default(sdata, false); @@ -1770,11 +1749,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, lockdep_assert_held(&sdata->u.mgd.mtx); - if (auth_data->synced) - drv_finish_tx_sync(sdata->local, sdata, - auth_data->bss->bssid, - IEEE80211_TX_SYNC_AUTH); - if (!assoc) { sta_info_destroy_addr(sdata, auth_data->bss->bssid); @@ -1862,10 +1836,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: authenticated\n", sdata->name); out: - if (ifmgd->auth_data->synced) - drv_finish_tx_sync(sdata->local, sdata, bssid, - IEEE80211_TX_SYNC_AUTH); - ifmgd->auth_data->synced = false; ifmgd->auth_data->done = true; ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -2005,11 +1975,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, lockdep_assert_held(&sdata->u.mgd.mtx); - if (assoc_data->synced) - drv_finish_tx_sync(sdata->local, sdata, - assoc_data->bss->bssid, - IEEE80211_TX_SYNC_ASSOC); - if (!assoc) { sta_info_destroy_addr(sdata, assoc_data->bss->bssid); @@ -2030,15 +1995,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, struct ieee80211_supported_band *sband; struct sta_info *sta; u8 *pos; - u32 rates, basic_rates; u16 capab_info, aid; struct ieee802_11_elems elems; struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; u32 changed = 0; int err; - bool have_higher_than_11mbit = false; u16 ap_ht_cap_flags; - int min_rate = INT_MAX, min_rate_index = -1; /* AssocResp and ReassocResp have identical structure */ @@ -2083,39 +2045,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, return false; } - rates = 0; - basic_rates = 0; sband = local->hw.wiphy->bands[local->oper_channel->band]; - ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len, - &rates, &basic_rates, &have_higher_than_11mbit, - &min_rate, &min_rate_index); - - ieee80211_get_rates(sband, elems.ext_supp_rates, - elems.ext_supp_rates_len, &rates, &basic_rates, - &have_higher_than_11mbit, - &min_rate, &min_rate_index); - - /* - * some buggy APs don't advertise basic_rates. use the lowest - * supported rate instead. - */ - if (unlikely(!basic_rates) && min_rate_index >= 0) { - printk(KERN_DEBUG "%s: No basic rates in AssocResp. " - "Using min supported rate instead.\n", sdata->name); - basic_rates = BIT(min_rate_index); - } - - sta->sta.supp_rates[local->oper_channel->band] = rates; - sdata->vif.bss_conf.basic_rates = basic_rates; - - /* cf. IEEE 802.11 9.2.12 */ - if (local->oper_channel->band == IEEE80211_BAND_2GHZ && - have_higher_than_11mbit) - sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; - else - sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; - if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, elems.ht_cap_elem, &sta->sta.ht_cap); @@ -2162,7 +2093,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_QOS; if (elems.ht_info_elem && elems.wmm_param && - (sdata->local->hw.queues >= 4) && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, cbss->bssid, ap_ht_cap_flags, @@ -2255,14 +2185,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, } else { printk(KERN_DEBUG "%s: associated\n", sdata->name); - /* tell driver about sync done first */ - if (assoc_data->synced) { - drv_finish_tx_sync(sdata->local, sdata, - assoc_data->bss->bssid, - IEEE80211_TX_SYNC_ASSOC); - assoc_data->synced = false; - } - if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { /* oops -- internal error -- send timeout for now */ ieee80211_destroy_assoc_data(sdata, true); @@ -2747,14 +2669,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) if (WARN_ON_ONCE(!auth_data)) return -EINVAL; - if (!auth_data->synced) { - int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid, - IEEE80211_TX_SYNC_AUTH); - if (ret) - return ret; - } - auth_data->synced = true; - auth_data->tries++; if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { @@ -2811,14 +2725,6 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&sdata->u.mgd.mtx); - if (!assoc_data->synced) { - int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid, - IEEE80211_TX_SYNC_ASSOC); - if (ret) - return ret; - } - assoc_data->synced = true; - assoc_data->tries++; if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { printk(KERN_DEBUG "%s: association with %pM timed out\n", @@ -3107,6 +3013,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ifmgd->flags = 0; ifmgd->powersave = sdata->wdev.ps; + ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; + ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; mutex_init(&ifmgd->mtx); @@ -3143,6 +3051,101 @@ int ieee80211_max_network_latency(struct notifier_block *nb, return 0; } +static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, + struct cfg80211_bss *cbss, bool assoc) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_bss *bss = (void *)cbss->priv; + struct sta_info *sta; + bool have_sta = false; + int err; + + if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) + return -EINVAL; + + if (assoc) { + rcu_read_lock(); + have_sta = sta_info_get(sdata, cbss->bssid); + rcu_read_unlock(); + } + + if (!have_sta) { + sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); + if (!sta) + return -ENOMEM; + } + + mutex_lock(&local->mtx); + ieee80211_recalc_idle(sdata->local); + mutex_unlock(&local->mtx); + + /* switch to the right channel */ + local->oper_channel = cbss->channel; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); + + if (!have_sta) { + struct ieee80211_supported_band *sband; + u32 rates = 0, basic_rates = 0; + bool have_higher_than_11mbit; + int min_rate = INT_MAX, min_rate_index = -1; + + sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; + + ieee80211_get_rates(sband, bss->supp_rates, + bss->supp_rates_len, + &rates, &basic_rates, + &have_higher_than_11mbit, + &min_rate, &min_rate_index); + + /* + * This used to be a workaround for basic rates missing + * in the association response frame. Now that we no + * longer use the basic rates from there, it probably + * doesn't happen any more, but keep the workaround so + * in case some *other* APs are buggy in different ways + * we can connect -- with a warning. + */ + if (!basic_rates && min_rate_index >= 0) { + printk(KERN_DEBUG + "%s: No basic rates, using min rate instead.\n", + sdata->name); + basic_rates = BIT(min_rate_index); + } + + sta->sta.supp_rates[cbss->channel->band] = rates; + sdata->vif.bss_conf.basic_rates = basic_rates; + + /* cf. IEEE 802.11 9.2.12 */ + if (local->oper_channel->band == IEEE80211_BAND_2GHZ && + have_higher_than_11mbit) + sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; + else + sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; + + memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); + + /* tell driver about BSSID and basic rates */ + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES); + + if (assoc) + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); + + err = sta_info_insert(sta); + sta = NULL; + if (err) { + printk(KERN_DEBUG + "%s: failed to insert STA entry for the AP (error %d)\n", + sdata->name, err); + return err; + } + } else + WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid)); + + return 0; +} + /* config hooks */ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, struct cfg80211_auth_request *req) @@ -3150,7 +3153,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_mgd_auth_data *auth_data; - struct sta_info *sta; u16 auth_alg; int err; @@ -3216,38 +3218,12 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: authenticate with %pM\n", sdata->name, req->bss->bssid); - mutex_lock(&local->mtx); - ieee80211_recalc_idle(sdata->local); - mutex_unlock(&local->mtx); - - /* switch to the right channel */ - local->oper_channel = req->bss->channel; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - - /* set BSSID */ - memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); - - /* add station entry */ - sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); - if (!sta) { - err = -ENOMEM; + err = ieee80211_prep_connection(sdata, req->bss, false); + if (err) goto err_clear; - } - - err = sta_info_insert(sta); - if (err) { - printk(KERN_DEBUG - "%s: failed to insert STA entry for the AP %pM (error %d)\n", - sdata->name, req->bss->bssid, err); - goto err_clear; - } err = ieee80211_probe_auth(sdata); if (err) { - if (auth_data->synced) - drv_finish_tx_sync(local, sdata, req->bss->bssid, - IEEE80211_TX_SYNC_AUTH); sta_info_destroy_addr(sdata, req->bss->bssid); goto err_clear; } @@ -3274,7 +3250,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_bss *bss = (void *)req->bss->priv; struct ieee80211_mgd_assoc_data *assoc_data; - struct sta_info *sta; + struct ieee80211_supported_band *sband; const u8 *ssidie; int i, err; @@ -3316,6 +3292,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ifmgd->beacon_crc_valid = false; + /* + * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. + * We still associate in non-HT mode (11a/b/g) if any one of these + * ciphers is configured as pairwise. + * We can set this to true for non-11n hardware, that'll be checked + * separately along with the peer capabilities. + */ for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || @@ -3325,6 +3308,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, if (req->flags & ASSOC_REQ_DISABLE_HT) ifmgd->flags |= IEEE80211_STA_DISABLE_11N; + /* Also disable HT if we don't support it or the AP doesn't use WMM */ + sband = local->hw.wiphy->bands[req->bss->channel->band]; + if (!sband->ht_cap.ht_supported || + local->hw.queues < 4 || !bss->wmm_used) + ifmgd->flags |= IEEE80211_STA_DISABLE_11N; + memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, sizeof(ifmgd->ht_capa_mask)); @@ -3344,15 +3333,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, } else ifmgd->ap_smps = ifmgd->req_smps; - /* - * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. - * We still associate in non-HT mode (11a/b/g) if any one of these - * ciphers is configured as pairwise. - * We can set this to true for non-11n hardware, that'll be checked - * separately along with the peer capabilities. - */ assoc_data->capability = req->bss->capability; - assoc_data->wmm_used = bss->wmm_used; + assoc_data->wmm = bss->wmm_used && (local->hw.queues >= 4); assoc_data->supp_rates = bss->supp_rates; assoc_data->supp_rates_len = bss->supp_rates_len; assoc_data->ht_information_ie = @@ -3360,10 +3342,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, if (bss->wmm_used && bss->uapsd_supported && (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { - assoc_data->uapsd_used = true; + assoc_data->uapsd = true; ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; } else { - assoc_data->uapsd_used = false; + assoc_data->uapsd = false; ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; } @@ -3393,41 +3375,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ifmgd->assoc_data = assoc_data; - mutex_lock(&local->mtx); - ieee80211_recalc_idle(sdata->local); - mutex_unlock(&local->mtx); - - /* switch to the right channel */ - local->oper_channel = req->bss->channel; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - - rcu_read_lock(); - sta = sta_info_get(sdata, req->bss->bssid); - rcu_read_unlock(); - - if (!sta) { - /* set BSSID */ - memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); - - sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); - if (!sta) { - err = -ENOMEM; - goto err_clear; - } - - sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); - - err = sta_info_insert(sta); - sta = NULL; - if (err) { - printk(KERN_DEBUG - "%s: failed to insert STA entry for the AP (error %d)\n", - sdata->name, err); - goto err_clear; - } - } else - WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid)); + err = ieee80211_prep_connection(sdata, req->bss, true); + if (err) + goto err_clear; if (!bss->dtim_period && sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index ff5f7b84e825..16e0b277b9a8 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -568,6 +568,13 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) minstrel_next_sample_idx(mi); /* + * Sampling might add some overhead (RTS, no aggregation) + * to the frame. Hence, don't use sampling for the currently + * used max TP rate. + */ + if (sample_idx == mi->max_tp_rate) + return -1; + /* * When not using MRR, do not sample if the probability is already * higher than 95% to avoid wasting airtime */ @@ -692,6 +699,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, int ack_dur; int stbc; int i; + unsigned int smps; /* fall back to the old minstrel for legacy stations */ if (!sta->ht_cap.ht_supported) @@ -731,6 +739,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, oper_chan_type != NL80211_CHAN_HT40PLUS) sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >> + IEEE80211_HT_CAP_SM_PS_SHIFT; + for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { u16 req = 0; @@ -748,6 +759,11 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, if ((sta_cap & req) != req) continue; + /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ + if (smps == WLAN_HT_CAP_SM_PS_STATIC && + minstrel_mcs_groups[i].streams > 1) + continue; + mi->groups[i].supported = mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5f6e32ca0858..bcfe8c77c839 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1063,20 +1063,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return RX_DROP_MONITOR; } - if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; - /* the hdr variable is invalid now! */ - switch (rx->key->conf.cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - /* Check for weak IVs if possible */ - if (rx->sta && ieee80211_is_data(fc) && - (!(status->flag & RX_FLAG_IV_STRIPPED) || - !(status->flag & RX_FLAG_DECRYPTED)) && - ieee80211_wep_is_weak_iv(rx->skb, rx->key)) - rx->sta->wep_weak_iv_count++; - result = ieee80211_crypto_wep_decrypt(rx); break; case WLAN_CIPHER_SUITE_TKIP: @@ -1096,6 +1085,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return RX_DROP_UNUSABLE; } + /* the hdr variable is invalid after the decrypt handlers */ + /* either the frame has been decrypted or will be dropped */ status->flag |= RX_FLAG_DECRYPTED; @@ -2278,9 +2269,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) sband = rx->local->hw.wiphy->bands[status->band]; - rate_control_rate_update(local, sband, rx->sta, - IEEE80211_RC_SMPS_CHANGED, - local->_oper_channel_type); + rate_control_rate_update( + local, sband, rx->sta, + IEEE80211_RC_SMPS_CHANGED, + ieee80211_get_tx_channel_type( + local, local->_oper_channel_type)); goto handled; } default: diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 570737df2d22..782a60198df4 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -226,12 +226,12 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) * have correct qos tag for some reason, due the network or the * peer application. * - * Note: local->uapsd_queues access is racy here. If the value is + * Note: ifmgd->uapsd_queues access is racy here. If the value is * changed via debugfs, user needs to reassociate manually to have * everything in sync. */ if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) - && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) + && (ifmgd->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) && skb_get_queue_mapping(tx->skb) == 0) return TX_CONTINUE; @@ -1065,6 +1065,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, { bool queued = false; bool reset_agg_timer = false; + struct sk_buff *purge_skb = NULL; if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { info->flags |= IEEE80211_TX_CTL_AMPDU; @@ -1106,8 +1107,13 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, info->control.vif = &tx->sdata->vif; info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; __skb_queue_tail(&tid_tx->pending, skb); + if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) + purge_skb = __skb_dequeue(&tid_tx->pending); } spin_unlock(&tx->sta->lock); + + if (purge_skb) + dev_kfree_skb(purge_skb); } /* reset session timer */ diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 68ad351479df..7aa31bbfaa3b 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -263,16 +263,14 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, } -bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) +static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, + struct ieee80211_key *key) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; unsigned int hdrlen; u8 *ivpos; u32 iv; - if (!ieee80211_has_protected(hdr->frame_control)) - return false; - hdrlen = ieee80211_hdrlen(hdr->frame_control); ivpos = skb->data + hdrlen; iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; @@ -286,18 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; - if (!ieee80211_is_data(hdr->frame_control) && - !ieee80211_is_auth(hdr->frame_control)) + if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc)) return RX_CONTINUE; if (!(status->flag & RX_FLAG_DECRYPTED)) { + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) + rx->sta->wep_weak_iv_count++; if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) return RX_DROP_UNUSABLE; } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN)) + return RX_DROP_UNUSABLE; + if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) + rx->sta->wep_weak_iv_count++; ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); /* remove ICV */ - skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); + if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN)) + return RX_DROP_UNUSABLE; } return RX_CONTINUE; diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 01e54840a628..9615749d1f65 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h @@ -25,7 +25,6 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, const u8 *key, int keylen, int keyidx); int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, size_t klen, u8 *data, size_t data_len); -bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); ieee80211_rx_result ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index b758350919ff..0ae23c60968c 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -138,6 +138,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) if (skb->len < hdrlen + MICHAEL_MIC_LEN) return RX_DROP_UNUSABLE; + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + hdr = (void *)skb->data; + data = skb->data + hdrlen; data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; @@ -253,6 +257,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || skb->len - hdrlen < 12) return RX_DROP_UNUSABLE; + /* it may be possible to optimize this a bit more */ + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + hdr = (void *)skb->data; + /* * Let TKIP code verify IV, but skip decryption. * In the case where hardware checks the IV as well, @@ -484,6 +493,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || data_len < 0) return RX_DROP_UNUSABLE; + if (status->flag & RX_FLAG_DECRYPTED) { + if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN)) + return RX_DROP_UNUSABLE; + } else { + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + } + ccmp_hdr2pn(pn, skb->data + hdrlen); queue = rx->security_idx; @@ -509,7 +526,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); /* Remove CCMP header and MIC */ - skb_trim(skb, skb->len - CCMP_MIC_LEN); + if (pskb_trim(skb, skb->len - CCMP_MIC_LEN)) + return RX_DROP_UNUSABLE; memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); skb_pull(skb, CCMP_HDR_LEN); @@ -609,6 +627,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) if (!ieee80211_is_mgmt(hdr->frame_control)) return RX_CONTINUE; + /* management frames are already linear */ + if (skb->len < 24 + sizeof(*mmie)) return RX_DROP_UNUSABLE; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2124977ac31d..ca7e8354e4f8 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -967,20 +967,21 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, } } - if (nf_conntrack_event_report(IPCT_DESTROY, ct, - NETLINK_CB(skb).pid, - nlmsg_report(nlh)) < 0) { + if (del_timer(&ct->timeout)) { + if (nf_conntrack_event_report(IPCT_DESTROY, ct, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)) < 0) { + nf_ct_delete_from_lists(ct); + /* we failed to report the event, try later */ + nf_ct_insert_dying_list(ct); + nf_ct_put(ct); + return 0; + } + /* death_by_timeout would report the event again */ + set_bit(IPS_DYING_BIT, &ct->status); nf_ct_delete_from_lists(ct); - /* we failed to report the event, try later */ - nf_ct_insert_dying_list(ct); nf_ct_put(ct); - return 0; } - - /* death_by_timeout would report the event again */ - set_bit(IPS_DYING_BIT, &ct->status); - - nf_ct_kill(ct); nf_ct_put(ct); return 0; diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 60d47180f043..02a21abea65e 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -469,11 +469,15 @@ enqueue: if (slot->qlen == 1) { /* The flow is new */ if (q->tail == NULL) { /* It is the first flow */ slot->next = x; - q->tail = slot; } else { slot->next = q->tail->next; q->tail->next = x; } + /* We put this flow at the end of our flow list. + * This might sound unfair for a new flow to wait after old ones, + * but we could endup servicing new flows only, and freeze old ones. + */ + q->tail = slot; /* We could use a bigger initial quantum for new flows */ slot->allot = q->scaled_quantum; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 39dbdf2adb12..4c1eb9472ddb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -205,6 +205,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { }, [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, + [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, }; /* policy for the key attributes */ @@ -5116,6 +5117,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) wiphy = &rdev->wiphy; + connect.bg_scan_period = -1; + if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] && + (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) { + connect.bg_scan_period = + nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]); + } + if (info->attrs[NL80211_ATTR_MAC]) connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index afde7e5f0010..70faadf16a32 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -734,9 +734,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, struct cfg80211_bss* cfg80211_inform_bss(struct wiphy *wiphy, struct ieee80211_channel *channel, - const u8 *bssid, - u64 timestamp, u16 capability, u16 beacon_interval, - const u8 *ie, size_t ielen, + const u8 *bssid, u64 tsf, u16 capability, + u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp) { struct cfg80211_internal_bss *res; @@ -758,7 +757,7 @@ cfg80211_inform_bss(struct wiphy *wiphy, memcpy(res->pub.bssid, bssid, ETH_ALEN); res->pub.channel = channel; res->pub.signal = signal; - res->pub.tsf = timestamp; + res->pub.tsf = tsf; res->pub.beacon_interval = beacon_interval; res->pub.capability = capability; /* diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 326750b99151..7c01c2f3b6cf 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -30,6 +30,9 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, wdev->wext.connect.ie = wdev->wext.ie; wdev->wext.connect.ie_len = wdev->wext.ie_len; + /* Use default background scan period */ + wdev->wext.connect.bg_scan_period = -1; + if (wdev->wext.keys) { wdev->wext.keys->def = wdev->wext.default_key; wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 7c12650165ae..8a4b9bccf8b2 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -249,6 +249,8 @@ LIB_H += util/include/asm/uaccess.h LIB_H += util/include/dwarf-regs.h LIB_H += util/include/asm/dwarf2.h LIB_H += util/include/asm/cpufeature.h +LIB_H += util/include/asm/unistd_32.h +LIB_H += util/include/asm/unistd_64.h LIB_H += perf.h LIB_H += util/annotate.h LIB_H += util/cache.h diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index eba80c292945..2f7073d107fd 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -25,7 +25,7 @@ get_cpuid(char *buffer, size_t sz) pvr = mfspr(SPRN_PVR); - nb = snprintf(buffer, sz, "%lu,%lu$", PVR_VER(pvr), PVR_REV(pvr)); + nb = scnprintf(buffer, sz, "%lu,%lu$", PVR_VER(pvr), PVR_REV(pvr)); /* look for end marker to ensure the entire data fit */ if (strchr(buffer, '$')) { diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c index f94006068d2b..146d12a1cec0 100644 --- a/tools/perf/arch/x86/util/header.c +++ b/tools/perf/arch/x86/util/header.c @@ -48,7 +48,7 @@ get_cpuid(char *buffer, size_t sz) if (family >= 0x6) model += ((a >> 16) & 0xf) << 4; } - nb = snprintf(buffer, sz, "%s,%u,%u,%u$", vendor, family, model, step); + nb = scnprintf(buffer, sz, "%s,%u,%u,%u$", vendor, family, model, step); /* look for end marker to ensure the entire data fit */ if (strchr(buffer, '$')) { diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 16e7d20eee83..3afa39ac1d40 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -10,6 +10,9 @@ void get_term_dimensions(struct winsize *ws); #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" +#ifndef __NR_perf_event_open +# define __NR_perf_event_open 336 +#endif #endif #if defined(__x86_64__) @@ -17,6 +20,9 @@ void get_term_dimensions(struct winsize *ws); #define rmb() asm volatile("lfence" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" +#ifndef __NR_perf_event_open +# define __NR_perf_event_open 298 +#endif #endif #ifdef __powerpc__ diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 521c38a79190..11e46da17bbb 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -1,3 +1,4 @@ +#include <linux/kernel.h> #include "cache.h" #include "color.h" @@ -182,12 +183,12 @@ static int __color_vsnprintf(char *bf, size_t size, const char *color, } if (perf_use_color_default && *color) - r += snprintf(bf, size, "%s", color); - r += vsnprintf(bf + r, size - r, fmt, args); + r += scnprintf(bf, size, "%s", color); + r += vscnprintf(bf + r, size - r, fmt, args); if (perf_use_color_default && *color) - r += snprintf(bf + r, size - r, "%s", PERF_COLOR_RESET); + r += scnprintf(bf + r, size - r, "%s", PERF_COLOR_RESET); if (trail) - r += snprintf(bf + r, size - r, "%s", trail); + r += scnprintf(bf + r, size - r, "%s", trail); return r; } diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index ecd7f4dd7eea..14bb035c5fd9 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -280,7 +280,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, if (realname == NULL || filename == NULL || linkname == NULL) goto out_free; - len = snprintf(filename, size, "%s%s%s", + len = scnprintf(filename, size, "%s%s%s", debugdir, is_kallsyms ? "/" : "", realname); if (mkdir_p(filename, 0755)) goto out_free; @@ -295,7 +295,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, goto out_free; } - len = snprintf(linkname, size, "%s/.build-id/%.2s", + len = scnprintf(linkname, size, "%s/.build-id/%.2s", debugdir, sbuild_id); if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6f505d1abac7..e11e482bd185 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -768,7 +768,7 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, sep ? "%.2f" : " %6.2f%%", (period * 100.0) / total); else - ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%", + ret = scnprintf(s, size, sep ? "%.2f" : " %6.2f%%", (period * 100.0) / total); if (symbol_conf.show_cpu_utilization) { ret += percent_color_snprintf(s + ret, size - ret, @@ -791,20 +791,20 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, } } } else - ret = snprintf(s, size, sep ? "%" PRIu64 : "%12" PRIu64 " ", period); + ret = scnprintf(s, size, sep ? "%" PRIu64 : "%12" PRIu64 " ", period); if (symbol_conf.show_nr_samples) { if (sep) - ret += snprintf(s + ret, size - ret, "%c%" PRIu64, *sep, nr_events); + ret += scnprintf(s + ret, size - ret, "%c%" PRIu64, *sep, nr_events); else - ret += snprintf(s + ret, size - ret, "%11" PRIu64, nr_events); + ret += scnprintf(s + ret, size - ret, "%11" PRIu64, nr_events); } if (symbol_conf.show_total_period) { if (sep) - ret += snprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period); + ret += scnprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period); else - ret += snprintf(s + ret, size - ret, " %12" PRIu64, period); + ret += scnprintf(s + ret, size - ret, " %12" PRIu64, period); } if (pair_hists) { @@ -819,25 +819,25 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, diff = new_percent - old_percent; if (fabs(diff) >= 0.01) - snprintf(bf, sizeof(bf), "%+4.2F%%", diff); + ret += scnprintf(bf, sizeof(bf), "%+4.2F%%", diff); else - snprintf(bf, sizeof(bf), " "); + ret += scnprintf(bf, sizeof(bf), " "); if (sep) - ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf); + ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); else - ret += snprintf(s + ret, size - ret, "%11.11s", bf); + ret += scnprintf(s + ret, size - ret, "%11.11s", bf); if (show_displacement) { if (displacement) - snprintf(bf, sizeof(bf), "%+4ld", displacement); + ret += scnprintf(bf, sizeof(bf), "%+4ld", displacement); else - snprintf(bf, sizeof(bf), " "); + ret += scnprintf(bf, sizeof(bf), " "); if (sep) - ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf); + ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); else - ret += snprintf(s + ret, size - ret, "%6.6s", bf); + ret += scnprintf(s + ret, size - ret, "%6.6s", bf); } } @@ -855,7 +855,7 @@ int hist_entry__snprintf(struct hist_entry *he, char *s, size_t size, if (se->elide) continue; - ret += snprintf(s + ret, size - ret, "%s", sep ?: " "); + ret += scnprintf(s + ret, size - ret, "%s", sep ?: " "); ret += se->se_snprintf(he, s + ret, size - ret, hists__col_len(hists, se->se_width_idx)); } diff --git a/tools/perf/util/include/asm/unistd_32.h b/tools/perf/util/include/asm/unistd_32.h new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/tools/perf/util/include/asm/unistd_32.h @@ -0,0 +1 @@ + diff --git a/tools/perf/util/include/asm/unistd_64.h b/tools/perf/util/include/asm/unistd_64.h new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/tools/perf/util/include/asm/unistd_64.h @@ -0,0 +1 @@ + diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index b029296d20d9..c7a6f6faf91e 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -165,7 +165,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) struct tracepoint_path *path = NULL; DIR *sys_dir, *evt_dir; struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; - char id_buf[4]; + char id_buf[24]; int fd; u64 id; char evt_path[MAXPATHLEN]; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 16da30d8d765..076c9d4e1ea4 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -33,6 +33,9 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) } } va_end(ap); + + if (n >= (int)size) + return size - 1; return n; } diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index 92e068517c1a..2eeb51baf077 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -1,4 +1,5 @@ #include "cache.h" +#include <linux/kernel.h> int prefixcmp(const char *str, const char *prefix) { @@ -89,14 +90,14 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) if (!strbuf_avail(sb)) strbuf_grow(sb, 64); va_start(ap, fmt); - len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len < 0) - die("your vsnprintf is broken"); + die("your vscnprintf is broken"); if (len > strbuf_avail(sb)) { strbuf_grow(sb, len); va_start(ap, fmt); - len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len > strbuf_avail(sb)) { die("this should not happen, your snprintf is broken"); diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index e81aef1f2569..bb9197c9c4a4 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c @@ -837,15 +837,15 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size, unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE]; nr_events = convert_unit(nr_events, &unit); - printed = snprintf(bf, size, "Events: %lu%c %s", nr_events, unit, ev_name); + printed = scnprintf(bf, size, "Events: %lu%c %s", nr_events, unit, ev_name); if (thread) - printed += snprintf(bf + printed, size - printed, + printed += scnprintf(bf + printed, size - printed, ", Thread: %s(%d)", (thread->comm_set ? thread->comm : ""), thread->pid); if (dso) - printed += snprintf(bf + printed, size - printed, + printed += scnprintf(bf + printed, size - printed, ", DSO: %s", dso->short_name); return printed; } @@ -1095,7 +1095,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, HE_COLORSET_NORMAL); nr_events = convert_unit(nr_events, &unit); - printed = snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events, + printed = scnprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events, unit, unit == ' ' ? "" : " ", ev_name); slsmg_printf("%s", bf); @@ -1105,8 +1105,8 @@ static void perf_evsel_menu__write(struct ui_browser *browser, if (!current_entry) ui_browser__set_color(browser, HE_COLORSET_TOP); nr_events = convert_unit(nr_events, &unit); - snprintf(bf, sizeof(bf), ": %ld%c%schunks LOST!", nr_events, - unit, unit == ' ' ? "" : " "); + printed += scnprintf(bf, sizeof(bf), ": %ld%c%schunks LOST!", + nr_events, unit, unit == ' ' ? "" : " "); warn = bf; } diff --git a/tools/perf/util/ui/helpline.c b/tools/perf/util/ui/helpline.c index 4f48f5901b30..2f950c2641c8 100644 --- a/tools/perf/util/ui/helpline.c +++ b/tools/perf/util/ui/helpline.c @@ -64,7 +64,7 @@ int ui_helpline__show_help(const char *format, va_list ap) static int backlog; pthread_mutex_lock(&ui__lock); - ret = vsnprintf(ui_helpline__last_msg + backlog, + ret = vscnprintf(ui_helpline__last_msg + backlog, sizeof(ui_helpline__last_msg) - backlog, format, ap); backlog += ret; |