Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
diff --git a/.mailmap b/.mailmap
index 658003a..df1baba 100644
--- a/.mailmap
+++ b/.mailmap
@@ -99,6 +99,7 @@
 Sam Ravnborg <sam@mars.ravnborg.org>
 Sascha Hauer <s.hauer@pengutronix.de>
 S.Çağlar Onur <caglar@pardus.org.tr>
+Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
 Simon Kelley <simon@thekelleys.org.uk>
 Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
 Stephen Hemminger <shemminger@osdl.org>
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index f517008..cc63f30 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -276,7 +276,7 @@
      </para>
 
      <sect1><title>Frame Buffer Memory</title>
-!Edrivers/video/fbmem.c
+!Edrivers/video/fbdev/core/fbmem.c
      </sect1>
 <!--
      <sect1><title>Frame Buffer Console</title>
@@ -284,7 +284,7 @@
      </sect1>
 -->
      <sect1><title>Frame Buffer Colormap</title>
-!Edrivers/video/fbcmap.c
+!Edrivers/video/fbdev/core/fbcmap.c
      </sect1>
 <!-- FIXME:
   drivers/video/fbgen.c has no docs, which stuffs up the sgml.  Comment
@@ -294,11 +294,11 @@
      </sect1>
 KAO -->
      <sect1><title>Frame Buffer Video Mode Database</title>
-!Idrivers/video/modedb.c
-!Edrivers/video/modedb.c
+!Idrivers/video/fbdev/core/modedb.c
+!Edrivers/video/fbdev/core/modedb.c
      </sect1>
      <sect1><title>Frame Buffer Macintosh Video Mode Database</title>
-!Edrivers/video/macmodes.c
+!Edrivers/video/fbdev/macmodes.c
      </sect1>
      <sect1><title>Frame Buffer Fonts</title>
         <para>
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 702c4474..677a025 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2287,6 +2287,11 @@
 !Edrivers/gpu/drm/drm_crtc_helper.c
     </sect2>
     <sect2>
+      <title>Output Probing Helper Functions Reference</title>
+!Pdrivers/gpu/drm/drm_probe_helper.c output probing helper overview
+!Edrivers/gpu/drm/drm_probe_helper.c
+    </sect2>
+    <sect2>
       <title>fbdev Helper Functions Reference</title>
 !Pdrivers/gpu/drm/drm_fb_helper.c fbdev helpers
 !Edrivers/gpu/drm/drm_fb_helper.c
diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
new file mode 100644
index 0000000..925ecbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
@@ -0,0 +1,97 @@
+Marvell Kirkwood SoC Family Device Tree Bindings
+------------------------------------------------
+
+Boards with a SoC of the Marvell Kirkwook family, eg 88f6281
+
+* Required root node properties:
+compatible: must contain "marvell,kirkwood"
+
+In addition, the above compatible shall be extended with the specific
+SoC. Currently known SoC compatibles are:
+
+"marvell,kirkwood-88f6192"
+"marvell,kirkwood-88f6281"
+"marvell,kirkwood-88f6282"
+"marvell,kirkwood-88f6283"
+"marvell,kirkwood-88f6702"
+"marvell,kirkwood-98DX4122"
+
+And in addition, the compatible shall be extended with the specific
+board. Currently known boards are:
+
+"buffalo,lschlv2"
+"buffalo,lsxhl"
+"buffalo,lsxl"
+"dlink,dns-320"
+"dlink,dns-320-a1"
+"dlink,dns-325"
+"dlink,dns-325-a1"
+"dlink,dns-kirkwood"
+"excito,b3"
+"globalscale,dreamplug-003-ds2001"
+"globalscale,guruplug"
+"globalscale,guruplug-server-plus"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug-esata"
+"globalscale,sheevaplug-esata-rev13"
+"iom,iconnect"
+"iom,iconnect-1.1"
+"iom,ix2-200"
+"keymile,km_kirkwood"
+"lacie,cloudbox"
+"lacie,inetspace_v2"
+"lacie,laplug"
+"lacie,netspace_lite_v2"
+"lacie,netspace_max_v2"
+"lacie,netspace_mini_v2"
+"lacie,netspace_v2"
+"marvell,db-88f6281-bp"
+"marvell,db-88f6282-bp"
+"marvell,mv88f6281gtw-ge"
+"marvell,rd88f6281"
+"marvell,rd88f6281"
+"marvell,rd88f6281-a0"
+"marvell,rd88f6281-a1"
+"mpl,cec4"
+"mpl,cec4-10"
+"netgear,readynas"
+"netgear,readynas"
+"netgear,readynas-duo-v2"
+"netgear,readynas-nv+-v2"
+"plathome,openblocks-a6"
+"plathome,openblocks-a7"
+"raidsonic,ib-nas6210"
+"raidsonic,ib-nas6210-b"
+"raidsonic,ib-nas6220"
+"raidsonic,ib-nas6220-b"
+"raidsonic,ib-nas62x0"
+"seagate,dockstar"
+"seagate,goflexnet"
+"synology,ds109"
+"synology,ds110jv10"
+"synology,ds110jv20"
+"synology,ds110jv30"
+"synology,ds111"
+"synology,ds209"
+"synology,ds210jv10"
+"synology,ds210jv20"
+"synology,ds212"
+"synology,ds212jv10"
+"synology,ds212jv20"
+"synology,ds212pv10"
+"synology,ds409"
+"synology,ds409slim"
+"synology,ds410j"
+"synology,ds411"
+"synology,ds411j"
+"synology,ds411slim"
+"synology,ds413jv10"
+"synology,rs212"
+"synology,rs409"
+"synology,rs411"
+"synology,rs812"
+"usi,topkick"
+"usi,topkick-1281P2"
+"zyxel,nsa310"
+"zyxel,nsa310a"
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index 71724d0..bef86e5 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -13,8 +13,22 @@
 ad,adm9240		ADM9240:  Complete System Hardware Monitor for uProcessor-Based Systems
 adi,adt7461		+/-1C TDM Extended Temp Range I.C
 adt7461			+/-1C TDM Extended Temp Range I.C
+adi,adt7473		+/-1C TDM Extended Temp Range I.C
+adi,adt7475		+/-1C TDM Extended Temp Range I.C
+adi,adt7476		+/-1C TDM Extended Temp Range I.C
+adi,adt7490		+/-1C TDM Extended Temp Range I.C
 at,24c08		i2c serial eeprom  (24cxx)
+atmel,24c00		i2c serial eeprom  (24cxx)
+atmel,24c01		i2c serial eeprom  (24cxx)
 atmel,24c02		i2c serial eeprom  (24cxx)
+atmel,24c04		i2c serial eeprom  (24cxx)
+atmel,24c16		i2c serial eeprom  (24cxx)
+atmel,24c32		i2c serial eeprom  (24cxx)
+atmel,24c64		i2c serial eeprom  (24cxx)
+atmel,24c128		i2c serial eeprom  (24cxx)
+atmel,24c256		i2c serial eeprom  (24cxx)
+atmel,24c512		i2c serial eeprom  (24cxx)
+atmel,24c1024		i2c serial eeprom  (24cxx)
 atmel,at97sc3204t	i2c trusted platform module (TPM)
 capella,cm32181		CM32181: Ambient Light Sensor
 catalyst,24c32		i2c serial eeprom
@@ -46,8 +60,10 @@
 maxim,max1237		Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
 maxim,max6625		9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
 mc,rv3029c2		Real Time Clock Module with I2C-Bus
+national,lm63		Temperature sensor with integrated fan control
 national,lm75		I2C TEMP SENSOR
 national,lm80		Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
+national,lm85		Temperature sensor with integrated fan control
 national,lm92		±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface
 nuvoton,npct501		i2c trusted platform module (TPM)
 nxp,pca9556		Octal SMBus and I2C registered interface
diff --git a/Documentation/devicetree/bindings/net/broadcom-systemport.txt b/Documentation/devicetree/bindings/net/broadcom-systemport.txt
new file mode 100644
index 0000000..1b7600e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/broadcom-systemport.txt
@@ -0,0 +1,29 @@
+* Broadcom BCM7xxx Ethernet Systemport Controller (SYSTEMPORT)
+
+Required properties:
+- compatible: should be one of "brcm,systemport-v1.00" or "brcm,systemport"
+- reg: address and length of the register set for the device.
+- interrupts: interrupts for the device, first cell must be for the the rx
+  interrupts, and the second cell should be for the transmit queues
+- local-mac-address: Ethernet MAC address (48 bits) of this adapter
+- phy-mode: Should be a string describing the PHY interface to the
+  Ethernet switch/PHY, see Documentation/devicetree/bindings/net/ethernet.txt
+- fixed-link: see Documentation/devicetree/bindings/net/fsl-tsec-phy.txt for
+  the property specific details
+
+Optional properties:
+- systemport,num-tier2-arb: number of tier 2 arbiters, an integer
+- systemport,num-tier1-arb: number of tier 1 arbiters, an integer
+- systemport,num-txq: number of HW transmit queues, an integer
+- systemport,num-rxq: number of HW receive queues, an integer
+
+Example:
+ethernet@f04a0000 {
+	compatible = "brcm,systemport-v1.00";
+	reg = <0xf04a0000 0x4650>;
+	local-mac-address = [ 00 11 22 33 44 55 ];
+	fixed-link = <0 1 1000 0 0>;
+	phy-mode = "gmii";
+	interrupts = <0x0 0x16 0x0>,
+		<0x0 0x17 0x0>;
+};
diff --git a/Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt b/Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt
new file mode 100644
index 0000000..d3bbdded
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt
@@ -0,0 +1,23 @@
+* AT86RF230 IEEE 802.15.4 *
+
+Required properties:
+  - compatible:		should be "atmel,at86rf230", "atmel,at86rf231",
+			"atmel,at86rf233" or "atmel,at86rf212"
+  - spi-max-frequency:	maximal bus speed, should be set to 7500000 depends
+			sync or async operation mode
+  - reg:		the chipselect index
+  - interrupts:		the interrupt generated by the device
+
+Optional properties:
+  - reset-gpio:		GPIO spec for the rstn pin
+  - sleep-gpio:		GPIO spec for the slp_tr pin
+
+Example:
+
+	at86rf231@0 {
+		compatible = "atmel,at86rf231";
+		spi-max-frequency = <7500000>;
+		reg = <0>;
+		interrupts = <19 1>;
+		interrupt-parent = <&gpio3>;
+	};
diff --git a/Documentation/devicetree/bindings/net/via-rhine.txt b/Documentation/devicetree/bindings/net/via-rhine.txt
new file mode 100644
index 0000000..334eca2
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/via-rhine.txt
@@ -0,0 +1,17 @@
+* VIA Rhine 10/100 Network Controller
+
+Required properties:
+- compatible : Should be "via,vt8500-rhine" for integrated
+	Rhine controllers found in VIA VT8500, WonderMedia WM8950
+	and similar. These are listed as 1106:3106 rev. 0x84 on the
+	virtual PCI bus under vendor-provided kernels
+- reg : Address and length of the io space
+- interrupts : Should contain the controller interrupt line
+
+Examples:
+
+ethernet@d8004000 {
+	compatible = "via,vt8500-rhine";
+	reg = <0xd8004000 0x100>;
+	interrupts = <10>;
+};
diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
index c119deb..67a5db9 100644
--- a/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
@@ -119,7 +119,7 @@
 Example:
 // pin controller node
 pinctrl@35004800 {
-	compatible = "brcmbcm11351-pinctrl";
+	compatible = "brcm,bcm11351-pinctrl";
 	reg = <0x35004800 0x430>;
 
 	// pin configuration node
diff --git a/Documentation/devicetree/bindings/serial/efm32-uart.txt b/Documentation/devicetree/bindings/serial/efm32-uart.txt
index 1984bdf..3ca0133 100644
--- a/Documentation/devicetree/bindings/serial/efm32-uart.txt
+++ b/Documentation/devicetree/bindings/serial/efm32-uart.txt
@@ -1,7 +1,7 @@
 * Energymicro efm32 UART
 
 Required properties:
-- compatible : Should be "efm32,uart"
+- compatible : Should be "energymicro,efm32-uart"
 - reg : Address and length of the register set
 - interrupts : Should contain uart interrupt
 
@@ -13,7 +13,7 @@
 Example:
 
 uart@0x4000c400 {
-	compatible = "efm32,uart";
+	compatible = "energymicro,efm32-uart";
 	reg = <0x4000c400 0x400>;
 	interrupts = <15>;
 	efm32,location = <0>;
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 0f01c9b..abc3080 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -22,6 +22,7 @@
 avago	Avago Technologies
 bosch	Bosch Sensortec GmbH
 brcm	Broadcom Corporation
+buffalo	Buffalo, Inc.
 calxeda	Calxeda
 capella	Capella Microsystems, Inc
 cavium	Cavium, Inc.
@@ -33,15 +34,18 @@
 crystalfontz	Crystalfontz America, Inc.
 dallas	Maxim Integrated Products (formerly Dallas Semiconductor)
 davicom	DAVICOM Semiconductor, Inc.
-dlink	D-Link Systems, Inc.
 denx	Denx Software Engineering
+digi	Digi International Inc.
+dlink	D-Link Corporation
 dmo	Data Modul AG
+ebv	EBV Elektronik
 edt	Emerging Display Technologies
 emmicro	EM Microelectronic
 epfl	Ecole Polytechnique Fédérale de Lausanne
 epson	Seiko Epson Corp.
 est	ESTeem Wireless Modems
 eukrea  Eukréa Electromatique
+excito	Excito
 fsl	Freescale Semiconductor
 GEFanuc	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
@@ -53,13 +57,17 @@
 hisilicon	Hisilicon Limited.
 honeywell	Honeywell
 hp	Hewlett Packard
+i2se	I2SE GmbH
 ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
+iom	Iomega Corporation
 img	Imagination Technologies Ltd.
 intel	Intel Corporation
 intercontrol	Inter Control Group
+isee	ISEE 2007 S.L.
 isl	Intersil
 karo	Ka-Ro electronics GmbH
+keymile	Keymile GmbH
 lacie	LaCie
 lantiq	Lantiq Semiconductor
 lg	LG Corporation
@@ -70,9 +78,12 @@
 microchip	Microchip Technology Inc.
 mosaixtech	Mosaix Technologies, Inc.
 moxa	Moxa
+mpl	MPL AG
+mxicy	Macronix International Co., Ltd.
 national	National Semiconductor
 neonode		Neonode Inc.
 netgear	NETGEAR
+newhaven	Newhaven Display International
 nintendo	Nintendo
 nokia	Nokia
 nvidia	NVIDIA
@@ -82,10 +93,12 @@
 panasonic	Panasonic Corporation
 phytec	PHYTEC Messtechnik GmbH
 picochip	Picochip Ltd
+plathome	Plat'Home Co., Ltd.
 powervr	PowerVR (deprecated, use img)
 qca	Qualcomm Atheros, Inc.
 qcom	Qualcomm Technologies, Inc
 qnap	QNAP Systems, Inc.
+raidsonic	RaidSonic Technology GmbH
 ralink	Mediatek/Ralink Technology Corp.
 ramtron	Ramtron International
 realtek Realtek Semiconductor Corp.
@@ -95,6 +108,7 @@
 samsung	Samsung Semiconductor
 sbs	Smart Battery System
 schindler	Schindler
+seagate	Seagate Technology PLC
 sil	Silicon Image
 silabs	Silicon Laboratories
 simtek
@@ -111,6 +125,7 @@
 tlm	Trusted Logic Mobility
 toshiba	Toshiba Corporation
 toumaz	Toumaz
+usi	Universal Scientifc Industrial Co., Ltd.
 v3	V3 Semiconductor
 via	VIA Technologies, Inc.
 voipac	Voipac Technologies s.r.o.
@@ -119,3 +134,4 @@
 wm	Wondermedia Technologies, Inc.
 xes	Extreme Engineering Solutions (X-ES)
 xlnx	Xilinx
+zyxel	ZyXEL Communications Corp.
diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO
index 0091a82..b61885c 100644
--- a/Documentation/ja_JP/HOWTO
+++ b/Documentation/ja_JP/HOWTO
@@ -315,7 +315,7 @@
 もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が
 最新の安定版カーネルです。
 
-3.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
+3.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必
 要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
 た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
 の場合はこれに対してだいたいの場合、すぐにリリースがされます。
diff --git a/Documentation/ja_JP/stable_kernel_rules.txt b/Documentation/ja_JP/stable_kernel_rules.txt
index 1426583..9dbda9b 100644
--- a/Documentation/ja_JP/stable_kernel_rules.txt
+++ b/Documentation/ja_JP/stable_kernel_rules.txt
@@ -50,16 +50,16 @@
 
 -stable ツリーにパッチを送付する手続き-
 
- - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
+ - 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ
    を送る。
  - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
    には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
    日かかる場合がある。
  - もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
    メンテナーによるレビューのために -stable キューに追加される。
- - パッチに stable@kernel.org のアドレスが付加されているときには、それ
+ - パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ
    が Linus のツリーに入る時に自動的に stable チームに email される。
- - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
+ - セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ
    きではなく、代わりに security@kernel.org のアドレスに送られる。
 
 レビューサイクル-
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 03e50b4..4384217 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -804,13 +804,6 @@
 	dhash_entries=	[KNL]
 			Set number of hash buckets for dentry cache.
 
-	digi=		[HW,SERIAL]
-			IO parameters + enable/disable command.
-
-	digiepca=	[HW,SERIAL]
-			See drivers/char/README.epca and
-			Documentation/serial/digiepca.txt.
-
 	disable=	[IPV6]
 			See Documentation/networking/ipv6.txt.
 
@@ -2939,9 +2932,6 @@
 	rhash_entries=	[KNL,NET]
 			Set number of hash buckets for route cache
 
-	riscom8=	[HW,SERIAL]
-			Format: <io_board1>[,<io_board2>[,...<io_boardN>]]
-
 	ro		[KNL] Mount root device read-only on boot
 
 	root=		[KNL] Root filesystem
@@ -3083,9 +3073,6 @@
 	sonypi.*=	[HW] Sony Programmable I/O Control Device driver
 			See Documentation/laptops/sonypi.txt
 
-	specialix=	[HW,SERIAL] Specialix multi-serial port adapter
-			See Documentation/serial/specialix.txt.
-
 	spia_io_base=	[HW,MTD]
 	spia_fio_base=
 	spia_pedr=
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index 76d80a6..4c8e142 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -63,8 +63,6 @@
 PG_MAGIC              'P'         pg_{read,write}_hdr include/linux/pg.h
 CMAGIC                0x0111      user              include/linux/a.out.h
 MKISS_DRIVER_MAGIC    0x04bf      mkiss_channel     drivers/net/mkiss.h
-RISCOM8_MAGIC         0x0907      riscom_port       drivers/char/riscom8.h
-SPECIALIX_MAGIC       0x0907      specialix_port    drivers/char/specialix_io8.h
 HDLC_MAGIC            0x239e      n_hdlc            drivers/char/n_hdlc.c
 APM_BIOS_MAGIC        0x4101      apm_user          arch/x86/kernel/apm_32.c
 CYCLADES_MAGIC        0x4359      cyclades_port     include/linux/cyclades.h
@@ -82,7 +80,6 @@
 X25_ASY_MAGIC         0x5303      x25_asy           drivers/net/x25_asy.h
 SIXPACK_MAGIC         0x5304      sixpack           drivers/net/hamradio/6pack.h
 AX25_MAGIC            0x5316      ax_disp           drivers/net/mkiss.h
-ESP_MAGIC             0x53ee      esp_struct        drivers/char/esp.h
 TTY_MAGIC             0x5401      tty_struct        include/linux/tty.h
 MGSL_MAGIC            0x5401      mgsl_info         drivers/char/synclink.c
 TTY_DRIVER_MAGIC      0x5402      tty_driver        include/linux/tty_driver.h
@@ -94,13 +91,10 @@
 RFCOMM_TTY_MAGIC      0x6d02                        net/bluetooth/rfcomm/tty.c
 USB_SERIAL_PORT_MAGIC 0x7301      usb_serial_port   drivers/usb/serial/usb-serial.h
 CG_MAGIC              0x00090255  ufs_cylinder_group include/linux/ufs_fs.h
-A2232_MAGIC           0x000a2232  gs_port           drivers/char/ser_a2232.h
 RPORT_MAGIC           0x00525001  r_port            drivers/char/rocket_int.h
 LSEMAGIC              0x05091998  lse               drivers/fc4/fc.c
 GDTIOCTL_MAGIC        0x06030f07  gdth_iowr_str     drivers/scsi/gdth_ioctl.h
 RIEBL_MAGIC           0x09051990                    drivers/net/atarilance.c
-RIO_MAGIC             0x12345678  gs_port           drivers/char/rio/rio_linux.c
-SX_MAGIC              0x12345678  gs_port           drivers/char/sx.h
 NBD_REQUEST_MAGIC     0x12560953  nbd_request       include/linux/nbd.h
 RED_MAGIC2            0x170fc2a5  (any)             mm/slab.c
 BAYCOM_MAGIC          0x19730510  baycom_state      drivers/net/baycom_epp.c
@@ -116,7 +110,6 @@
 CTC_ASYNC_MAGIC       0x49344C01  ctc_tty_info      drivers/s390/net/ctctty.c
 ISDN_NET_MAGIC        0x49344C02  isdn_net_local_s  drivers/isdn/i4l/isdn_net_lib.h
 SAVEKMSG_MAGIC2       0x4B4D5347  savekmsg          arch/*/amiga/config.c
-STLI_BOARDMAGIC       0x4bc6c825  stlibrd           include/linux/istallion.h
 CS_STATE_MAGIC        0x4c4f4749  cs_state          sound/oss/cs46xx.c
 SLAB_C_MAGIC          0x4f17a36d  kmem_cache        mm/slab.c
 COW_MAGIC             0x4f4f4f4d  cow_header_v1     arch/um/drivers/ubd_user.c
@@ -127,10 +120,8 @@
 SAVEKMSG_MAGIC1       0x53415645  savekmsg          arch/*/amiga/config.c
 GDA_MAGIC             0x58464552  gda               arch/mips/include/asm/sn/gda.h
 RED_MAGIC1            0x5a2cf071  (any)             mm/slab.c
-STL_PORTMAGIC         0x5a7182c9  stlport           include/linux/stallion.h
 EEPROM_MAGIC_VALUE    0x5ab478d2  lanai_dev         drivers/atm/lanai.c
 HDLCDRV_MAGIC         0x5ac6e778  hdlcdrv_state     include/linux/hdlcdrv.h
-EPCA_MAGIC            0x5c6df104  channel           include/linux/epca.h
 PCXX_MAGIC            0x5c6df104  channel           drivers/char/pcxx.h
 KV_MAGIC              0x5f4b565f  kernel_vars_s     arch/mips/include/asm/sn/klkernvars.h
 I810_STATE_MAGIC      0x63657373  i810_state        sound/oss/i810_audio.c
@@ -142,17 +133,14 @@
 LO_MAGIC              0x68797548  nbd_device        include/linux/nbd.h
 OPROFILE_MAGIC        0x6f70726f  super_block       drivers/oprofile/oprofilefs.h
 M3_STATE_MAGIC        0x734d724d  m3_state          sound/oss/maestro3.c
-STL_PANELMAGIC        0x7ef621a1  stlpanel          include/linux/stallion.h
 VMALLOC_MAGIC         0x87654320  snd_alloc_track   sound/core/memory.c
 KMALLOC_MAGIC         0x87654321  snd_alloc_track   sound/core/memory.c
 PWC_MAGIC             0x89DC10AB  pwc_device        drivers/usb/media/pwc.h
 NBD_REPLY_MAGIC       0x96744668  nbd_reply         include/linux/nbd.h
-STL_BOARDMAGIC        0xa2267f52  stlbrd            include/linux/stallion.h
 ENI155_MAGIC          0xa54b872d  midway_eprom	    drivers/atm/eni.h
 SCI_MAGIC             0xbabeface  gs_port           drivers/char/sh-sci.h
 CODA_MAGIC            0xC0DAC0DA  coda_file_info    fs/coda/coda_fs_i.h
 DPMEM_MAGIC           0xc0ffee11  gdt_pci_sram      drivers/scsi/gdth.h
-STLI_PORTMAGIC        0xe671c7a1  stliport          include/linux/istallion.h
 YAM_MAGIC             0xF10A7654  yam_port          drivers/net/hamradio/yam.c
 CCB_MAGIC             0xf2691ad2  ccb               drivers/scsi/ncr53c8xx.c
 QUEUE_MAGIC_FREE      0xf7e1c9a3  queue_entry       drivers/scsi/arm/queue.c
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index a383c00..9c723ec 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -585,13 +585,19 @@
 	balance-tlb or 5
 
 		Adaptive transmit load balancing: channel bonding that
-		does not require any special switch support.  The
-		outgoing traffic is distributed according to the
-		current load (computed relative to the speed) on each
-		slave.  Incoming traffic is received by the current
-		slave.  If the receiving slave fails, another slave
-		takes over the MAC address of the failed receiving
-		slave.
+		does not require any special switch support.
+
+		In tlb_dynamic_lb=1 mode; the outgoing traffic is
+		distributed according to the current load (computed
+		relative to the speed) on each slave.
+
+		In tlb_dynamic_lb=0 mode; the load balancing based on
+		current load is disabled and the load is distributed
+		only using the hash distribution.
+
+		Incoming traffic is received by the current slave.
+		If the receiving slave fails, another slave takes over
+		the MAC address of the failed receiving slave.
 
 		Prerequisite:
 
@@ -736,6 +742,28 @@
 
 	This option was added for bonding version 3.6.0.
 
+tlb_dynamic_lb
+
+	Specifies if dynamic shuffling of flows is enabled in tlb
+	mode. The value has no effect on any other modes.
+
+	The default behavior of tlb mode is to shuffle active flows across
+	slaves based on the load in that interval. This gives nice lb
+	characteristics but can cause packet reordering. If re-ordering is
+	a concern use this variable to disable flow shuffling and rely on
+	load balancing provided solely by the hash distribution.
+	xmit-hash-policy can be used to select the appropriate hashing for
+	the setup.
+
+	The sysfs entry can be used to change the setting per bond device
+	and the initial value is derived from the module parameter. The
+	sysfs entry is allowed to be changed only if the bond device is
+	down.
+
+	The default value is "1" that enables flow shuffling while value "0"
+	disables it. This option was added in bonding driver 3.7.1
+
+
 updelay
 
 	Specifies the time, in milliseconds, to wait before enabling a
@@ -769,7 +797,7 @@
 xmit_hash_policy
 
 	Selects the transmit hash policy to use for slave selection in
-	balance-xor and 802.3ad modes.  Possible values are:
+	balance-xor, 802.3ad, and tlb modes.  Possible values are:
 
 	layer2
 
diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt
index 81f940f..82e1cb0 100644
--- a/Documentation/networking/filter.txt
+++ b/Documentation/networking/filter.txt
@@ -281,6 +281,7 @@
   cpu                                   raw_smp_processor_id()
   vlan_tci                              vlan_tx_tag_get(skb)
   vlan_pr                               vlan_tx_tag_present(skb)
+  rand                                  prandom_u32()
 
 These extensions can also be prefixed with '#'.
 Examples for low-level BPF:
@@ -308,6 +309,18 @@
   ret #-1
   drop: ret #0
 
+** icmp random packet sampling, 1 in 4
+  ldh [12]
+  jne #0x800, drop
+  ldb [23]
+  jneq #1, drop
+  # get a random uint32 number
+  ld rand
+  mod #4
+  jneq #1, drop
+  ret #-1
+  drop: ret #0
+
 ** SECCOMP filter example:
 
   ld [4]                  /* offsetof(struct seccomp_data, arch) */
diff --git a/Documentation/networking/scaling.txt b/Documentation/networking/scaling.txt
index ca6977f..99ca40e 100644
--- a/Documentation/networking/scaling.txt
+++ b/Documentation/networking/scaling.txt
@@ -429,7 +429,7 @@
 (therbert@google.com)
 
 Accelerated RFS was introduced in 2.6.35. Original patches were
-submitted by Ben Hutchings (bhutchings@solarflare.com)
+submitted by Ben Hutchings (bwh@kernel.org)
 
 Authors:
 Tom Herbert (therbert@google.com)
diff --git a/Documentation/serial/00-INDEX b/Documentation/serial/00-INDEX
index f9c6b5e..8021a9f 100644
--- a/Documentation/serial/00-INDEX
+++ b/Documentation/serial/00-INDEX
@@ -2,23 +2,15 @@
 	- this file.
 README.cycladesZ
 	- info on Cyclades-Z firmware loading.
-digiepca.txt
-	- info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
 driver
 	- intro to the low level serial driver.
 moxa-smartio
 	- file with info on installing/using Moxa multiport serial driver.
 n_gsm.txt
 	- GSM 0710 tty multiplexer howto.
-riscom8.txt
-	- notes on using the RISCom/8 multi-port serial driver.
 rocket.txt
 	- info on the Comtrol RocketPort multiport serial driver.
 serial-rs485.txt
 	- info about RS485 structures and support in the kernel.
-specialix.txt
-	- info on hardware/driver for specialix IO8+ multiport serial card.
-sx.txt
-	- info on the Specialix SX/SI multiport serial driver.
 tty.txt
 	- guide to the locking policies of the tty layer.
diff --git a/Documentation/serial/digiepca.txt b/Documentation/serial/digiepca.txt
deleted file mode 100644
index f2560e2..0000000
--- a/Documentation/serial/digiepca.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-NOTE:  This driver is obsolete.  Digi provides a 2.6 driver (dgdm) at
-http://www.digi.com for PCI cards.  They no longer maintain this driver,
-and have no 2.6 driver for ISA cards.
-
-This driver requires a number of user-space tools.  They can be acquired from
-http://www.digi.com, but only works with 2.4 kernels.
-
-
-The Digi Intl. epca driver. 
-----------------------------
-The Digi Intl. epca driver for Linux supports the following boards:
-
-Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve 
-Digi EISA/Xem, PCI/Xem, PCI/Xr 
-
-Limitations:
-------------
-Currently the driver only autoprobes for supported PCI boards. 
-
-The Linux MAKEDEV command does not support generating the Digiboard
-Devices.  Users executing digiConfig to setup EISA and PC series cards
-will have their device nodes automatically constructed (cud?? for ~CLOCAL,
-and ttyD?? for CLOCAL).  Users wishing to boot their board from the LILO
-prompt, or those users booting PCI cards may use buildDIGI to construct 
-the necessary nodes. 
-
-Notes:
-------
-This driver may be configured via LILO.  For users who have already configured
-their driver using digiConfig, configuring from LILO will override previous 
-settings.  Multiple boards may be configured by issuing multiple LILO command 
-lines.  For examples see the bottom of this document.
-
-Device names start at 0 and continue up.  Beware of this as previous Digi 
-drivers started device names with 1.
-
-PCI boards are auto-detected and configured by the driver.  PCI boards will
-be allocated device numbers (internally) beginning with the lowest PCI slot
-first.  In other words a PCI card in slot 3 will always have higher device
-nodes than a PCI card in slot 1. 
-
-LILO config examples:
----------------------
-Using LILO's APPEND command, a string of comma separated identifiers or 
-integers can be used to configure supported boards.  The six values in order 
-are:
-
-   Enable/Disable this card or Override,
-   Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2), 
-                 EISA/Xem (3), PC/64Xe (4), PC/Xi (5), 
-   Enable/Disable alternate pin arrangement,
-   Number of ports on this card,
-   I/O Port where card is configured (in HEX if using string identifiers),
-   Base of memory window (in HEX if using string identifiers), 
-
-NOTE : PCI boards are auto-detected and configured.  Do not attempt to 
-configure PCI boards with the LILO append command.  If you wish to override
-previous configuration data (As set by digiConfig), but you do not wish to
-configure any specific card (Example if there are PCI cards in the system) 
-the following override command will accomplish this:
--> append="digi=2"
-
-Samples:
-   append="digiepca=E,PC/Xe,D,16,200,D0000"
-                  or
-   append="digi=1,0,0,16,512,851968"
-
-Supporting Tools:
------------------
-Supporting tools include digiDload, digiConfig, buildPCI, and ditty.  See
-drivers/char/README.epca for more details.  Note,
-this driver REQUIRES that digiDload be executed prior to it being used. 
-Failure to do this will result in an ENODEV error.
-
-Documentation:
---------------
-Complete documentation for this product may be found in the tool package. 
-
-Sources of information and support:
------------------------------------
-Digi Intl. support site for this product:
-
-->  http://www.digi.com
-
-Acknowledgments:
-----------------
-Much of this work (And even text) was derived from a similar document 
-supporting the original public domain DigiBoard driver Copyright (C)
-1994,1995 Troy De Jongh.  Many thanks to Christoph Lameter 
-(christoph@lameter.com) and Mike McLagan (mike.mclagan@linux.org) who authored 
-and contributed to the original document. 
-
-Changelog:
-----------
-10-29-04:	Update status of driver, remove dead links in document
-		James Nelson <james4765@gmail.com>
-
-2000 (?)	Original Document
diff --git a/Documentation/serial/riscom8.txt b/Documentation/serial/riscom8.txt
deleted file mode 100644
index 14f61fd..0000000
--- a/Documentation/serial/riscom8.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-* NOTE - this is an unmaintained driver.  The original author cannot be located.
-
-SDL Communications is now SBS Technologies, and does not have any
-information on these ancient ISA cards on their website.
-
-James Nelson <james4765@gmail.com> - 12-12-2004
-
-	This is the README for RISCom/8 multi-port serial driver
-	(C) 1994-1996 D.Gorodchanin
-	See file LICENSE for terms and conditions.
-
-NOTE: English is not my native language. 
-      I'm sorry for any mistakes in this text.
-
-Misc. notes for RISCom/8 serial driver, in no particular order :)
-
-1) This driver can support up to 4 boards at time.
-   Use string "riscom8=0xXXX,0xXXX,0xXXX,0xXXX" at LILO prompt, for
-   setting I/O base addresses for boards. If you compile driver
-   as module use modprobe options "iobase=0xXXX iobase1=0xXXX iobase2=..."
-
-2) The driver partially supports famous 'setserial' program, you can use almost
-   any of its options, excluding port & irq settings.
-
-3) There are some misc. defines at the beginning of riscom8.c, please read the 
-   comments and try to change some of them in case of problems.
-
-4) I consider the current state of the driver as BETA.
-
-5) SDL Communications WWW page is http://www.sdlcomm.com.
-
-6) You can use the MAKEDEV program to create RISCom/8 /dev/ttyL* entries.
-
-7) Minor numbers for first board are 0-7, for second 8-15, etc.
-
-22 Apr 1996.
diff --git a/Documentation/serial/specialix.txt b/Documentation/serial/specialix.txt
deleted file mode 100644
index 6eb6f3a..0000000
--- a/Documentation/serial/specialix.txt
+++ /dev/null
@@ -1,383 +0,0 @@
-
-      specialix.txt  -- specialix IO8+ multiport serial driver readme.
-
-
-
-      Copyright (C) 1997  Roger Wolff (R.E.Wolff@BitWizard.nl)
-
-      Specialix pays for the development and support of this driver.
-      Please DO contact io8-linux@specialix.co.uk if you require
-      support.
-
-      This driver was developed in the BitWizard linux device
-      driver service. If you require a linux device driver for your
-      product, please contact devices@BitWizard.nl for a quote.
-
-      This code is firmly based on the riscom/8 serial driver,
-      written by Dmitry Gorodchanin. The specialix IO8+ card
-      programming information was obtained from the CL-CD1865 Data
-      Book, and Specialix document number 6200059: IO8+ Hardware
-      Functional Specification, augmented by document number 6200088:
-      Merak Hardware Functional Specification. (IO8+/PCI is also 
-      called Merak)
-
-
-      This program is free software; you can redistribute it and/or
-      modify it under the terms of the GNU General Public License as
-      published by the Free Software Foundation; either version 2 of
-      the License, or (at your option) any later version.
-
-      This program is distributed in the hope that it will be
-      useful, but WITHOUT ANY WARRANTY; without even the implied
-      warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-      PURPOSE.  See the GNU General Public License for more details.
-
-      You should have received a copy of the GNU General Public
-      License along with this program; if not, write to the Free
-      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
-      USA.
-
-
-Intro
-=====
-
- 
-This file contains some random information, that I like to have online
-instead of in a manual that can get lost. Ever misplace your Linux
-kernel sources?  And the manual of one of the boards in your computer?
-
-
-Addresses and interrupts
-========================
-
-Address dip switch settings:
-The dip switch sets bits 2-9 of the IO address. 
-
-       9 8 7 6 5 4 3 2 
-     +-----------------+
-   0 | X   X X X X X X |
-     |                 |    =   IoBase = 0x100 
-   1 |   X             |
-     +-----------------+          ------ RS232 connectors ---->
-         
-         |    |    |
-       edge connector
-         |    |    |
-         V    V    V
-
-Base address 0x100 caused a conflict in one of my computers once.  I
-haven't the foggiest why. My Specialix card is now at 0x180.  My
-other computer runs just fine with the Specialix card at 0x100....
-The card occupies 4 addresses, but actually only two are really used.
-
-The PCI version doesn't have any dip switches. The BIOS assigns
-an IO address. 
-
-The driver now still autoprobes at 0x100, 0x180, 0x250 and 0x260.  If
-that causes trouble for you, please report that. I'll remove
-autoprobing then.
-
-The driver will tell the card what IRQ to use, so you don't have to
-change any jumpers to change the IRQ. Just use a command line
-argument (irq=xx) to the insmod program to set the interrupt.
-
-The BIOS assigns the IRQ on the PCI version. You have no say in what
-IRQ to use in that case. 
-
-If your specialix cards are not at the default locations, you can use
-the kernel command line argument "specialix=io0,irq0,io1,irq1...".
-Here "io0" is the io address for the first card, and "irq0" is the
-irq line that the first card should use. And so on. 
-
-Examples. 
-
-You use the driver as a module and have three cards at 0x100, 0x250
-and 0x180. And some way or another you want them detected in that
-order. Moreover irq 12 is taken (e.g. by your PS/2 mouse).
-
-  insmod specialix.o iobase=0x100,0x250,0x180 irq=9,11,15
-
-The same three cards, but now in the kernel would require you to
-add 
-
-   specialix=0x100,9,0x250,11,0x180,15
-
-to the command line. This would become 
-
-   append="specialix=0x100,9,0x250,11,0x180,15" 
-
-in your /etc/lilo.conf file if you use lilo. 
-
-The Specialix driver is slightly odd: It allows you to have the second
-or third card detected without having a first card. This has
-advantages and disadvantages. A slot that isn't filled by an ISA card,
-might be filled if a PCI card is detected. Thus if you have an ISA
-card at 0x250 and a PCI card, you would get:
-
-sx0: specialix IO8+ Board at 0x100 not found.
-sx1: specialix IO8+ Board at 0x180 not found.
-sx2: specialix IO8+ board detected at 0x250, IRQ 12, CD1865 Rev. B.
-sx3: specialix IO8+ Board at 0x260 not found.
-sx0: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
-
-This would happen if you don't give any probe hints to the driver. 
-If you would specify:
-
-   specialix=0x250,11
-
-you'd get the following messages:
-
-sx0: specialix IO8+ board detected at 0x250, IRQ 11, CD1865 Rev. B.
-sx1: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
-
-ISA probing is aborted after the IO address you gave is exhausted, and
-the PCI card is now detected as the second card. The ISA card is now
-also forced to IRQ11....
-
-
-Baud rates
-==========
-
-The rev 1.2 and below boards use a CL-CD1864. These chips can only 
-do 64kbit. The rev 1.3 and newer boards use a CL-CD1865. These chips
-are officially capable of 115k2.
-
-The Specialix card uses a 25MHz crystal (in times two mode, which in
-fact is a divided by two mode). This is not enough to reach the rated
-115k2 on all ports at the same time. With this clock rate you can only
-do 37% of this rate. This means that at 115k2 on all ports you are
-going to lose characters (The chip cannot handle that many incoming
-bits at this clock rate.) (Yes, you read that correctly: there is a
-limit to the number of -=bits=- per second that the chip can handle.)
-
-If you near the "limit" you will first start to see a graceful
-degradation in that the chip cannot keep the transmitter busy at all
-times. However with a central clock this slow, you can also get it to
-miss incoming characters. The driver will print a warning message when
-you are outside the official specs. The messages usually show up in
-the file /var/log/messages .
-
-The specialix card cannot reliably do 115k2. If you use it, you have
-to do "extensive testing" (*) to verify if it actually works.
-
-When "mgetty" communicates with my modem at 115k2 it reports:
-got: +++[0d]ATQ0V1H0[0d][0d][8a]O[cb][0d][8a]
-                            ^^^^ ^^^^    ^^^^ 
-
-The three characters that have the "^^^" under them have suffered a
-bit error in the highest bit. In conclusion: I've tested it, and found
-that it simply DOESN'T work for me. I also suspect that this is also
-caused by the baud rate being just a little bit out of tune. 
-
-I upgraded the crystal to 66Mhz on one of my Specialix cards. Works
-great! Contact me for details. (Voids warranty, requires a steady hand
-and more such restrictions....)
-
-
-(*) Cirrus logic CD1864 databook, page 40.
-
-
-Cables for the Specialix IO8+
-=============================
-
-The pinout of the connectors on the IO8+ is:
-
-     pin    short    direction    long name
-            name
-    Pin 1   DCD      input        Data Carrier Detect
-    Pin 2   RXD      input        Receive
-    Pin 3   DTR/RTS  output       Data Terminal Ready/Ready To Send
-    Pin 4   GND      -            Ground
-    Pin 5   TXD      output       Transmit
-    Pin 6   CTS      input        Clear To Send
-        
-    
-             -- 6  5  4  3  2  1 --
-             |                    |
-             |                    |
-             |                    |
-             |                    |
-             +-----          -----+
-                  |__________|
-                      clip
-    
-    Front view of an RJ12 connector. Cable moves "into" the paper.
-    (the plug is ready to plug into your mouth this way...)
-
-    
-    NULL cable. I don't know who is going to use these except for
-    testing purposes, but I tested the cards with this cable. (It 
-    took quite a while to figure out, so I'm not going to delete
-    it. So there! :-)
-    
-    
-    This end goes               This end needs
-    straight into the           some twists in
-    RJ12 plug.                  the wiring.
-       IO8+ RJ12                   IO8+ RJ12
-        1  DCD       white          -
-        -             -             1 DCD
-        2  RXD       black          5 TXD
-        3  DTR/RTS   red            6 CTS
-        4  GND       green          4 GND
-        5  TXD       yellow         2 RXD
-        6  CTS       blue           3 DTR/RTS
-    
-
-    Same NULL cable, but now sorted on the second column.
- 
-        1  DCD       white          -
-        -             -             1 DCD
-        5  TXD       yellow         2 RXD
-        6  CTS       blue           3 DTR/RTS
-        4  GND       green          4 GND
-        2  RXD       black          5 TXD
-        3  DTR/RTS   red            6 CTS
-    
-    
-    
-    This is a modem cable usable for hardware handshaking:
-        RJ12                        DB25           DB9
-        1   DCD      white          8 DCD          1 DCD
-        2   RXD      black          3 RXD          2 RXD
-        3   DTR/RTS  red            4 RTS          7 RTS
-        4   GND      green          7 GND          5 GND
-        5   TXD      yellow         2 TXD          3 TXD
-        6   CTS      blue           5 CTS          8 CTS
-                            +----   6 DSR          6 DSR
-                            +----  20 DTR          4 DTR
-
-    This is a modem cable usable for software handshaking:
-    It allows you to reset the modem using the DTR ioctls.
-    I (REW) have never tested this, "but xxxxxxxxxxxxx
-    says that it works." If you test this, please
-    tell me and I'll fill in your name on the xxx's.
-
-        RJ12                        DB25           DB9
-        1   DCD      white          8 DCD          1 DCD
-        2   RXD      black          3 RXD          2 RXD
-        3   DTR/RTS  red           20 DTR          4 DTR
-        4   GND      green          7 GND          5 GND
-        5   TXD      yellow         2 TXD          3 TXD
-        6   CTS      blue           5 CTS          8 CTS
-                            +----   6 DSR          6 DSR
-                            +----   4 RTS          7 RTS
-
-   I bought a 6 wire flat cable. It was colored as indicated.
-   Check that yours is the same before you trust me on this.
-   
- 
-Hardware handshaking issues.
-============================
-
-The driver can be told to operate in two different ways. The default
-behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when
-hardware handshaking is off. It behaves as the RTS hardware
-handshaking signal when hardware handshaking is selected.
-
-When you use this, you have to use the appropriate cable. The
-cable will either be compatible with hardware handshaking or with
-software handshaking. So switching on the fly is not really an
-option.
-
-I actually prefer to use the "specialix.sx_rtscts=1" option.
-This makes the DTR/RTS pin always an RTS pin, and ioctls to
-change DTR are always ignored. I have a cable that is configured
-for this. 
-
-
-Ports and devices
-=================
-
-Port 0 is the one furthest from the card-edge connector.
-
-Devices:
-
-You should make the devices as follows:
-
-bash
-cd /dev
-for i in  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 \
-         16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
-do
-  echo -n "$i "
-  mknod /dev/ttyW$i c 75 $i
-  mknod /dev/cuw$i c 76 $i
-done
-echo ""
-
-If your system doesn't come with these devices preinstalled, bug your
-linux-vendor about this. They have had ample time to get this
-implemented by now.
-
-You cannot have more than 4 boards in one computer. The card only
-supports 4 different interrupts. If you really want this, contact me
-about this and I'll give you a few tips (requires soldering iron)....
-
-If you have enough PCI slots, you can probably use more than 4 PCI
-versions of the card though.... 
-
-The PCI version of the card cannot adhere to the mechanical part of
-the PCI spec because the 8 serial connectors are simply too large. If
-it doesn't fit in your computer, bring back the card.
-
-
-------------------------------------------------------------------------
-
-
-  Fixed bugs and restrictions:
-       - During initialization, interrupts are blindly turned on.
-            Having a shadow variable would cause an extra memory
-            access on every IO instruction. 
-       - The interrupt (on the card) should be disabled when we
-         don't allocate the Linux end of the interrupt. This allows 
-         a different driver/card to use it while all ports are not in
-         use..... (a la standard serial port)
-       == An extra _off variant of the sx_in and sx_out macros are
-          now available. They don't set the interrupt enable bit.
-          These are used during initialization. Normal operation uses
-          the old variant which enables the interrupt line.
-       - RTS/DTR issue needs to be implemented according to 
-         specialix' spec.
-            I kind of like the "determinism" of the current 
-            implementation. Compile time flag?
-       == Ok. Compile time flag! Default is how Specialix likes it.
-       == Now a config time flag! Gets saved in your config file. Neat!
-       - Can you set the IO address from the lilo command line?
-            If you need this, bug me about it, I'll make it. 
-       == Hah! No bugging needed. Fixed! :-)
-       - Cirrus logic hasn't gotten back to me yet why the CD1865 can
-            and the CD1864 can't do 115k2. I suspect that this is
-            because the CD1864 is not rated for 33MHz operation.
-            Therefore the CD1864 versions of the card can't do 115k2 on 
-            all ports just like the CD1865 versions. The driver does
-            not block 115k2 on CD1864 cards. 
-        == I called the Cirrus Logic representative here in Holland.
-           The CD1864 databook is identical to the CD1865 databook, 
-           except for an extra warning at the end. Similar Bit errors
-           have been observed in testing at 115k2 on both an 1865 and
-           a 1864 chip. I see no reason why I would prohibit 115k2 on
-           1864 chips and not do it on 1865 chips. Actually there is
-           reason to prohibit it on BOTH chips. I print a warning.
-           If you use 115k2, you're on your own. 
-       - A spiky CD may send spurious HUPs. Also in CLOCAL???
-         -- A fix for this turned out to be counter productive. 
-            Different fix? Current behaviour is acceptable?
-         -- Maybe the current implementation is correct. If anybody
-            gets bitten by this, please report, and it will get fixed.
-
-         -- Testing revealed that when in CLOCAL, the problem doesn't
-            occur. As warned for in the CD1865 manual, the chip may
-            send modem intr's on a spike. We could filter those out,
-            but that would be a cludge anyway (You'd still risk getting
-            a spurious HUP when two spikes occur.).....
- 
-
-
-  Bugs & restrictions:
-       - This is a difficult card to autoprobe.
-            You have to WRITE to the address register to even 
-            read-probe a CD186x register. Disable autodetection?
-         -- Specialix: any suggestions?
-
-
diff --git a/Documentation/serial/sx.txt b/Documentation/serial/sx.txt
deleted file mode 100644
index cb4efa0..0000000
--- a/Documentation/serial/sx.txt
+++ /dev/null
@@ -1,294 +0,0 @@
-
-      sx.txt  -- specialix SX/SI multiport serial driver readme.
-
-
-
-      Copyright (C) 1997  Roger Wolff (R.E.Wolff@BitWizard.nl)
-
-      Specialix pays for the development and support of this driver.
-      Please DO contact support@specialix.co.uk if you require
-      support.
-
-      This driver was developed in the BitWizard linux device
-      driver service. If you require a linux device driver for your
-      product, please contact devices@BitWizard.nl for a quote.
-
-      (History)
-      There used to be an SI driver by Simon Allan. This is a complete 
-      rewrite  from scratch. Just a few lines-of-code have been snatched.
-
-      (Sources)
-      Specialix document number 6210028: SX Host Card and Download Code
-      Software Functional Specification.
-
-      (Copying)
-      This program is free software; you can redistribute it and/or
-      modify it under the terms of the GNU General Public License as
-      published by the Free Software Foundation; either version 2 of
-      the License, or (at your option) any later version.
-
-      This program is distributed in the hope that it will be
-      useful, but WITHOUT ANY WARRANTY; without even the implied
-      warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-      PURPOSE.  See the GNU General Public License for more details.
-
-      You should have received a copy of the GNU General Public
-      License along with this program; if not, write to the Free
-      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
-      USA.
-      
-      (Addendum)
-      I'd appreciate it that if you have fixes, that you send them
-      to me first. 
-
-
-Introduction
-============
-
-This file contains some random information, that I like to have online
-instead of in a manual that can get lost. Ever misplace your Linux
-kernel sources?  And the manual of one of the boards in your computer?
-
-
-Theory of operation
-===================
-
-An important thing to know is that the driver itself doesn't have the
-firmware for the card. This means that you need the separate package
-"sx_firmware". For now you can get the source at
-
-	ftp://ftp.bitwizard.nl/specialix/sx_firmware_<version>.tgz
-
-The firmware load needs a "misc" device, so you'll need to enable the
-"Support for user misc device modules" in your kernel configuration.
-The misc device needs to be called "/dev/specialix_sxctl". It needs
-misc major 10, and minor number 167 (assigned by HPA). The section
-on creating device files below also creates this device. 
-
-After loading the sx.o module into your kernel, the driver will report
-the number of cards detected, but because it doesn't have any
-firmware, it will not be able to determine the number of ports. Only
-when you then run "sx_firmware" will the firmware be downloaded and
-the rest of the driver initialized. At that time the sx_firmware
-program will report the number of ports installed.
-
-In contrast with many other multi port serial cards, some of the data
-structures are only allocated when the card knows the number of ports
-that are connected. This means we won't waste memory for 120 port
-descriptor structures when you only have 8 ports. If you experience
-problems due to this, please report them: I haven't seen any.
-
-
-Interrupts
-==========
-
-A multi port serial card, would generate a horrendous amount of
-interrupts if it would interrupt the CPU for every received
-character. Even more than 10 years ago, the trick not to use
-interrupts but to poll the serial cards was invented.
-
-The SX card allow us to do this two ways. First the card limits its
-own interrupt rate to a rate that won't overwhelm the CPU. Secondly,
-we could forget about the cards interrupt completely and use the
-internal timer for this purpose.
-
-Polling the card can take up to a few percent of your CPU. Using the
-interrupts would be better if you have most of the ports idle. Using
-timer-based polling is better if your card almost always has work to
-do. You save the separate interrupt in that case.
-
-In any case, it doesn't really matter all that much. 
-
-The most common problem with interrupts is that for ISA cards in a PCI
-system the BIOS has to be told to configure that interrupt as "legacy
-ISA". Otherwise the card can pull on the interrupt line all it wants
-but the CPU won't see this.
-
-If you can't get the interrupt to work, remember that polling mode is
-more efficient (provided you actually use the card intensively).
-
-
-Allowed Configurations
-======================
-
-Some configurations are disallowed. Even though at a glance they might
-seem to work, they are known to lockup the bus between the host card
-and the device concentrators. You should respect the drivers decision
-not to support certain configurations. It's there for a reason.
-
-Warning: Seriously technical stuff ahead. Executive summary: Don't use
-SX cards except configured at a 64k boundary. Skip the next paragraph.
-
-The SX cards can theoretically be placed at a 32k boundary. So for
-instance you can put an SX card at 0xc8000-0xd7fff. This is not a
-"recommended configuration". ISA cards have to tell the bus controller
-how they like their timing. Due to timing issues they have to do this
-based on which 64k window the address falls into. This means that the
-32k window below and above the SX card have to use exactly the same
-timing as the SX card. That reportedly works for other SX cards. But
-you're still left with two useless 32k windows that should not be used
-by anybody else.
-
-
-Configuring the driver
-======================
-
-PCI cards are always detected. The driver auto-probes for ISA cards at
-some sensible addresses. Please report if the auto-probe causes trouble
-in your system, or when a card isn't detected.
-
-I'm afraid I haven't implemented "kernel command line parameters" yet.
-This means that if the default doesn't work for you, you shouldn't use
-the compiled-into-the-kernel version of the driver. Use a module
-instead.  If you convince me that you need this, I'll make it for
-you. Deal?
-
-I'm afraid that the module parameters are a bit clumsy. If you have a
-better idea, please tell me.
-
-You can specify several parameters:
-
-	sx_poll: number of jiffies between timer-based polls.
-
-		Set this to "0" to disable timer based polls. 
-                Initialization of cards without a working interrupt
-                will fail.
-
-		Set this to "1" if you want a polling driver. 
-		(on Intel: 100 polls per second). If you don't use
-                fast baud rates, you might consider a value like "5". 
-                (If you don't know how to do the math, use 1).
-
-	sx_slowpoll: Number of jiffies between timer-based polls. 
- 		Set this to "100" to poll once a second. 
-		This should get the card out of a stall if the driver
-                ever misses an interrupt. I've never seen this happen,
-                and if it does, that's a bug. Tell me. 
-
-	sx_maxints: Number of interrupts to request from the card. 
-		The card normally limits interrupts to about 100 per
-		second to offload the host CPU. You can increase this
-		number to reduce latency on the card a little.
-		Note that if you give a very high number you can overload
-		your CPU as well as the CPU on the host card. This setting 
-		is inaccurate and not recommended for SI cards (But it 
-		works). 
-
-	sx_irqmask: The mask of allowable IRQs to use. I suggest you set 
-		this to 0 (disable IRQs all together) and use polling if 
-		the assignment of IRQs becomes problematic. This is defined
-		as the sum of (1 << irq) 's that you want to allow. So 
-		sx_irqmask of 8 (1 << 3) specifies that only irq 3 may
-		be used by the SX driver. If you want to specify to the 
-		driver: "Either irq 11 or 12 is ok for you to use", then
-		specify (1 << 11) | (1 << 12) = 0x1800 . 
-
-	sx_debug: You can enable different sorts of debug traces with this. 
-		At "-1" all debugging traces are active. You'll get several
-		times more debugging output than you'll get characters 
-		transmitted. 
-
-
-Baud rates
-==========
-
-Theoretically new SXDCs should be capable of more than 460k
-baud. However the line drivers usually give up before that.  Also the
-CPU on the card may not be able to handle 8 channels going at full
-blast at that speed. Moreover, the buffers are not large enough to
-allow operation with 100 interrupts per second. You'll have to realize
-that the card has a 256 byte buffer, so you'll have to increase the
-number of interrupts per second if you have more than 256*100 bytes
-per second to transmit.  If you do any performance testing in this
-area, I'd be glad to hear from you...
-
-(Psst Linux users..... I think the Linux driver is more efficient than
-the driver for other OSes. If you can and want to benchmark them
-against each other, be my guest, and report your findings...... :-)
-
-
-Ports and devices
-=================
-
-Port 0 is the top connector on the module closest to the host
-card. Oh, the ports on the SXDCs and TAs are labelled from 1 to 8
-instead of from 0 to 7, as they are numbered by linux. I'm stubborn in
-this: I know for sure that I wouldn't be able to calculate which port
-is which anymore if I would change that....
-
-
-Devices:
-
-You should make the device files as follows:
-
-#!/bin/sh
-# (I recommend that you cut-and-paste this into a file and run that)
-cd /dev
-t=0
-mknod specialix_sxctl c 10 167
-while [ $t -lt 64 ]
-  do 
-  echo -n "$t "
-  mknod ttyX$t c 32 $t
-  mknod cux$t  c 33 $t
-  t=`expr $t + 1`
-done
-echo ""
-rm /etc/psdevtab
-ps > /dev/null
-
-
-This creates 64 devices. If you have more, increase the constant on
-the line with "while". The devices start at 0, as is customary on
-Linux. Specialix seems to like starting the numbering at 1. 
-
-If your system doesn't come with these devices pre-installed, bug your
-linux-vendor about this. They should have these devices
-"pre-installed" before the new millennium. The "ps" stuff at the end
-is to "tell" ps that the new devices exist.
-
-Officially the maximum number of cards per computer is 4. This driver
-however supports as many cards in one machine as you want. You'll run
-out of interrupts after a few, but you can switch to polled operation
-then. At about 256 ports (More than 8 cards), we run out of minor
-device numbers. Sorry. I suggest you buy a second computer.... (Or
-switch to RIO).
-
-------------------------------------------------------------------------
-
-
-  Fixed bugs and restrictions:
-	- Hangup processing.  
-	  -- Done.
-
-	- the write path in generic_serial (lockup / oops). 
-	  -- Done (Ugly: not the way I want it. Copied from serial.c).
-
-        - write buffer isn't flushed at close.
-	  -- Done. I still seem to lose a few chars at close. 
-	     Sorry. I think that this is a firmware issue. (-> Specialix)
-
-	- drain hardware before  changing termios
-	- Change debug on the fly. 
-	- ISA free irq -1. (no firmware loaded).
-	- adding c8000 as a probe address. Added warning. 
-	- Add a RAMtest for the RAM on the card.c
-        - Crash when opening a port "way" of the number of allowed ports. 
-          (for example opening port 60 when there are only 24 ports attached)
-	- Sometimes the use-count strays a bit. After a few hours of
-          testing the use count is sometimes "3". If you are not like
-          me and can remember what you did to get it that way, I'd
-          appreciate an Email. Possibly fixed. Tell me if anyone still
-          sees this.
-	- TAs don't work right if you don't connect all the modem control
-	  signals. SXDCs do. T225 firmware problem -> Specialix. 
-	  (Mostly fixed now, I think. Tell me if you encounter this!)
-
-  Bugs & restrictions:
-
-	- Arbitrary baud rates. Requires firmware update. (-> Specialix)
-
-	- Low latency (mostly firmware, -> Specialix)
-
-
-
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt
index b0714d8..cbc2f03 100644
--- a/Documentation/stable_kernel_rules.txt
+++ b/Documentation/stable_kernel_rules.txt
@@ -39,7 +39,7 @@
    the stable tree without anything else needing to be done by the author
    or subsystem maintainer.
  - If the patch requires other patches as prerequisites which can be
-   cherry-picked than this can be specified in the following format in
+   cherry-picked, then this can be specified in the following format in
    the sign-off area:
 
      Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 4e7da65..badb050 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -174,7 +174,6 @@
 	allocation fails, the kernel will search other nodes, in order of
 	increasing distance from the preferred node based on information
 	provided by the platform firmware.
-	containing the cpu where the allocation takes place.
 
 	    Internally, the Preferred policy uses a single node--the
 	    preferred_node member of struct mempolicy.  When the internal
@@ -275,9 +274,9 @@
 	    For example, consider a task that is attached to a cpuset with
 	    mems 2-5 that sets an Interleave policy over the same set with
 	    MPOL_F_RELATIVE_NODES.  If the cpuset's mems change to 3-7, the
-	    interleave now occurs over nodes 3,5-6.  If the cpuset's mems
+	    interleave now occurs over nodes 3,5-7.  If the cpuset's mems
 	    then change to 0,2-3,5, then the interleave occurs over nodes
-	    0,3,5.
+	    0,2-3,5.
 
 	    Thanks to the consistent remapping, applications preparing
 	    nodemasks to specify memory policies using this flag should
diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO
index 6c914aa..54ea24f 100644
--- a/Documentation/zh_CN/HOWTO
+++ b/Documentation/zh_CN/HOWTO
@@ -237,7 +237,7 @@
 如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
 版内核。
 
-2.6.x.y版本由“稳定版”小组(邮件地址<stable@kernel.org>)维护,一般隔周发
+2.6.x.y版本由“稳定版”小组(邮件地址<stable@vger.kernel.org>)维护,一般隔周发
 布新版本。
 
 内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
diff --git a/Documentation/zh_CN/io_ordering.txt b/Documentation/zh_CN/io_ordering.txt
new file mode 100644
index 0000000..e592daf
--- /dev/null
+++ b/Documentation/zh_CN/io_ordering.txt
@@ -0,0 +1,67 @@
+Chinese translated version of Documentation/io_orderings.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly.  However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help.  Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Chinese maintainer: Lin Yongting <linyongting@gmail.com>
+---------------------------------------------------------------------
+Documentation/io_ordering.txt 的中文翻译
+
+如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
+交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
+译存在问题,请联系中文版维护者。
+
+中文版维护者: 林永听 Lin Yongting <linyongting@gmail.com>
+中文版翻译者: 林永听 Lin Yongting <linyongting@gmail.com>
+中文版校译者: 林永听 Lin Yongting <linyongting@gmail.com>
+
+
+以下为正文
+---------------------------------------------------------------------
+
+在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
+保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
+设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
+而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
+这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
+屏障操作,mb(),不过仅适用于I/O)。
+
+假设一个设备驱动程的具体例子:
+
+        ...
+CPU A:  spin_lock_irqsave(&dev_lock, flags)
+CPU A:  val = readl(my_status);
+CPU A:  ...
+CPU A:  writel(newval, ring_ptr);
+CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
+        ...
+CPU B:  spin_lock_irqsave(&dev_lock, flags)
+CPU B:  val = readl(my_status);
+CPU B:  ...
+CPU B:  writel(newval2, ring_ptr);
+CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
+        ...
+
+上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
+发生了。不过很容易通过下面方法来修复:
+
+        ...
+CPU A:  spin_lock_irqsave(&dev_lock, flags)
+CPU A:  val = readl(my_status);
+CPU A:  ...
+CPU A:  writel(newval, ring_ptr);
+CPU A:  (void)readl(safe_register); /* 配置寄存器?*/
+CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
+        ...
+CPU B:  spin_lock_irqsave(&dev_lock, flags)
+CPU B:  val = readl(my_status);
+CPU B:  ...
+CPU B:  writel(newval2, ring_ptr);
+CPU B:  (void)readl(safe_register); /* 配置寄存器?*/
+CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
+
+在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
+再处理后面的读操作,防止引发数据不一致问题。
diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt
index 2ebe539..dfb72a5 100644
--- a/Documentation/zh_CN/magic-number.txt
+++ b/Documentation/zh_CN/magic-number.txt
@@ -63,8 +63,6 @@
 PG_MAGIC              'P'         pg_{read,write}_hdr include/linux/pg.h
 CMAGIC                0x0111      user              include/linux/a.out.h
 MKISS_DRIVER_MAGIC    0x04bf      mkiss_channel     drivers/net/mkiss.h
-RISCOM8_MAGIC         0x0907      riscom_port       drivers/char/riscom8.h
-SPECIALIX_MAGIC       0x0907      specialix_port    drivers/char/specialix_io8.h
 HDLC_MAGIC            0x239e      n_hdlc            drivers/char/n_hdlc.c
 APM_BIOS_MAGIC        0x4101      apm_user          arch/x86/kernel/apm_32.c
 CYCLADES_MAGIC        0x4359      cyclades_port     include/linux/cyclades.h
@@ -82,7 +80,6 @@
 X25_ASY_MAGIC         0x5303      x25_asy           drivers/net/x25_asy.h
 SIXPACK_MAGIC         0x5304      sixpack           drivers/net/hamradio/6pack.h
 AX25_MAGIC            0x5316      ax_disp           drivers/net/mkiss.h
-ESP_MAGIC             0x53ee      esp_struct        drivers/char/esp.h
 TTY_MAGIC             0x5401      tty_struct        include/linux/tty.h
 MGSL_MAGIC            0x5401      mgsl_info         drivers/char/synclink.c
 TTY_DRIVER_MAGIC      0x5402      tty_driver        include/linux/tty_driver.h
@@ -94,13 +91,10 @@
 RFCOMM_TTY_MAGIC      0x6d02                        net/bluetooth/rfcomm/tty.c
 USB_SERIAL_PORT_MAGIC 0x7301      usb_serial_port   drivers/usb/serial/usb-serial.h
 CG_MAGIC              0x00090255  ufs_cylinder_group include/linux/ufs_fs.h
-A2232_MAGIC           0x000a2232  gs_port           drivers/char/ser_a2232.h
 RPORT_MAGIC           0x00525001  r_port            drivers/char/rocket_int.h
 LSEMAGIC              0x05091998  lse               drivers/fc4/fc.c
 GDTIOCTL_MAGIC        0x06030f07  gdth_iowr_str     drivers/scsi/gdth_ioctl.h
 RIEBL_MAGIC           0x09051990                    drivers/net/atarilance.c
-RIO_MAGIC             0x12345678  gs_port           drivers/char/rio/rio_linux.c
-SX_MAGIC              0x12345678  gs_port           drivers/char/sx.h
 NBD_REQUEST_MAGIC     0x12560953  nbd_request       include/linux/nbd.h
 RED_MAGIC2            0x170fc2a5  (any)             mm/slab.c
 BAYCOM_MAGIC          0x19730510  baycom_state      drivers/net/baycom_epp.c
@@ -116,7 +110,6 @@
 CTC_ASYNC_MAGIC       0x49344C01  ctc_tty_info      drivers/s390/net/ctctty.c
 ISDN_NET_MAGIC        0x49344C02  isdn_net_local_s  drivers/isdn/i4l/isdn_net_lib.h
 SAVEKMSG_MAGIC2       0x4B4D5347  savekmsg          arch/*/amiga/config.c
-STLI_BOARDMAGIC       0x4bc6c825  stlibrd           include/linux/istallion.h
 CS_STATE_MAGIC        0x4c4f4749  cs_state          sound/oss/cs46xx.c
 SLAB_C_MAGIC          0x4f17a36d  kmem_cache        mm/slab.c
 COW_MAGIC             0x4f4f4f4d  cow_header_v1     arch/um/drivers/ubd_user.c
@@ -127,10 +120,8 @@
 SAVEKMSG_MAGIC1       0x53415645  savekmsg          arch/*/amiga/config.c
 GDA_MAGIC             0x58464552  gda               arch/mips/include/asm/sn/gda.h
 RED_MAGIC1            0x5a2cf071  (any)             mm/slab.c
-STL_PORTMAGIC         0x5a7182c9  stlport           include/linux/stallion.h
 EEPROM_MAGIC_VALUE    0x5ab478d2  lanai_dev         drivers/atm/lanai.c
 HDLCDRV_MAGIC         0x5ac6e778  hdlcdrv_state     include/linux/hdlcdrv.h
-EPCA_MAGIC            0x5c6df104  channel           include/linux/epca.h
 PCXX_MAGIC            0x5c6df104  channel           drivers/char/pcxx.h
 KV_MAGIC              0x5f4b565f  kernel_vars_s     arch/mips/include/asm/sn/klkernvars.h
 I810_STATE_MAGIC      0x63657373  i810_state        sound/oss/i810_audio.c
@@ -142,17 +133,14 @@
 LO_MAGIC              0x68797548  nbd_device        include/linux/nbd.h
 OPROFILE_MAGIC        0x6f70726f  super_block       drivers/oprofile/oprofilefs.h
 M3_STATE_MAGIC        0x734d724d  m3_state          sound/oss/maestro3.c
-STL_PANELMAGIC        0x7ef621a1  stlpanel          include/linux/stallion.h
 VMALLOC_MAGIC         0x87654320  snd_alloc_track   sound/core/memory.c
 KMALLOC_MAGIC         0x87654321  snd_alloc_track   sound/core/memory.c
 PWC_MAGIC             0x89DC10AB  pwc_device        drivers/usb/media/pwc.h
 NBD_REPLY_MAGIC       0x96744668  nbd_reply         include/linux/nbd.h
-STL_BOARDMAGIC        0xa2267f52  stlbrd            include/linux/stallion.h
 ENI155_MAGIC          0xa54b872d  midway_eprom	    drivers/atm/eni.h
 SCI_MAGIC             0xbabeface  gs_port           drivers/char/sh-sci.h
 CODA_MAGIC            0xC0DAC0DA  coda_file_info    include/linux/coda_fs_i.h
 DPMEM_MAGIC           0xc0ffee11  gdt_pci_sram      drivers/scsi/gdth.h
-STLI_PORTMAGIC        0xe671c7a1  stliport          include/linux/istallion.h
 YAM_MAGIC             0xF10A7654  yam_port          drivers/net/hamradio/yam.c
 CCB_MAGIC             0xf2691ad2  ccb               drivers/scsi/ncr53c8xx.c
 QUEUE_MAGIC_FREE      0xf7e1c9a3  queue_entry       drivers/scsi/arm/queue.c
diff --git a/Documentation/zh_CN/stable_kernel_rules.txt b/Documentation/zh_CN/stable_kernel_rules.txt
index b5b9b0a..26ea5ed 100644
--- a/Documentation/zh_CN/stable_kernel_rules.txt
+++ b/Documentation/zh_CN/stable_kernel_rules.txt
@@ -42,7 +42,7 @@
 
 向稳定版代码树提交补丁的过程:
 
-  - 在确认了补丁符合以上的规则后,将补丁发送到stable@kernel.org。
+  - 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。
   - 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
     到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
   - 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
diff --git a/MAINTAINERS b/MAINTAINERS
index 6dc67b1..7bb7ead 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1967,6 +1967,12 @@
 F:	drivers/bcma/
 F:	include/linux/bcma/
 
+BROADCOM SYSTEMPORT ETHERNET DRIVER
+M:	Florian Fainelli <f.fainelli@gmail.com>
+L:	netdev@vger.kernel.org
+S:	Supported
+F:	drivers/net/ethernet/broadcom/bcmsysport.*
+
 BROCADE BFA FC SCSI DRIVER
 M:	Anil Gurumurthy <anil.gurumurthy@qlogic.com>
 M:	Sudarsana Kalluru <sudarsana.kalluru@qlogic.com>
@@ -6782,7 +6788,7 @@
 M:	Peter Zijlstra <a.p.zijlstra@chello.nl>
 M:	Paul Mackerras <paulus@samba.org>
 M:	Ingo Molnar <mingo@redhat.com>
-M:	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+M:	Arnaldo Carvalho de Melo <acme@kernel.org>
 L:	linux-kernel@vger.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
 S:	Supported
@@ -7674,7 +7680,6 @@
 SAMSUNG SXGBE DRIVERS
 M:	Byungho An <bh74.an@samsung.com>
 M:	Girish K S <ks.giri@samsung.com>
-M:	Siva Reddy Kallam <siva.kallam@samsung.com>
 M:	Vipul Pandya <vipul.pandya@samsung.com>
 S:	Supported
 L:	netdev@vger.kernel.org
@@ -8315,7 +8320,7 @@
 
 SPEAR PLATFORM SUPPORT
 M:	Viresh Kumar <viresh.linux@gmail.com>
-M:	Shiraz Hashim <shiraz.hashim@st.com>
+M:	Shiraz Hashim <shiraz.linux.kernel@gmail.com>
 L:	spear-devel@list.st.com
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:	http://www.st.com/spear
diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
deleted file mode 100644
index c32245c..0000000
--- a/arch/arc/include/asm/barrier.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_BARRIER_H
-#define __ASM_BARRIER_H
-
-#ifndef __ASSEMBLY__
-
-/* TODO-vineetg: Need to see what this does, don't we need sync anywhere */
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#define rmb() mb()
-#define wmb() mb()
-#define set_mb(var, value)  do { var = value; mb(); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
-#define read_barrier_depends()  mb()
-
-/* TODO-vineetg verify the correctness of macros here */
-#ifdef CONFIG_SMP
-#define smp_mb()        mb()
-#define smp_rmb()       rmb()
-#define smp_wmb()       wmb()
-#else
-#define smp_mb()        barrier()
-#define smp_rmb()       barrier()
-#define smp_wmb()       barrier()
-#endif
-
-#define smp_read_barrier_depends()      do { } while (0)
-
-#endif
-
-#endif
diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts
index 3075d2d..0aa6fef 100644
--- a/arch/arm/boot/dts/spear320-hmi.dts
+++ b/arch/arm/boot/dts/spear320-hmi.dts
@@ -1,7 +1,7 @@
 /*
  * DTS file for SPEAr320 Evaluation Baord
  *
- * Copyright 2012 Shiraz Hashim <shiraz.hashim@st.com>
+ * Copyright 2012 Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
diff --git a/arch/arm/boot/dts/vt8500.dtsi b/arch/arm/boot/dts/vt8500.dtsi
index 51d0e91..1929ad3 100644
--- a/arch/arm/boot/dts/vt8500.dtsi
+++ b/arch/arm/boot/dts/vt8500.dtsi
@@ -165,5 +165,11 @@
 			reg = <0xd8100000 0x10000>;
 			interrupts = <48>;
 		};
+
+		ethernet@d8004000 {
+			compatible = "via,vt8500-rhine";
+			reg = <0xd8004000 0x100>;
+			interrupts = <10>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi
index 7525982..b1c59a7 100644
--- a/arch/arm/boot/dts/wm8650.dtsi
+++ b/arch/arm/boot/dts/wm8650.dtsi
@@ -218,5 +218,11 @@
 			reg = <0xd8100000 0x10000>;
 			interrupts = <48>;
 		};
+
+		ethernet@d8004000 {
+			compatible = "via,vt8500-rhine";
+			reg = <0xd8004000 0x100>;
+			interrupts = <10>;
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/wm8850.dtsi b/arch/arm/boot/dts/wm8850.dtsi
index d98386d..8fbccfbe 100644
--- a/arch/arm/boot/dts/wm8850.dtsi
+++ b/arch/arm/boot/dts/wm8850.dtsi
@@ -298,5 +298,11 @@
 			bus-width = <4>;
 			sdon-inverted;
 		};
+
+		ethernet@d8004000 {
+			compatible = "via,vt8500-rhine";
+			reg = <0xd8004000 0x100>;
+			interrupts = <10>;
+                };
 	};
 };
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
index 0100464..3df3f3a 100644
--- a/arch/arm/configs/bcm_defconfig
+++ b/arch/arm/configs/bcm_defconfig
@@ -132,7 +132,7 @@
 CONFIG_CRC7=y
 CONFIG_XZ_DEC=y
 CONFIG_AVERAGE=y
-CONFIG_PINCTRL_CAPRI=y
+CONFIG_PINCTRL_BCM281XX=y
 CONFIG_WATCHDOG=y
 CONFIG_BCM_KONA_WDT=y
 CONFIG_BCM_KONA_WDT_DEBUG=y
diff --git a/arch/arm/mach-spear/headsmp.S b/arch/arm/mach-spear/headsmp.S
index ed85473..c52192d 100644
--- a/arch/arm/mach-spear/headsmp.S
+++ b/arch/arm/mach-spear/headsmp.S
@@ -3,7 +3,7 @@
  *
  * Picked from realview
  * Copyright (c) 2012 ST Microelectronics Limited
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c
index 5c4a198..c19751f 100644
--- a/arch/arm/mach-spear/platsmp.c
+++ b/arch/arm/mach-spear/platsmp.c
@@ -4,7 +4,7 @@
  * based upon linux/arch/arm/mach-realview/platsmp.c
  *
  * Copyright (C) 2012 ST Microelectronics Ltd.
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c
index 218ba5b..6479035 100644
--- a/arch/arm/mach-spear/time.c
+++ b/arch/arm/mach-spear/time.c
@@ -2,7 +2,7 @@
  * arch/arm/plat-spear/time.c
  *
  * Copyright (C) 2010 ST Microelectronics
- * Shiraz Hashim<shiraz.hashim@st.com>
+ * Shiraz Hashim<shiraz.linux.kernel@gmail.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index e6f80fc..a4acdda 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -259,7 +259,7 @@
 	 * Switch into virtual mode:
 	 */
 	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
-		  |IA64_PSR_DI|IA64_PSR_AC)
+		  |IA64_PSR_DI)
 	;;
 	mov cr.ipsr=r16
 	movl r17=1f
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index 689ffca..18e794a 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -58,7 +58,7 @@
 #include <asm/unistd.h>
 #include <asm/errno.h>
 
-#if 1
+#if 0
 # define PSR_DEFAULT_BITS	psr.ac
 #else
 # define PSR_DEFAULT_BITS	0
diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S
index 2401848..397e34a 100644
--- a/arch/ia64/kvm/vmm_ivt.S
+++ b/arch/ia64/kvm/vmm_ivt.S
@@ -64,7 +64,7 @@
 #include "kvm_minstate.h"
 #include "vti.h"
 
-#if 1
+#if 0
 # define PSR_DEFAULT_BITS   psr.ac
 #else
 # define PSR_DEFAULT_BITS   0
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index e422b38..9e67cde 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -29,15 +29,15 @@
 void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
 	unsigned long pfn);
 void (*flush_icache_range)(unsigned long start, unsigned long end);
+EXPORT_SYMBOL_GPL(flush_icache_range);
 void (*local_flush_icache_range)(unsigned long start, unsigned long end);
 
 void (*__flush_cache_vmap)(void);
 void (*__flush_cache_vunmap)(void);
 
 void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
-void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
-
 EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
+void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
 
 /* MIPS specific cache operations */
 void (*flush_cache_sigtramp)(unsigned long addr);
diff --git a/arch/parisc/include/asm/shmparam.h b/arch/parisc/include/asm/shmparam.h
index 628ddc2..afe1300 100644
--- a/arch/parisc/include/asm/shmparam.h
+++ b/arch/parisc/include/asm/shmparam.h
@@ -1,8 +1,7 @@
 #ifndef _ASMPARISC_SHMPARAM_H
 #define _ASMPARISC_SHMPARAM_H
 
-#define __ARCH_FORCE_SHMLBA 	1
-
-#define SHMLBA 0x00400000   /* attach addr needs to be 4 Mb aligned */
+#define SHMLBA	   PAGE_SIZE	/* attach addr a multiple of this */
+#define SHM_COLOUR 0x00400000	/* shared mappings colouring */
 
 #endif /* _ASMPARISC_SHMPARAM_H */
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index a6ffc77..f6448c7 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -323,7 +323,8 @@
 		 * specifically accesses it, of course) */
 
 		flush_tlb_page(mpnt, addr);
-		if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
+		if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
+				      != (addr & (SHM_COLOUR - 1))) {
 			__flush_cache_page(mpnt, addr, page_to_phys(page));
 			if (old_addr)
 				printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index b7cadc4..31ffa9b 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -45,7 +45,7 @@
 
 static int get_offset(unsigned int last_mmap)
 {
-	return (last_mmap & (SHMLBA-1)) >> PAGE_SHIFT;
+	return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT;
 }
 
 static unsigned long shared_align_offset(unsigned int last_mmap,
@@ -57,8 +57,8 @@
 static inline unsigned long COLOR_ALIGN(unsigned long addr,
 			 unsigned int last_mmap, unsigned long pgoff)
 {
-	unsigned long base = (addr+SHMLBA-1) & ~(SHMLBA-1);
-	unsigned long off  = (SHMLBA-1) &
+	unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1);
+	unsigned long off  = (SHM_COLOUR-1) &
 		(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
 
 	return base + off;
@@ -101,7 +101,7 @@
 	if (flags & MAP_FIXED) {
 		if ((flags & MAP_SHARED) && last_mmap &&
 		    (addr - shared_align_offset(last_mmap, pgoff))
-				& (SHMLBA - 1))
+				& (SHM_COLOUR - 1))
 			return -EINVAL;
 		goto found_addr;
 	}
@@ -122,7 +122,7 @@
 	info.length = len;
 	info.low_limit = mm->mmap_legacy_base;
 	info.high_limit = mmap_upper_limit();
-	info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+	info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
 	info.align_offset = shared_align_offset(last_mmap, pgoff);
 	addr = vm_unmapped_area(&info);
 
@@ -161,7 +161,7 @@
 	if (flags & MAP_FIXED) {
 		if ((flags & MAP_SHARED) && last_mmap &&
 		    (addr - shared_align_offset(last_mmap, pgoff))
-			& (SHMLBA - 1))
+			& (SHM_COLOUR - 1))
 			return -EINVAL;
 		goto found_addr;
 	}
@@ -182,7 +182,7 @@
 	info.length = len;
 	info.low_limit = PAGE_SIZE;
 	info.high_limit = mm->mmap_base;
-	info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+	info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
 	info.align_offset = shared_align_offset(last_mmap, pgoff);
 	addr = vm_unmapped_area(&info);
 	if (!(addr & ~PAGE_MASK))
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 80e5dd2..83ead0e 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -392,7 +392,7 @@
 	ENTRY_COMP(vmsplice)
 	ENTRY_COMP(move_pages)		/* 295 */
 	ENTRY_SAME(getcpu)
-	ENTRY_SAME(epoll_pwait)
+	ENTRY_COMP(epoll_pwait)
 	ENTRY_COMP(statfs64)
 	ENTRY_COMP(fstatfs64)
 	ENTRY_COMP(kexec_load)		/* 300 */
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index 413dc17..b2b441b 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -470,7 +470,7 @@
 		return 0;
 
 	/* if a load or store fault occured we can get the faulty addr */
-	d = &__get_cpu_var(exception_data);
+	d = this_cpu_ptr(&exception_data);
 	fault_addr = d->fault_addr;
 
 	/* error in load or store? */
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 9d08c71..7475507 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -151,7 +151,7 @@
 	fix = search_exception_tables(regs->iaoq[0]);
 	if (fix) {
 		struct exception_data *d;
-		d = &__get_cpu_var(exception_data);
+		d = this_cpu_ptr(&exception_data);
 		d->fault_ip = regs->iaoq[0];
 		d->fault_space = regs->isr;
 		d->fault_addr = regs->ior;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 2a47790..155013d 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -208,7 +208,7 @@
 			  unsigned long in_devfn)
 {
 	struct pci_controller* hose;
-	struct pci_bus *bus = NULL;
+	struct pci_bus *tmp_bus, *bus = NULL;
 	struct device_node *hose_node;
 
 	/* Argh ! Please forgive me for that hack, but that's the
@@ -229,10 +229,12 @@
 	 * used on pre-domains setup. We return the first match
 	 */
 
-	list_for_each_entry(bus, &pci_root_buses, node) {
-		if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
+	list_for_each_entry(tmp_bus, &pci_root_buses, node) {
+		if (in_bus >= tmp_bus->number &&
+		    in_bus <= tmp_bus->busn_res.end) {
+			bus = tmp_bus;
 			break;
-		bus = NULL;
+		}
 	}
 	if (bus == NULL || bus->dev.of_node == NULL)
 		return -ENODEV;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 4ebbb9e..3b181b2 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -232,6 +232,7 @@
 
 	return distance;
 }
+EXPORT_SYMBOL(__node_distance);
 
 static void initialize_distance_lookup_table(int nid,
 		const __be32 *associativity)
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index d091aa1..bf9c823 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -31,4 +31,23 @@
 #define SIGP_STATUS_INCORRECT_STATE	0x00000200UL
 #define SIGP_STATUS_NOT_RUNNING		0x00000400UL
 
+#ifndef __ASSEMBLY__
+
+static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
+{
+	register unsigned int reg1 asm ("1") = parm;
+	int cc;
+
+	asm volatile(
+		"	sigp	%1,%2,0(%3)\n"
+		"	ipm	%0\n"
+		"	srl	%0,28\n"
+		: "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
+	if (status && cc == 1)
+		*status = reg1;
+	return cc;
+}
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* __S390_ASM_SIGP_H */
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 1607793..21703f8 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -7,6 +7,8 @@
 #ifndef __ASM_SMP_H
 #define __ASM_SMP_H
 
+#include <asm/sigp.h>
+
 #ifdef CONFIG_SMP
 
 #include <asm/lowcore.h>
@@ -50,9 +52,18 @@
 static inline int smp_vcpu_scheduled(int cpu) { return 1; }
 static inline void smp_yield_cpu(int cpu) { }
 static inline void smp_yield(void) { }
-static inline void smp_stop_cpu(void) { }
 static inline void smp_fill_possible_mask(void) { }
 
+static inline void smp_stop_cpu(void)
+{
+	u16 pcpu = stap();
+
+	for (;;) {
+		__pcpu_sigp(pcpu, SIGP_STOP, 0, NULL);
+		cpu_relax();
+	}
+}
+
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h
index 5eb5c9d..3802d2d 100644
--- a/arch/s390/include/uapi/asm/unistd.h
+++ b/arch/s390/include/uapi/asm/unistd.h
@@ -282,7 +282,8 @@
 #define __NR_finit_module	344
 #define __NR_sched_setattr	345
 #define __NR_sched_getattr	346
-#define NR_syscalls 345
+#define __NR_renameat2		347
+#define NR_syscalls 348
 
 /* 
  * There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c
index 824c39d..45cdb37 100644
--- a/arch/s390/kernel/compat_wrapper.c
+++ b/arch/s390/kernel/compat_wrapper.c
@@ -1,5 +1,5 @@
 /*
- *  Compat sytem call wrappers.
+ *  Compat system call wrappers.
  *
  *    Copyright IBM Corp. 2014
  */
@@ -213,3 +213,4 @@
 COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags);
 COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags);
 COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags);
+COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags);
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
index e6af940..acb4124 100644
--- a/arch/s390/kernel/dumpstack.c
+++ b/arch/s390/kernel/dumpstack.c
@@ -144,10 +144,10 @@
 	char *mode;
 
 	mode = user_mode(regs) ? "User" : "Krnl";
-	printk("%s PSW : %p %p (%pSR)\n",
-	       mode, (void *) regs->psw.mask,
-	       (void *) regs->psw.addr,
-	       (void *) regs->psw.addr);
+	printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
+	if (!user_mode(regs))
+		printk(" (%pSR)", (void *)regs->psw.addr);
+	printk("\n");
 	printk("           R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
 	       "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER),
 	       mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO),
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 4ac8faf..1c82619 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -64,7 +64,7 @@
 		if (task->thread.per_flags & PER_FLAG_NO_TE)
 			cr_new &= ~(1UL << 55);
 		if (cr_new != cr)
-			__ctl_load(cr, 0, 0);
+			__ctl_load(cr_new, 0, 0);
 		/* Set or clear transaction execution TDC bits 62 and 63. */
 		__ctl_store(cr, 2, 2);
 		cr_new = cr & ~3UL;
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f70f248..88d1ca8 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -1027,3 +1027,35 @@
 	/* Setup zfcpdump support */
 	setup_zfcpdump();
 }
+
+#ifdef CONFIG_32BIT
+static int no_removal_warning __initdata;
+
+static int __init parse_no_removal_warning(char *str)
+{
+	no_removal_warning = 1;
+	return 0;
+}
+__setup("no_removal_warning", parse_no_removal_warning);
+
+static int __init removal_warning(void)
+{
+	if (no_removal_warning)
+		return 0;
+	printk(KERN_ALERT "\n\n");
+	printk(KERN_CONT "Warning - you are using a 31 bit kernel!\n\n");
+	printk(KERN_CONT "We plan to remove 31 bit kernel support from the kernel sources in March 2015.\n");
+	printk(KERN_CONT "Currently we assume that nobody is using the 31 bit kernel on old 31 bit\n");
+	printk(KERN_CONT "hardware anymore. If you think that the code should not be removed and also\n");
+	printk(KERN_CONT "future versions of the Linux kernel should be able to run in 31 bit mode\n");
+	printk(KERN_CONT "please let us know. Please write to:\n");
+	printk(KERN_CONT "linux390@de.ibm.com (mail address) and/or\n");
+	printk(KERN_CONT "linux-s390@vger.kernel.org (mailing list).\n\n");
+	printk(KERN_CONT "Thank you!\n\n");
+	printk(KERN_CONT "If this kernel runs on a 64 bit machine you may consider using a 64 bit kernel.\n");
+	printk(KERN_CONT "This message can be disabled with the \"no_removal_warning\" kernel parameter.\n");
+	schedule_timeout_uninterruptible(300 * HZ);
+	return 0;
+}
+early_initcall(removal_warning);
+#endif
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 512ce1c..86e65ec 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -82,21 +82,6 @@
 /*
  * Signal processor helper functions.
  */
-static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
-{
-	register unsigned int reg1 asm ("1") = parm;
-	int cc;
-
-	asm volatile(
-		"	sigp	%1,%2,0(%3)\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
-	if (status && cc == 1)
-		*status = reg1;
-	return cc;
-}
-
 static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
 {
 	int cc;
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 542ef48..fe5cdf2 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -355,3 +355,4 @@
 SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module)
 SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */
 SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr)
+SYSCALL(sys_renameat2,sys_renameat2,compat_sys_renameat2)
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
index 23f866b..7416efe 100644
--- a/arch/s390/lib/uaccess.c
+++ b/arch/s390/lib/uaccess.c
@@ -338,9 +338,6 @@
 	register unsigned long reg0 asm("0") = 0;
 	unsigned long tmp1, tmp2;
 
-	if (unlikely(!size))
-		return 0;
-	update_primary_asce(current);
 	asm volatile(
 		"   la    %2,0(%1)\n"
 		"   la    %3,0(%0,%1)\n"
@@ -359,6 +356,8 @@
 
 unsigned long __strnlen_user(const char __user *src, unsigned long size)
 {
+	if (unlikely(!size))
+		return 0;
 	update_primary_asce(current);
 	return strnlen_user_srst(src, size);
 }
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 19f623f..2f51a99 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -126,6 +126,133 @@
 	return 0;
 }
 
+static int bad_address(void *p)
+{
+	unsigned long dummy;
+
+	return probe_kernel_address((unsigned long *)p, dummy);
+}
+
+#ifdef CONFIG_64BIT
+static void dump_pagetable(unsigned long asce, unsigned long address)
+{
+	unsigned long *table = __va(asce & PAGE_MASK);
+
+	pr_alert("AS:%016lx ", asce);
+	switch (asce & _ASCE_TYPE_MASK) {
+	case _ASCE_TYPE_REGION1:
+		table = table + ((address >> 53) & 0x7ff);
+		if (bad_address(table))
+			goto bad;
+		pr_cont("R1:%016lx ", *table);
+		if (*table & _REGION_ENTRY_INVALID)
+			goto out;
+		table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+		/* fallthrough */
+	case _ASCE_TYPE_REGION2:
+		table = table + ((address >> 42) & 0x7ff);
+		if (bad_address(table))
+			goto bad;
+		pr_cont("R2:%016lx ", *table);
+		if (*table & _REGION_ENTRY_INVALID)
+			goto out;
+		table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+		/* fallthrough */
+	case _ASCE_TYPE_REGION3:
+		table = table + ((address >> 31) & 0x7ff);
+		if (bad_address(table))
+			goto bad;
+		pr_cont("R3:%016lx ", *table);
+		if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE))
+			goto out;
+		table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+		/* fallthrough */
+	case _ASCE_TYPE_SEGMENT:
+		table = table + ((address >> 20) & 0x7ff);
+		if (bad_address(table))
+			goto bad;
+		pr_cont(KERN_CONT "S:%016lx ", *table);
+		if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE))
+			goto out;
+		table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+	}
+	table = table + ((address >> 12) & 0xff);
+	if (bad_address(table))
+		goto bad;
+	pr_cont("P:%016lx ", *table);
+out:
+	pr_cont("\n");
+	return;
+bad:
+	pr_cont("BAD\n");
+}
+
+#else /* CONFIG_64BIT */
+
+static void dump_pagetable(unsigned long asce, unsigned long address)
+{
+	unsigned long *table = __va(asce & PAGE_MASK);
+
+	pr_alert("AS:%08lx ", asce);
+	table = table + ((address >> 20) & 0x7ff);
+	if (bad_address(table))
+		goto bad;
+	pr_cont("S:%08lx ", *table);
+	if (*table & _SEGMENT_ENTRY_INVALID)
+		goto out;
+	table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+	table = table + ((address >> 12) & 0xff);
+	if (bad_address(table))
+		goto bad;
+	pr_cont("P:%08lx ", *table);
+out:
+	pr_cont("\n");
+	return;
+bad:
+	pr_cont("BAD\n");
+}
+
+#endif /* CONFIG_64BIT */
+
+static void dump_fault_info(struct pt_regs *regs)
+{
+	unsigned long asce;
+
+	pr_alert("Fault in ");
+	switch (regs->int_parm_long & 3) {
+	case 3:
+		pr_cont("home space ");
+		break;
+	case 2:
+		pr_cont("secondary space ");
+		break;
+	case 1:
+		pr_cont("access register ");
+		break;
+	case 0:
+		pr_cont("primary space ");
+		break;
+	}
+	pr_cont("mode while using ");
+	if (!user_space_fault(regs)) {
+		asce = S390_lowcore.kernel_asce;
+		pr_cont("kernel ");
+	}
+#ifdef CONFIG_PGSTE
+	else if ((current->flags & PF_VCPU) && S390_lowcore.gmap) {
+		struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
+		asce = gmap->asce;
+		pr_cont("gmap ");
+	}
+#endif
+	else {
+		asce = S390_lowcore.user_asce;
+		pr_cont("user ");
+	}
+	pr_cont("ASCE.\n");
+	dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK);
+}
+
 static inline void report_user_fault(struct pt_regs *regs, long signr)
 {
 	if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
@@ -138,8 +265,9 @@
 	       regs->int_code);
 	print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
 	printk(KERN_CONT "\n");
-	printk(KERN_ALERT "failing address: %lX\n",
-	       regs->int_parm_long & __FAIL_ADDR_MASK);
+	printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
+	       regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
+	dump_fault_info(regs);
 	show_regs(regs);
 }
 
@@ -177,11 +305,13 @@
 	address = regs->int_parm_long & __FAIL_ADDR_MASK;
 	if (!user_space_fault(regs))
 		printk(KERN_ALERT "Unable to handle kernel pointer dereference"
-		       " at virtual kernel address %p\n", (void *)address);
+		       " in virtual kernel address space\n");
 	else
 		printk(KERN_ALERT "Unable to handle kernel paging request"
-		       " at virtual user address %p\n", (void *)address);
-
+		       " in virtual user address space\n");
+	printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
+	       regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
+	dump_fault_info(regs);
 	die(regs, "Oops");
 	do_exit(SIGKILL);
 }
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 602f57e..d1b7c37 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -250,8 +250,8 @@
 PHONY += kvmconfig
 kvmconfig:
 	$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target))
-	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config arch/x86/configs/kvm_guest.config
-	$(Q)yes "" | $(MAKE) oldconfig
+	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config
+	$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
 
 define archhelp
   echo  '* bzImage      - Compressed kernel image (arch/x86/boot/bzImage)'
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index eeee23f..68317c8 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -598,7 +598,6 @@
 {
 	struct mce m;
 	int i;
-	unsigned long *v;
 
 	this_cpu_inc(mce_poll_count);
 
@@ -618,8 +617,7 @@
 		if (!(m.status & MCI_STATUS_VAL))
 			continue;
 
-		v = &get_cpu_var(mce_polled_error);
-		set_bit(0, v);
+		this_cpu_write(mce_polled_error, 1);
 		/*
 		 * Uncorrected or signalled events are handled by the exception
 		 * handler when it is enabled, so don't process those here.
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
index 3bdb95a..9a316b2 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -42,7 +42,7 @@
  * cmci_discover_lock protects against parallel discovery attempts
  * which could race against each other.
  */
-static DEFINE_RAW_SPINLOCK(cmci_discover_lock);
+static DEFINE_SPINLOCK(cmci_discover_lock);
 
 #define CMCI_THRESHOLD		1
 #define CMCI_POLL_INTERVAL	(30 * HZ)
@@ -144,14 +144,14 @@
 	int bank;
 	u64 val;
 
-	raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+	spin_lock_irqsave(&cmci_discover_lock, flags);
 	owned = __get_cpu_var(mce_banks_owned);
 	for_each_set_bit(bank, owned, MAX_NR_BANKS) {
 		rdmsrl(MSR_IA32_MCx_CTL2(bank), val);
 		val &= ~MCI_CTL2_CMCI_EN;
 		wrmsrl(MSR_IA32_MCx_CTL2(bank), val);
 	}
-	raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+	spin_unlock_irqrestore(&cmci_discover_lock, flags);
 }
 
 static bool cmci_storm_detect(void)
@@ -211,7 +211,7 @@
 	int i;
 	int bios_wrong_thresh = 0;
 
-	raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+	spin_lock_irqsave(&cmci_discover_lock, flags);
 	for (i = 0; i < banks; i++) {
 		u64 val;
 		int bios_zero_thresh = 0;
@@ -266,7 +266,7 @@
 			WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
 		}
 	}
-	raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+	spin_unlock_irqrestore(&cmci_discover_lock, flags);
 	if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) {
 		pr_info_once(
 			"bios_cmci_threshold: Some banks do not have valid thresholds set\n");
@@ -316,10 +316,10 @@
 
 	if (!cmci_supported(&banks))
 		return;
-	raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+	spin_lock_irqsave(&cmci_discover_lock, flags);
 	for (i = 0; i < banks; i++)
 		__cmci_disable_bank(i);
-	raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+	spin_unlock_irqrestore(&cmci_discover_lock, flags);
 }
 
 static void cmci_rediscover_work_func(void *arg)
@@ -360,9 +360,9 @@
 	if (!cmci_supported(&banks))
 		return;
 
-	raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+	spin_lock_irqsave(&cmci_discover_lock, flags);
 	__cmci_disable_bank(bank);
-	raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+	spin_unlock_irqrestore(&cmci_discover_lock, flags);
 }
 
 static void intel_init_cmci(void)
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c
index 059218e..7c87424 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c
@@ -59,7 +59,7 @@
 #define INTEL_RAPL_PKG		0x2	/* pseudo-encoding */
 #define RAPL_IDX_RAM_NRG_STAT	2	/* DRAM */
 #define INTEL_RAPL_RAM		0x3	/* pseudo-encoding */
-#define RAPL_IDX_PP1_NRG_STAT	3	/* DRAM */
+#define RAPL_IDX_PP1_NRG_STAT	3	/* gpu */
 #define INTEL_RAPL_PP1		0x4	/* pseudo-encoding */
 
 /* Clients have PP0, PKG */
@@ -72,6 +72,12 @@
 			 1<<RAPL_IDX_PKG_NRG_STAT|\
 			 1<<RAPL_IDX_RAM_NRG_STAT)
 
+/* Servers have PP0, PKG, RAM, PP1 */
+#define RAPL_IDX_HSW	(1<<RAPL_IDX_PP0_NRG_STAT|\
+			 1<<RAPL_IDX_PKG_NRG_STAT|\
+			 1<<RAPL_IDX_RAM_NRG_STAT|\
+			 1<<RAPL_IDX_PP1_NRG_STAT)
+
 /*
  * event code: LSB 8 bits, passed in attr->config
  * any other bit is reserved
@@ -425,6 +431,24 @@
 	NULL,
 };
 
+static struct attribute *rapl_events_hsw_attr[] = {
+	EVENT_PTR(rapl_cores),
+	EVENT_PTR(rapl_pkg),
+	EVENT_PTR(rapl_gpu),
+	EVENT_PTR(rapl_ram),
+
+	EVENT_PTR(rapl_cores_unit),
+	EVENT_PTR(rapl_pkg_unit),
+	EVENT_PTR(rapl_gpu_unit),
+	EVENT_PTR(rapl_ram_unit),
+
+	EVENT_PTR(rapl_cores_scale),
+	EVENT_PTR(rapl_pkg_scale),
+	EVENT_PTR(rapl_gpu_scale),
+	EVENT_PTR(rapl_ram_scale),
+	NULL,
+};
+
 static struct attribute_group rapl_pmu_events_group = {
 	.name = "events",
 	.attrs = NULL, /* patched at runtime */
@@ -511,6 +535,7 @@
 	struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
 	int phys_id = topology_physical_package_id(cpu);
 	u64 ms;
+	u64 msr_rapl_power_unit_bits;
 
 	if (pmu)
 		return 0;
@@ -518,6 +543,9 @@
 	if (phys_id < 0)
 		return -1;
 
+	if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
+		return -1;
+
 	pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
 	if (!pmu)
 		return -1;
@@ -531,8 +559,7 @@
 	 *
 	 * we cache in local PMU instance
 	 */
-	rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit);
-	pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL;
+	pmu->hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
 	pmu->pmu = &rapl_pmu_class;
 
 	/*
@@ -631,11 +658,14 @@
 	switch (boot_cpu_data.x86_model) {
 	case 42: /* Sandy Bridge */
 	case 58: /* Ivy Bridge */
-	case 60: /* Haswell */
-	case 69: /* Haswell-Celeron */
 		rapl_cntr_mask = RAPL_IDX_CLN;
 		rapl_pmu_events_group.attrs = rapl_events_cln_attr;
 		break;
+	case 60: /* Haswell */
+	case 69: /* Haswell-Celeron */
+		rapl_cntr_mask = RAPL_IDX_HSW;
+		rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
+		break;
 	case 45: /* Sandy Bridge-EP */
 	case 62: /* IvyTown */
 		rapl_cntr_mask = RAPL_IDX_SRV;
@@ -650,7 +680,9 @@
 	cpu_notifier_register_begin();
 
 	for_each_online_cpu(cpu) {
-		rapl_cpu_prepare(cpu);
+		ret = rapl_cpu_prepare(cpu);
+		if (ret)
+			goto out;
 		rapl_cpu_init(cpu);
 	}
 
@@ -673,6 +705,7 @@
 		hweight32(rapl_cntr_mask),
 		ktime_to_ms(pmu->timer_interval));
 
+out:
 	cpu_notifier_register_done();
 
 	return 0;
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index b0cc380..6e2537c 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -240,7 +240,7 @@
 	return base;
 }
 
-#define KB(x)	((x) * 1024)
+#define KB(x)	((x) * 1024UL)
 #define MB(x)	(KB (KB (x)))
 #define GB(x)	(MB (KB (x)))
 
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 79a3f96..61b17dc 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -897,9 +897,10 @@
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	switch (kcb->kprobe_status) {
-	case KPROBE_HIT_SS:
-	case KPROBE_REENTER:
+	if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) {
+		/* This must happen on single-stepping */
+		WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS &&
+			kcb->kprobe_status != KPROBE_REENTER);
 		/*
 		 * We are here because the instruction being single
 		 * stepped caused a page fault. We reset the current
@@ -914,9 +915,8 @@
 		else
 			reset_current_kprobe();
 		preempt_enable_no_resched();
-		break;
-	case KPROBE_HIT_ACTIVE:
-	case KPROBE_HIT_SSDONE:
+	} else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
+		   kcb->kprobe_status == KPROBE_HIT_SSDONE) {
 		/*
 		 * We increment the nmissed count for accounting,
 		 * we can also use npre/npostfault count for accounting
@@ -945,10 +945,8 @@
 		 * fixup routine could not handle it,
 		 * Let do_page_fault() fix it.
 		 */
-		break;
-	default:
-		break;
 	}
+
 	return 0;
 }
 
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 654b465..3399d3a 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -114,8 +114,8 @@
  */
 static int __init set_pci_reboot(const struct dmi_system_id *d)
 {
-	if (reboot_type != BOOT_CF9) {
-		reboot_type = BOOT_CF9;
+	if (reboot_type != BOOT_CF9_FORCE) {
+		reboot_type = BOOT_CF9_FORCE;
 		pr_info("%s series board detected. Selecting %s-method for reboots.\n",
 			d->ident, "PCI");
 	}
@@ -458,20 +458,23 @@
 }
 
 /*
- * Windows compatible x86 hardware expects the following on reboot:
+ * To the best of our knowledge Windows compatible x86 hardware expects
+ * the following on reboot:
  *
  * 1) If the FADT has the ACPI reboot register flag set, try it
  * 2) If still alive, write to the keyboard controller
  * 3) If still alive, write to the ACPI reboot register again
  * 4) If still alive, write to the keyboard controller again
  * 5) If still alive, call the EFI runtime service to reboot
- * 6) If still alive, write to the PCI IO port 0xCF9 to reboot
- * 7) If still alive, inform BIOS to do a proper reboot
+ * 6) If no EFI runtime service, call the BIOS to do a reboot
  *
- * If the machine is still alive at this stage, it gives up. We default to
- * following the same pattern, except that if we're still alive after (7) we'll
- * try to force a triple fault and then cycle between hitting the keyboard
- * controller and doing that
+ * We default to following the same pattern. We also have
+ * two other reboot methods: 'triple fault' and 'PCI', which
+ * can be triggered via the reboot= kernel boot option or
+ * via quirks.
+ *
+ * This means that this function can never return, it can misbehave
+ * by not rebooting properly and hanging.
  */
 static void native_machine_emergency_restart(void)
 {
@@ -492,6 +495,11 @@
 	for (;;) {
 		/* Could also try the reset bit in the Hammer NB */
 		switch (reboot_type) {
+		case BOOT_ACPI:
+			acpi_reboot();
+			reboot_type = BOOT_KBD;
+			break;
+
 		case BOOT_KBD:
 			mach_reboot_fixups(); /* For board specific fixups */
 
@@ -509,43 +517,29 @@
 			}
 			break;
 
-		case BOOT_TRIPLE:
-			load_idt(&no_idt);
-			__asm__ __volatile__("int3");
-
-			/* We're probably dead after this, but... */
-			reboot_type = BOOT_KBD;
-			break;
-
-		case BOOT_BIOS:
-			machine_real_restart(MRR_BIOS);
-
-			/* We're probably dead after this, but... */
-			reboot_type = BOOT_TRIPLE;
-			break;
-
-		case BOOT_ACPI:
-			acpi_reboot();
-			reboot_type = BOOT_KBD;
-			break;
-
 		case BOOT_EFI:
 			if (efi_enabled(EFI_RUNTIME_SERVICES))
 				efi.reset_system(reboot_mode == REBOOT_WARM ?
 						 EFI_RESET_WARM :
 						 EFI_RESET_COLD,
 						 EFI_SUCCESS, 0, NULL);
-			reboot_type = BOOT_CF9_COND;
+			reboot_type = BOOT_BIOS;
 			break;
 
-		case BOOT_CF9:
+		case BOOT_BIOS:
+			machine_real_restart(MRR_BIOS);
+
+			/* We're probably dead after this, but... */
+			reboot_type = BOOT_CF9_SAFE;
+			break;
+
+		case BOOT_CF9_FORCE:
 			port_cf9_safe = true;
 			/* Fall through */
 
-		case BOOT_CF9_COND:
+		case BOOT_CF9_SAFE:
 			if (port_cf9_safe) {
-				u8 reboot_code = reboot_mode == REBOOT_WARM ?
-					0x06 : 0x0E;
+				u8 reboot_code = reboot_mode == REBOOT_WARM ?  0x06 : 0x0E;
 				u8 cf9 = inb(0xcf9) & ~reboot_code;
 				outb(cf9|2, 0xcf9); /* Request hard reset */
 				udelay(50);
@@ -553,7 +547,15 @@
 				outb(cf9|reboot_code, 0xcf9);
 				udelay(50);
 			}
-			reboot_type = BOOT_BIOS;
+			reboot_type = BOOT_TRIPLE;
+			break;
+
+		case BOOT_TRIPLE:
+			load_idt(&no_idt);
+			__asm__ __volatile__("int3");
+
+			/* We're probably dead after this, but... */
+			reboot_type = BOOT_KBD;
 			break;
 		}
 	}
diff --git a/arch/x86/syscalls/Makefile b/arch/x86/syscalls/Makefile
index f325af2..3323c27 100644
--- a/arch/x86/syscalls/Makefile
+++ b/arch/x86/syscalls/Makefile
@@ -54,5 +54,7 @@
 
 targets	+= $(uapisyshdr-y) $(syshdr-y)
 
+PHONY += all
 all: $(addprefix $(uapi)/,$(uapisyshdr-y))
 all: $(addprefix $(out)/,$(syshdr-y))
+	@:
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 96bc506..d6b8679 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -359,3 +359,4 @@
 350	i386	finit_module		sys_finit_module
 351	i386	sched_setattr		sys_sched_setattr
 352	i386	sched_getattr		sys_sched_getattr
+353	i386	renameat2		sys_renameat2
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile
index e812034..604a37e 100644
--- a/arch/x86/tools/Makefile
+++ b/arch/x86/tools/Makefile
@@ -40,4 +40,6 @@
 HOST_EXTRACFLAGS += -I$(srctree)/tools/include
 hostprogs-y	+= relocs
 relocs-objs     := relocs_32.o relocs_64.o relocs_common.o
+PHONY += relocs
 relocs: $(obj)/relocs
+	@:
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index a18eadd..7005974 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -441,10 +441,11 @@
 	irq_ctx_init(cpu);
 #else
 	clear_tsk_thread_flag(idle, TIF_FORK);
+#endif
 	per_cpu(kernel_stack, cpu) =
 		(unsigned long)task_stack_page(idle) -
 		KERNEL_STACK_OFFSET + THREAD_SIZE;
-#endif
+
 	xen_setup_runstate_info(cpu);
 	xen_setup_timer(cpu);
 	xen_init_lock_cpu(cpu);
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 4d3acc3..0ba5f3b 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -274,7 +274,7 @@
 		printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
 		return;
 	}
-
+	printk(KERN_DEBUG "xen: PV spinlocks enabled\n");
 	pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning);
 	pv_lock_ops.unlock_kick = xen_unlock_kick;
 }
@@ -290,6 +290,9 @@
 	if (!xen_pvspin)
 		return 0;
 
+	if (!xen_domain())
+		return 0;
+
 	static_key_slow_inc(&paravirt_ticketlocks_enabled);
 	return 0;
 }
diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S
index 33ca6e4..fd92a64 100644
--- a/arch/x86/xen/xen-asm_32.S
+++ b/arch/x86/xen/xen-asm_32.S
@@ -75,6 +75,17 @@
  * stack state in whatever form its in, we keep things simple by only
  * using a single register which is pushed/popped on the stack.
  */
+
+.macro POP_FS
+1:
+	popw %fs
+.pushsection .fixup, "ax"
+2:	movw $0, (%esp)
+	jmp 1b
+.popsection
+	_ASM_EXTABLE(1b,2b)
+.endm
+
 ENTRY(xen_iret)
 	/* test eflags for special cases */
 	testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp)
@@ -83,15 +94,13 @@
 	push %eax
 	ESP_OFFSET=4	# bytes pushed onto stack
 
-	/*
-	 * Store vcpu_info pointer for easy access.  Do it this way to
-	 * avoid having to reload %fs
-	 */
+	/* Store vcpu_info pointer for easy access */
 #ifdef CONFIG_SMP
-	GET_THREAD_INFO(%eax)
-	movl %ss:TI_cpu(%eax), %eax
-	movl %ss:__per_cpu_offset(,%eax,4), %eax
-	mov %ss:xen_vcpu(%eax), %eax
+	pushw %fs
+	movl $(__KERNEL_PERCPU), %eax
+	movl %eax, %fs
+	movl %fs:xen_vcpu, %eax
+	POP_FS
 #else
 	movl %ss:xen_vcpu, %eax
 #endif
diff --git a/drivers/Makefile b/drivers/Makefile
index e3ced91..d05d81b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -53,8 +53,8 @@
 obj-$(CONFIG_CONNECTOR)		+= connector/
 
 # i810fb and intelfb depend on char/agp/
-obj-$(CONFIG_FB_I810)           += video/i810/
-obj-$(CONFIG_FB_INTEL)          += video/intelfb/
+obj-$(CONFIG_FB_I810)           += video/fbdev/i810/
+obj-$(CONFIG_FB_INTEL)          += video/fbdev/intelfb/
 
 obj-$(CONFIG_PARPORT)		+= parport/
 obj-y				+= base/ block/ misc/ mfd/ nfc/
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0dd6528..20da3ad 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -614,39 +614,6 @@
 }
 EXPORT_SYMBOL_GPL(device_remove_bin_file);
 
-/**
- * device_schedule_callback_owner - helper to schedule a callback for a device
- * @dev: device.
- * @func: callback function to invoke later.
- * @owner: module owning the callback routine
- *
- * Attribute methods must not unregister themselves or their parent device
- * (which would amount to the same thing).  Attempts to do so will deadlock,
- * since unregistration is mutually exclusive with driver callbacks.
- *
- * Instead methods can call this routine, which will attempt to allocate
- * and schedule a workqueue request to call back @func with @dev as its
- * argument in the workqueue's process context.  @dev will be pinned until
- * @func returns.
- *
- * This routine is usually called via the inline device_schedule_callback(),
- * which automatically sets @owner to THIS_MODULE.
- *
- * Returns 0 if the request was submitted, -ENOMEM if storage could not
- * be allocated, -ENODEV if a reference to @owner isn't available.
- *
- * NOTE: This routine won't work if CONFIG_SYSFS isn't set!  It uses an
- * underlying sysfs routine (since it is intended for use by attribute
- * methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
- */
-int device_schedule_callback_owner(struct device *dev,
-		void (*func)(struct device *), struct module *owner)
-{
-	return sysfs_schedule_callback(&dev->kobj,
-			(void (*)(void *)) func, dev, owner);
-}
-EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
-
 static void klist_children_get(struct klist_node *n)
 {
 	struct device_private *p = to_device_private_parent(n);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..8986b9f 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -187,8 +187,8 @@
 		return;
 	}
 
-	pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
-		 __func__, dev->driver->name);
+	pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name,
+		 __func__, dev_name(dev));
 
 	klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
 
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index bbcbd3c..be7c1fb 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -39,8 +39,7 @@
 static ssize_t show_##name(struct device *dev,			\
 		struct device_attribute *attr, char *buf)	\
 {								\
-	unsigned int cpu = dev->id;				\
-	return sprintf(buf, "%d\n", topology_##name(cpu));	\
+	return sprintf(buf, "%d\n", topology_##name(dev->id));	\
 }
 
 #if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index fbae63e..6e9f74a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -40,7 +40,7 @@
 source "drivers/tty/serial/Kconfig"
 
 config TTY_PRINTK
-	bool "TTY driver to output user messages via printk"
+	tristate "TTY driver to output user messages via printk"
 	depends on EXPERT && TTY
 	default n
 	---help---
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 0baa8fa..db1c9b7 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -50,6 +50,18 @@
 	 Currently, only KCS and SMIC are supported.  If
 	 you are using IPMI, you should probably say "y" here.
 
+config IPMI_SI_PROBE_DEFAULTS
+       bool 'Probe for all possible IPMI system interfaces by default'
+       default n
+       depends on IPMI_SI
+       help
+	 Modern systems will usually expose IPMI interfaces via a discoverable
+	 firmware mechanism such as ACPI or DMI. Older systems do not, and so
+	 the driver is forced to probe hardware manually. This may cause boot
+	 delays. Say "n" here to disable this manual probing. IPMI will then
+	 only be available on older systems if the "ipmi_si_intf.trydefaults=1"
+	 boot argument is passed.
+
 config IPMI_WATCHDOG
        tristate 'IPMI Watchdog Timer'
        help
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index f5e4cd7..61e7161 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -352,7 +352,7 @@
 
 static inline int read_all_bytes(struct si_sm_data *bt)
 {
-	unsigned char i;
+	unsigned int i;
 
 	/*
 	 * length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index 6a4bdc1..8c25f59 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -251,8 +251,9 @@
 	if (!GET_STATUS_OBF(status)) {
 		kcs->obf_timeout -= time;
 		if (kcs->obf_timeout < 0) {
-		    start_error_recovery(kcs, "OBF not ready in time");
-		    return 1;
+			kcs->obf_timeout = OBF_RETRY_TIMEOUT;
+			start_error_recovery(kcs, "OBF not ready in time");
+			return 1;
 		}
 		return 0;
 	}
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index ec4e10f..e6db938 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -55,6 +55,7 @@
 static int ipmi_init_msghandler(void);
 static void smi_recv_tasklet(unsigned long);
 static void handle_new_recv_msgs(ipmi_smi_t intf);
+static void need_waiter(ipmi_smi_t intf);
 
 static int initialized;
 
@@ -73,14 +74,28 @@
  */
 #define MAX_MSG_TIMEOUT		60000
 
+/* Call every ~1000 ms. */
+#define IPMI_TIMEOUT_TIME	1000
+
+/* How many jiffies does it take to get to the timeout time. */
+#define IPMI_TIMEOUT_JIFFIES	((IPMI_TIMEOUT_TIME * HZ) / 1000)
+
+/*
+ * Request events from the queue every second (this is the number of
+ * IPMI_TIMEOUT_TIMES between event requests).  Hopefully, in the
+ * future, IPMI will add a way to know immediately if an event is in
+ * the queue and this silliness can go away.
+ */
+#define IPMI_REQUEST_EV_TIME	(1000 / (IPMI_TIMEOUT_TIME))
+
 /*
  * The main "user" data structure.
  */
 struct ipmi_user {
 	struct list_head link;
 
-	/* Set to "0" when the user is destroyed. */
-	int valid;
+	/* Set to false when the user is destroyed. */
+	bool valid;
 
 	struct kref refcount;
 
@@ -92,7 +107,7 @@
 	ipmi_smi_t intf;
 
 	/* Does this interface receive IPMI events? */
-	int gets_events;
+	bool gets_events;
 };
 
 struct cmd_rcvr {
@@ -383,6 +398,9 @@
 	unsigned int     waiting_events_count; /* How many events in queue? */
 	char             delivering_events;
 	char             event_msg_printed;
+	atomic_t         event_waiters;
+	unsigned int     ticks_to_req_ev;
+	int              last_needs_timer;
 
 	/*
 	 * The event receiver for my BMC, only really used at panic
@@ -395,7 +413,7 @@
 
 	/* For handling of maintenance mode. */
 	int maintenance_mode;
-	int maintenance_mode_enable;
+	bool maintenance_mode_enable;
 	int auto_maintenance_timeout;
 	spinlock_t maintenance_mode_lock; /* Used in a timer... */
 
@@ -451,7 +469,6 @@
 static LIST_HEAD(smi_watchers);
 static DEFINE_MUTEX(smi_watchers_mutex);
 
-
 #define ipmi_inc_stat(intf, stat) \
 	atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
 #define ipmi_get_stat(intf, stat) \
@@ -772,6 +789,7 @@
 		*seq = i;
 		*seqid = intf->seq_table[i].seqid;
 		intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
+		need_waiter(intf);
 	} else {
 		rv = -EAGAIN;
 	}
@@ -941,7 +959,7 @@
 	new_user->handler = handler;
 	new_user->handler_data = handler_data;
 	new_user->intf = intf;
-	new_user->gets_events = 0;
+	new_user->gets_events = false;
 
 	if (!try_module_get(intf->handlers->owner)) {
 		rv = -ENODEV;
@@ -962,10 +980,15 @@
 	 */
 	mutex_unlock(&ipmi_interfaces_mutex);
 
-	new_user->valid = 1;
+	new_user->valid = true;
 	spin_lock_irqsave(&intf->seq_lock, flags);
 	list_add_rcu(&new_user->link, &intf->users);
 	spin_unlock_irqrestore(&intf->seq_lock, flags);
+	if (handler->ipmi_watchdog_pretimeout) {
+		/* User wants pretimeouts, so make sure to watch for them. */
+		if (atomic_inc_return(&intf->event_waiters) == 1)
+			need_waiter(intf);
+	}
 	*user = new_user;
 	return 0;
 
@@ -1019,7 +1042,13 @@
 	struct cmd_rcvr  *rcvr;
 	struct cmd_rcvr  *rcvrs = NULL;
 
-	user->valid = 0;
+	user->valid = false;
+
+	if (user->handler->ipmi_watchdog_pretimeout)
+		atomic_dec(&intf->event_waiters);
+
+	if (user->gets_events)
+		atomic_dec(&intf->event_waiters);
 
 	/* Remove the user from the interface's sequence table. */
 	spin_lock_irqsave(&intf->seq_lock, flags);
@@ -1155,25 +1184,23 @@
 	if (intf->maintenance_mode != mode) {
 		switch (mode) {
 		case IPMI_MAINTENANCE_MODE_AUTO:
-			intf->maintenance_mode = mode;
 			intf->maintenance_mode_enable
 				= (intf->auto_maintenance_timeout > 0);
 			break;
 
 		case IPMI_MAINTENANCE_MODE_OFF:
-			intf->maintenance_mode = mode;
-			intf->maintenance_mode_enable = 0;
+			intf->maintenance_mode_enable = false;
 			break;
 
 		case IPMI_MAINTENANCE_MODE_ON:
-			intf->maintenance_mode = mode;
-			intf->maintenance_mode_enable = 1;
+			intf->maintenance_mode_enable = true;
 			break;
 
 		default:
 			rv = -EINVAL;
 			goto out_unlock;
 		}
+		intf->maintenance_mode = mode;
 
 		maintenance_mode_update(intf);
 	}
@@ -1184,7 +1211,7 @@
 }
 EXPORT_SYMBOL(ipmi_set_maintenance_mode);
 
-int ipmi_set_gets_events(ipmi_user_t user, int val)
+int ipmi_set_gets_events(ipmi_user_t user, bool val)
 {
 	unsigned long        flags;
 	ipmi_smi_t           intf = user->intf;
@@ -1194,8 +1221,18 @@
 	INIT_LIST_HEAD(&msgs);
 
 	spin_lock_irqsave(&intf->events_lock, flags);
+	if (user->gets_events == val)
+		goto out;
+
 	user->gets_events = val;
 
+	if (val) {
+		if (atomic_inc_return(&intf->event_waiters) == 1)
+			need_waiter(intf);
+	} else {
+		atomic_dec(&intf->event_waiters);
+	}
+
 	if (intf->delivering_events)
 		/*
 		 * Another thread is delivering events for this, so
@@ -1289,6 +1326,9 @@
 		goto out_unlock;
 	}
 
+	if (atomic_inc_return(&intf->event_waiters) == 1)
+		need_waiter(intf);
+
 	list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
 
  out_unlock:
@@ -1330,6 +1370,7 @@
 	mutex_unlock(&intf->cmd_rcvrs_mutex);
 	synchronize_rcu();
 	while (rcvrs) {
+		atomic_dec(&intf->event_waiters);
 		rcvr = rcvrs;
 		rcvrs = rcvr->next;
 		kfree(rcvr);
@@ -1535,7 +1576,7 @@
 				= IPMI_MAINTENANCE_MODE_TIMEOUT;
 			if (!intf->maintenance_mode
 			    && !intf->maintenance_mode_enable) {
-				intf->maintenance_mode_enable = 1;
+				intf->maintenance_mode_enable = true;
 				maintenance_mode_update(intf);
 			}
 			spin_unlock_irqrestore(&intf->maintenance_mode_lock,
@@ -2876,6 +2917,8 @@
 		     (unsigned long) intf);
 	atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
 	spin_lock_init(&intf->events_lock);
+	atomic_set(&intf->event_waiters, 0);
+	intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
 	INIT_LIST_HEAD(&intf->waiting_events);
 	intf->waiting_events_count = 0;
 	mutex_init(&intf->cmd_rcvrs_mutex);
@@ -3965,7 +4008,8 @@
 
 static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
 			      struct list_head *timeouts, long timeout_period,
-			      int slot, unsigned long *flags)
+			      int slot, unsigned long *flags,
+			      unsigned int *waiting_msgs)
 {
 	struct ipmi_recv_msg     *msg;
 	struct ipmi_smi_handlers *handlers;
@@ -3977,8 +4021,10 @@
 		return;
 
 	ent->timeout -= timeout_period;
-	if (ent->timeout > 0)
+	if (ent->timeout > 0) {
+		(*waiting_msgs)++;
 		return;
+	}
 
 	if (ent->retries_left == 0) {
 		/* The message has used all its retries. */
@@ -3995,6 +4041,8 @@
 		struct ipmi_smi_msg *smi_msg;
 		/* More retries, send again. */
 
+		(*waiting_msgs)++;
+
 		/*
 		 * Start with the max timer, set to normal timer after
 		 * the message is sent.
@@ -4040,117 +4088,118 @@
 	}
 }
 
-static void ipmi_timeout_handler(long timeout_period)
+static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, long timeout_period)
 {
-	ipmi_smi_t           intf;
 	struct list_head     timeouts;
 	struct ipmi_recv_msg *msg, *msg2;
 	unsigned long        flags;
 	int                  i;
+	unsigned int         waiting_msgs = 0;
 
-	rcu_read_lock();
-	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
-		tasklet_schedule(&intf->recv_tasklet);
+	/*
+	 * Go through the seq table and find any messages that
+	 * have timed out, putting them in the timeouts
+	 * list.
+	 */
+	INIT_LIST_HEAD(&timeouts);
+	spin_lock_irqsave(&intf->seq_lock, flags);
+	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
+		check_msg_timeout(intf, &(intf->seq_table[i]),
+				  &timeouts, timeout_period, i,
+				  &flags, &waiting_msgs);
+	spin_unlock_irqrestore(&intf->seq_lock, flags);
 
-		/*
-		 * Go through the seq table and find any messages that
-		 * have timed out, putting them in the timeouts
-		 * list.
-		 */
-		INIT_LIST_HEAD(&timeouts);
-		spin_lock_irqsave(&intf->seq_lock, flags);
-		for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
-			check_msg_timeout(intf, &(intf->seq_table[i]),
-					  &timeouts, timeout_period, i,
-					  &flags);
-		spin_unlock_irqrestore(&intf->seq_lock, flags);
+	list_for_each_entry_safe(msg, msg2, &timeouts, link)
+		deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
 
-		list_for_each_entry_safe(msg, msg2, &timeouts, link)
-			deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
-
-		/*
-		 * Maintenance mode handling.  Check the timeout
-		 * optimistically before we claim the lock.  It may
-		 * mean a timeout gets missed occasionally, but that
-		 * only means the timeout gets extended by one period
-		 * in that case.  No big deal, and it avoids the lock
-		 * most of the time.
-		 */
+	/*
+	 * Maintenance mode handling.  Check the timeout
+	 * optimistically before we claim the lock.  It may
+	 * mean a timeout gets missed occasionally, but that
+	 * only means the timeout gets extended by one period
+	 * in that case.  No big deal, and it avoids the lock
+	 * most of the time.
+	 */
+	if (intf->auto_maintenance_timeout > 0) {
+		spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
 		if (intf->auto_maintenance_timeout > 0) {
-			spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
-			if (intf->auto_maintenance_timeout > 0) {
-				intf->auto_maintenance_timeout
-					-= timeout_period;
-				if (!intf->maintenance_mode
-				    && (intf->auto_maintenance_timeout <= 0)) {
-					intf->maintenance_mode_enable = 0;
-					maintenance_mode_update(intf);
-				}
+			intf->auto_maintenance_timeout
+				-= timeout_period;
+			if (!intf->maintenance_mode
+			    && (intf->auto_maintenance_timeout <= 0)) {
+				intf->maintenance_mode_enable = false;
+				maintenance_mode_update(intf);
 			}
-			spin_unlock_irqrestore(&intf->maintenance_mode_lock,
-					       flags);
 		}
+		spin_unlock_irqrestore(&intf->maintenance_mode_lock,
+				       flags);
 	}
-	rcu_read_unlock();
+
+	tasklet_schedule(&intf->recv_tasklet);
+
+	return waiting_msgs;
 }
 
-static void ipmi_request_event(void)
+static void ipmi_request_event(ipmi_smi_t intf)
 {
-	ipmi_smi_t               intf;
 	struct ipmi_smi_handlers *handlers;
 
-	rcu_read_lock();
-	/*
-	 * Called from the timer, no need to check if handlers is
-	 * valid.
-	 */
-	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
-		/* No event requests when in maintenance mode. */
-		if (intf->maintenance_mode_enable)
-			continue;
+	/* No event requests when in maintenance mode. */
+	if (intf->maintenance_mode_enable)
+		return;
 
-		handlers = intf->handlers;
-		if (handlers)
-			handlers->request_events(intf->send_info);
-	}
-	rcu_read_unlock();
+	handlers = intf->handlers;
+	if (handlers)
+		handlers->request_events(intf->send_info);
 }
 
 static struct timer_list ipmi_timer;
 
-/* Call every ~1000 ms. */
-#define IPMI_TIMEOUT_TIME	1000
-
-/* How many jiffies does it take to get to the timeout time. */
-#define IPMI_TIMEOUT_JIFFIES	((IPMI_TIMEOUT_TIME * HZ) / 1000)
-
-/*
- * Request events from the queue every second (this is the number of
- * IPMI_TIMEOUT_TIMES between event requests).  Hopefully, in the
- * future, IPMI will add a way to know immediately if an event is in
- * the queue and this silliness can go away.
- */
-#define IPMI_REQUEST_EV_TIME	(1000 / (IPMI_TIMEOUT_TIME))
-
 static atomic_t stop_operation;
-static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
 
 static void ipmi_timeout(unsigned long data)
 {
+	ipmi_smi_t intf;
+	int nt = 0;
+
 	if (atomic_read(&stop_operation))
 		return;
 
-	ticks_to_req_ev--;
-	if (ticks_to_req_ev == 0) {
-		ipmi_request_event();
-		ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
+	rcu_read_lock();
+	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+		int lnt = 0;
+
+		if (atomic_read(&intf->event_waiters)) {
+			intf->ticks_to_req_ev--;
+			if (intf->ticks_to_req_ev == 0) {
+				ipmi_request_event(intf);
+				intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
+			}
+			lnt++;
+		}
+
+		lnt += ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME);
+
+		lnt = !!lnt;
+		if (lnt != intf->last_needs_timer &&
+					intf->handlers->set_need_watch)
+			intf->handlers->set_need_watch(intf->send_info, lnt);
+		intf->last_needs_timer = lnt;
+
+		nt += lnt;
 	}
+	rcu_read_unlock();
 
-	ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
-
-	mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+	if (nt)
+		mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
 }
 
+static void need_waiter(ipmi_smi_t intf)
+{
+	/* Racy, but worst case we start the timer twice. */
+	if (!timer_pending(&ipmi_timer))
+		mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+}
 
 static atomic_t smi_msg_inuse_count = ATOMIC_INIT(0);
 static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index b7efd3c..1c4bb4f 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -217,7 +217,7 @@
 	unsigned char       msg_flags;
 
 	/* Does the BMC have an event buffer? */
-	char		    has_event_buffer;
+	bool		    has_event_buffer;
 
 	/*
 	 * If set to true, this will request events the next time the
@@ -230,7 +230,7 @@
 	 * call.  Generally used after a panic to make sure stuff goes
 	 * out.
 	 */
-	int                 run_to_completion;
+	bool                run_to_completion;
 
 	/* The I/O port of an SI interface. */
 	int                 port;
@@ -248,19 +248,25 @@
 	/* The timer for this si. */
 	struct timer_list   si_timer;
 
+	/* This flag is set, if the timer is running (timer_pending() isn't enough) */
+	bool		    timer_running;
+
 	/* The time (in jiffies) the last timeout occurred at. */
 	unsigned long       last_timeout_jiffies;
 
 	/* Used to gracefully stop the timer without race conditions. */
 	atomic_t            stop_operation;
 
+	/* Are we waiting for the events, pretimeouts, received msgs? */
+	atomic_t            need_watch;
+
 	/*
 	 * The driver will disable interrupts when it gets into a
 	 * situation where it cannot handle messages due to lack of
 	 * memory.  Once that situation clears up, it will re-enable
 	 * interrupts.
 	 */
-	int interrupt_disabled;
+	bool interrupt_disabled;
 
 	/* From the get device id response... */
 	struct ipmi_device_id device_id;
@@ -273,7 +279,7 @@
 	 * True if we allocated the device, false if it came from
 	 * someplace else (like PCI).
 	 */
-	int dev_registered;
+	bool dev_registered;
 
 	/* Slave address, could be reported from DMI. */
 	unsigned char slave_addr;
@@ -297,19 +303,19 @@
 static int force_kipmid[SI_MAX_PARMS];
 static int num_force_kipmid;
 #ifdef CONFIG_PCI
-static int pci_registered;
+static bool pci_registered;
 #endif
 #ifdef CONFIG_ACPI
-static int pnp_registered;
+static bool pnp_registered;
 #endif
 #ifdef CONFIG_PARISC
-static int parisc_registered;
+static bool parisc_registered;
 #endif
 
 static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
 static int num_max_busy_us;
 
-static int unload_when_empty = 1;
+static bool unload_when_empty = true;
 
 static int add_smi(struct smi_info *smi);
 static int try_smi_init(struct smi_info *smi);
@@ -434,6 +440,13 @@
 	smi_info->si_state = SI_CLEARING_FLAGS;
 }
 
+static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
+{
+	smi_info->last_timeout_jiffies = jiffies;
+	mod_timer(&smi_info->si_timer, new_val);
+	smi_info->timer_running = true;
+}
+
 /*
  * When we have a situtaion where we run out of memory and cannot
  * allocate messages, we just leave them in the BMC and run the system
@@ -444,10 +457,9 @@
 {
 	if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
 		start_disable_irq(smi_info);
-		smi_info->interrupt_disabled = 1;
+		smi_info->interrupt_disabled = true;
 		if (!atomic_read(&smi_info->stop_operation))
-			mod_timer(&smi_info->si_timer,
-				  jiffies + SI_TIMEOUT_JIFFIES);
+			smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
 	}
 }
 
@@ -455,7 +467,7 @@
 {
 	if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
 		start_enable_irq(smi_info);
-		smi_info->interrupt_disabled = 0;
+		smi_info->interrupt_disabled = false;
 	}
 }
 
@@ -700,7 +712,7 @@
 			dev_warn(smi_info->dev,
 				 "Maybe ok, but ipmi might run very slowly.\n");
 		} else
-			smi_info->interrupt_disabled = 0;
+			smi_info->interrupt_disabled = false;
 		smi_info->si_state = SI_NORMAL;
 		break;
 	}
@@ -853,6 +865,19 @@
 	return si_sm_result;
 }
 
+static void check_start_timer_thread(struct smi_info *smi_info)
+{
+	if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
+		smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
+
+		if (smi_info->thread)
+			wake_up_process(smi_info->thread);
+
+		start_next_msg(smi_info);
+		smi_event_handler(smi_info, 0);
+	}
+}
+
 static void sender(void                *send_info,
 		   struct ipmi_smi_msg *msg,
 		   int                 priority)
@@ -906,27 +931,11 @@
 	else
 		list_add_tail(&msg->link, &smi_info->xmit_msgs);
 
-	if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
-		/*
-		 * last_timeout_jiffies is updated here to avoid
-		 * smi_timeout() handler passing very large time_diff
-		 * value to smi_event_handler() that causes
-		 * the send command to abort.
-		 */
-		smi_info->last_timeout_jiffies = jiffies;
-
-		mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
-
-		if (smi_info->thread)
-			wake_up_process(smi_info->thread);
-
-		start_next_msg(smi_info);
-		smi_event_handler(smi_info, 0);
-	}
+	check_start_timer_thread(smi_info);
 	spin_unlock_irqrestore(&smi_info->si_lock, flags);
 }
 
-static void set_run_to_completion(void *send_info, int i_run_to_completion)
+static void set_run_to_completion(void *send_info, bool i_run_to_completion)
 {
 	struct smi_info   *smi_info = send_info;
 	enum si_sm_result result;
@@ -1004,6 +1013,17 @@
 
 		spin_lock_irqsave(&(smi_info->si_lock), flags);
 		smi_result = smi_event_handler(smi_info, 0);
+
+		/*
+		 * If the driver is doing something, there is a possible
+		 * race with the timer.  If the timer handler see idle,
+		 * and the thread here sees something else, the timer
+		 * handler won't restart the timer even though it is
+		 * required.  So start it here if necessary.
+		 */
+		if (smi_result != SI_SM_IDLE && !smi_info->timer_running)
+			smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
+
 		spin_unlock_irqrestore(&(smi_info->si_lock), flags);
 		busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
 						  &busy_until);
@@ -1011,9 +1031,15 @@
 			; /* do nothing */
 		else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
 			schedule();
-		else if (smi_result == SI_SM_IDLE)
-			schedule_timeout_interruptible(100);
-		else
+		else if (smi_result == SI_SM_IDLE) {
+			if (atomic_read(&smi_info->need_watch)) {
+				schedule_timeout_interruptible(100);
+			} else {
+				/* Wait to be woken up when we are needed. */
+				__set_current_state(TASK_INTERRUPTIBLE);
+				schedule();
+			}
+		} else
 			schedule_timeout_interruptible(1);
 	}
 	return 0;
@@ -1024,7 +1050,7 @@
 {
 	struct smi_info *smi_info = send_info;
 	unsigned long flags = 0;
-	int run_to_completion = smi_info->run_to_completion;
+	bool run_to_completion = smi_info->run_to_completion;
 
 	/*
 	 * Make sure there is some delay in the poll loop so we can
@@ -1049,6 +1075,17 @@
 	atomic_set(&smi_info->req_events, 1);
 }
 
+static void set_need_watch(void *send_info, bool enable)
+{
+	struct smi_info *smi_info = send_info;
+	unsigned long flags;
+
+	atomic_set(&smi_info->need_watch, enable);
+	spin_lock_irqsave(&smi_info->si_lock, flags);
+	check_start_timer_thread(smi_info);
+	spin_unlock_irqrestore(&smi_info->si_lock, flags);
+}
+
 static int initialized;
 
 static void smi_timeout(unsigned long data)
@@ -1073,10 +1110,6 @@
 		     * SI_USEC_PER_JIFFY);
 	smi_result = smi_event_handler(smi_info, time_diff);
 
-	spin_unlock_irqrestore(&(smi_info->si_lock), flags);
-
-	smi_info->last_timeout_jiffies = jiffies_now;
-
 	if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
 		/* Running with interrupts, only do long timeouts. */
 		timeout = jiffies + SI_TIMEOUT_JIFFIES;
@@ -1098,7 +1131,10 @@
 
  do_mod_timer:
 	if (smi_result != SI_SM_IDLE)
-		mod_timer(&(smi_info->si_timer), timeout);
+		smi_mod_timer(smi_info, timeout);
+	else
+		smi_info->timer_running = false;
+	spin_unlock_irqrestore(&(smi_info->si_lock), flags);
 }
 
 static irqreturn_t si_irq_handler(int irq, void *data)
@@ -1146,8 +1182,7 @@
 
 	/* Set up the timer that drives the interface. */
 	setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
-	new_smi->last_timeout_jiffies = jiffies;
-	mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
+	smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
 
 	/*
 	 * Check if the user forcefully enabled the daemon.
@@ -1188,7 +1223,7 @@
 	return 0;
 }
 
-static void set_maintenance_mode(void *send_info, int enable)
+static void set_maintenance_mode(void *send_info, bool enable)
 {
 	struct smi_info   *smi_info = send_info;
 
@@ -1202,6 +1237,7 @@
 	.get_smi_info		= get_smi_info,
 	.sender			= sender,
 	.request_events		= request_events,
+	.set_need_watch		= set_need_watch,
 	.set_maintenance_mode   = set_maintenance_mode,
 	.set_run_to_completion  = set_run_to_completion,
 	.poll			= poll,
@@ -1229,7 +1265,7 @@
 #ifdef CONFIG_PCI
 static bool          si_trypci = 1;
 #endif
-static bool          si_trydefaults = 1;
+static bool          si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS);
 static char          *si_type[SI_MAX_PARMS];
 #define MAX_SI_TYPE_STR 30
 static char          si_type_str[MAX_SI_TYPE_STR];
@@ -1328,7 +1364,7 @@
 MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
 		 " disabled(0).  Normally the IPMI driver auto-detects"
 		 " this, but the value may be overridden by this parm.");
-module_param(unload_when_empty, int, 0);
+module_param(unload_when_empty, bool, 0);
 MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
 		 " specified or found, default is 1.  Setting to 0"
 		 " is useful for hot add of devices using hotmod.");
@@ -3336,18 +3372,19 @@
 	INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
 	new_smi->curr_msg = NULL;
 	atomic_set(&new_smi->req_events, 0);
-	new_smi->run_to_completion = 0;
+	new_smi->run_to_completion = false;
 	for (i = 0; i < SI_NUM_STATS; i++)
 		atomic_set(&new_smi->stats[i], 0);
 
-	new_smi->interrupt_disabled = 1;
+	new_smi->interrupt_disabled = true;
 	atomic_set(&new_smi->stop_operation, 0);
+	atomic_set(&new_smi->need_watch, 0);
 	new_smi->intf_num = smi_num;
 	smi_num++;
 
 	rv = try_enable_event_buffer(new_smi);
 	if (rv == 0)
-		new_smi->has_event_buffer = 1;
+		new_smi->has_event_buffer = true;
 
 	/*
 	 * Start clearing the flags before we enable interrupts or the
@@ -3381,7 +3418,7 @@
 			       rv);
 			goto out_err;
 		}
-		new_smi->dev_registered = 1;
+		new_smi->dev_registered = true;
 	}
 
 	rv = ipmi_register_smi(&handlers,
@@ -3430,7 +3467,7 @@
 	wait_for_timer_and_thread(new_smi);
 
  out_err:
-	new_smi->interrupt_disabled = 1;
+	new_smi->interrupt_disabled = true;
 
 	if (new_smi->intf) {
 		ipmi_unregister_smi(new_smi->intf);
@@ -3466,7 +3503,7 @@
 
 	if (new_smi->dev_registered) {
 		platform_device_unregister(new_smi->pdev);
-		new_smi->dev_registered = 0;
+		new_smi->dev_registered = false;
 	}
 
 	return rv;
@@ -3521,14 +3558,14 @@
 			printk(KERN_ERR PFX "Unable to register "
 			       "PCI driver: %d\n", rv);
 		else
-			pci_registered = 1;
+			pci_registered = true;
 	}
 #endif
 
 #ifdef CONFIG_ACPI
 	if (si_tryacpi) {
 		pnp_register_driver(&ipmi_pnp_driver);
-		pnp_registered = 1;
+		pnp_registered = true;
 	}
 #endif
 
@@ -3544,7 +3581,7 @@
 
 #ifdef CONFIG_PARISC
 	register_parisc_driver(&ipmi_parisc_driver);
-	parisc_registered = 1;
+	parisc_registered = true;
 	/* poking PC IO addresses will crash machine, don't do it */
 	si_trydefaults = 0;
 #endif
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig
index b27f534..8d3dfb0 100644
--- a/drivers/char/pcmcia/Kconfig
+++ b/drivers/char/pcmcia/Kconfig
@@ -15,7 +15,7 @@
 
 	  This driver may be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called synclinkmp.  If you want to do that, say M
+	  The module will be called synclink_cs.  If you want to do that, say M
 	  here.
 
 config CARDMAN_4000
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index daea84c..a15ce4e 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -17,7 +17,7 @@
 #include <linux/device.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
-#include <linux/export.h>
+#include <linux/module.h>
 
 struct ttyprintk_port {
 	struct tty_port port;
@@ -210,10 +210,19 @@
 	return 0;
 
 error:
+	put_tty_driver(ttyprintk_driver);
+	tty_port_destroy(&tpk_port.port);
+	return ret;
+}
+
+static void __exit ttyprintk_exit(void)
+{
 	tty_unregister_driver(ttyprintk_driver);
 	put_tty_driver(ttyprintk_driver);
 	tty_port_destroy(&tpk_port.port);
-	ttyprintk_driver = NULL;
-	return ret;
 }
+
 device_initcall(ttyprintk_init);
+module_exit(ttyprintk_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c
index e9a0415..30bcc539 100644
--- a/drivers/gpio/gpio-spear-spics.c
+++ b/drivers/gpio/gpio-spear-spics.c
@@ -2,7 +2,7 @@
  * SPEAr platform SPI chipselect abstraction over gpiolib
  *
  * Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
@@ -205,6 +205,6 @@
 }
 subsys_initcall(spics_gpio_init);
 
-MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
 MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 9d25dbb..48e38ba 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -23,7 +23,7 @@
 
 drm-usb-y   := drm_usb.o
 
-drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o
+drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o
 drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index 977cfb3..635f6ff 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -572,7 +572,7 @@
 		for (loop = 0; loop < CBR_PASSNUM2; loop++) {
 			if ((data = cbr_test2(ast)) != 0) {
 				data2 &= data;
-				if (!data)
+				if (!data2)
 					return 0;
 				break;
 			}
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 741965c..7eb52dd 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -1,5 +1,6 @@
 #include <linux/io.h>
 #include <linux/fb.h>
+#include <linux/console.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
@@ -87,8 +88,6 @@
 		struct bochs_framebuffer gfb;
 		struct drm_fb_helper helper;
 		int size;
-		int x1, y1, x2, y2; /* dirty rect */
-		spinlock_t dirty_lock;
 		bool initialized;
 	} fb;
 };
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index 395bba2..9c13df2 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -95,6 +95,49 @@
 };
 
 /* ---------------------------------------------------------------------- */
+/* pm interface                                                           */
+
+static int bochs_pm_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	struct bochs_device *bochs = drm_dev->dev_private;
+
+	drm_kms_helper_poll_disable(drm_dev);
+
+	if (bochs->fb.initialized) {
+		console_lock();
+		fb_set_suspend(bochs->fb.helper.fbdev, 1);
+		console_unlock();
+	}
+
+	return 0;
+}
+
+static int bochs_pm_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	struct bochs_device *bochs = drm_dev->dev_private;
+
+	drm_helper_resume_force_mode(drm_dev);
+
+	if (bochs->fb.initialized) {
+		console_lock();
+		fb_set_suspend(bochs->fb.helper.fbdev, 0);
+		console_unlock();
+	}
+
+	drm_kms_helper_poll_enable(drm_dev);
+	return 0;
+}
+
+static const struct dev_pm_ops bochs_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend,
+				bochs_pm_resume)
+};
+
+/* ---------------------------------------------------------------------- */
 /* pci interface                                                          */
 
 static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
@@ -155,6 +198,7 @@
 	.id_table =	bochs_pci_tbl,
 	.probe =	bochs_pci_probe,
 	.remove =	bochs_pci_remove,
+	.driver.pm =    &bochs_pm_ops,
 };
 
 /* ---------------------------------------------------------------------- */
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
index 4da5206..561b844 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -190,7 +190,6 @@
 	int ret;
 
 	bochs->fb.helper.funcs = &bochs_fb_helper_funcs;
-	spin_lock_init(&bochs->fb.dirty_lock);
 
 	ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper,
 				 1, 1);
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 953fc8a..08ce520 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/console.h>
 #include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
 
 #include "cirrus_drv.h"
 
@@ -75,6 +76,41 @@
 	drm_put_dev(dev);
 }
 
+static int cirrus_pm_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	struct cirrus_device *cdev = drm_dev->dev_private;
+
+	drm_kms_helper_poll_disable(drm_dev);
+
+	if (cdev->mode_info.gfbdev) {
+		console_lock();
+		fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
+		console_unlock();
+	}
+
+	return 0;
+}
+
+static int cirrus_pm_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	struct cirrus_device *cdev = drm_dev->dev_private;
+
+	drm_helper_resume_force_mode(drm_dev);
+
+	if (cdev->mode_info.gfbdev) {
+		console_lock();
+		fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
+		console_unlock();
+	}
+
+	drm_kms_helper_poll_enable(drm_dev);
+	return 0;
+}
+
 static const struct file_operations cirrus_driver_fops = {
 	.owner = THIS_MODULE,
 	.open = drm_open,
@@ -103,11 +139,17 @@
 	.dumb_destroy = drm_gem_dumb_destroy,
 };
 
+static const struct dev_pm_ops cirrus_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
+				cirrus_pm_resume)
+};
+
 static struct pci_driver cirrus_pci_driver = {
 	.name = DRIVER_NAME,
 	.id_table = pciidlist,
 	.probe = cirrus_pci_probe,
 	.remove = cirrus_pci_remove,
+	.driver.pm = &cirrus_pm_ops,
 };
 
 static int __init cirrus_init(void)
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 2d64aea..f59433b 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -308,6 +308,9 @@
 
 	WREG_HDR(hdr);
 	cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);
+
+	/* Unblank (needed on S3 resume, vgabios doesn't do it then) */
+	outb(0x20, 0x3c0);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index c43825e..df281b5 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -72,147 +72,6 @@
 }
 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
 
-static bool drm_kms_helper_poll = true;
-module_param_named(poll, drm_kms_helper_poll, bool, 0600);
-
-static void drm_mode_validate_flag(struct drm_connector *connector,
-				   int flags)
-{
-	struct drm_display_mode *mode;
-
-	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
-		      DRM_MODE_FLAG_3D_MASK))
-		return;
-
-	list_for_each_entry(mode, &connector->modes, head) {
-		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
-				!(flags & DRM_MODE_FLAG_INTERLACE))
-			mode->status = MODE_NO_INTERLACE;
-		if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
-				!(flags & DRM_MODE_FLAG_DBLSCAN))
-			mode->status = MODE_NO_DBLESCAN;
-		if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
-				!(flags & DRM_MODE_FLAG_3D_MASK))
-			mode->status = MODE_NO_STEREO;
-	}
-
-	return;
-}
-
-/**
- * drm_helper_probe_single_connector_modes - get complete set of display modes
- * @connector: connector to probe
- * @maxX: max width for modes
- * @maxY: max height for modes
- *
- * Based on the helper callbacks implemented by @connector try to detect all
- * valid modes.  Modes will first be added to the connector's probed_modes list,
- * then culled (based on validity and the @maxX, @maxY parameters) and put into
- * the normal modes list.
- *
- * Intended to be use as a generic implementation of the ->fill_modes()
- * @connector vfunc for drivers that use the crtc helpers for output mode
- * filtering and detection.
- *
- * Returns:
- * The number of modes found on @connector.
- */
-int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
-					    uint32_t maxX, uint32_t maxY)
-{
-	struct drm_device *dev = connector->dev;
-	struct drm_display_mode *mode;
-	struct drm_connector_helper_funcs *connector_funcs =
-		connector->helper_private;
-	int count = 0;
-	int mode_flags = 0;
-	bool verbose_prune = true;
-
-	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
-
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
-			drm_get_connector_name(connector));
-	/* set all modes to the unverified state */
-	list_for_each_entry(mode, &connector->modes, head)
-		mode->status = MODE_UNVERIFIED;
-
-	if (connector->force) {
-		if (connector->force == DRM_FORCE_ON)
-			connector->status = connector_status_connected;
-		else
-			connector->status = connector_status_disconnected;
-		if (connector->funcs->force)
-			connector->funcs->force(connector);
-	} else {
-		connector->status = connector->funcs->detect(connector, true);
-	}
-
-	/* Re-enable polling in case the global poll config changed. */
-	if (drm_kms_helper_poll != dev->mode_config.poll_running)
-		drm_kms_helper_poll_enable(dev);
-
-	dev->mode_config.poll_running = drm_kms_helper_poll;
-
-	if (connector->status == connector_status_disconnected) {
-		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
-			connector->base.id, drm_get_connector_name(connector));
-		drm_mode_connector_update_edid_property(connector, NULL);
-		verbose_prune = false;
-		goto prune;
-	}
-
-#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
-	count = drm_load_edid_firmware(connector);
-	if (count == 0)
-#endif
-		count = (*connector_funcs->get_modes)(connector);
-
-	if (count == 0 && connector->status == connector_status_connected)
-		count = drm_add_modes_noedid(connector, 1024, 768);
-	if (count == 0)
-		goto prune;
-
-	drm_mode_connector_list_update(connector);
-
-	if (maxX && maxY)
-		drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
-
-	if (connector->interlace_allowed)
-		mode_flags |= DRM_MODE_FLAG_INTERLACE;
-	if (connector->doublescan_allowed)
-		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
-	if (connector->stereo_allowed)
-		mode_flags |= DRM_MODE_FLAG_3D_MASK;
-	drm_mode_validate_flag(connector, mode_flags);
-
-	list_for_each_entry(mode, &connector->modes, head) {
-		if (mode->status == MODE_OK)
-			mode->status = connector_funcs->mode_valid(connector,
-								   mode);
-	}
-
-prune:
-	drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
-
-	if (list_empty(&connector->modes))
-		return 0;
-
-	list_for_each_entry(mode, &connector->modes, head)
-		mode->vrefresh = drm_mode_vrefresh(mode);
-
-	drm_mode_sort(&connector->modes);
-
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
-			drm_get_connector_name(connector));
-	list_for_each_entry(mode, &connector->modes, head) {
-		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
-		drm_mode_debug_printmodeline(mode);
-	}
-
-	return count;
-}
-EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
-
 /**
  * drm_helper_encoder_in_use - check if a given encoder is in use
  * @encoder: encoder to check
@@ -1020,232 +879,3 @@
 	drm_modeset_unlock_all(dev);
 }
 EXPORT_SYMBOL(drm_helper_resume_force_mode);
-
-/**
- * drm_kms_helper_hotplug_event - fire off KMS hotplug events
- * @dev: drm_device whose connector state changed
- *
- * This function fires off the uevent for userspace and also calls the
- * output_poll_changed function, which is most commonly used to inform the fbdev
- * emulation code and allow it to update the fbcon output configuration.
- *
- * Drivers should call this from their hotplug handling code when a change is
- * detected. Note that this function does not do any output detection of its
- * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
- * driver already.
- *
- * This function must be called from process context with no mode
- * setting locks held.
- */
-void drm_kms_helper_hotplug_event(struct drm_device *dev)
-{
-	/* send a uevent + call fbdev */
-	drm_sysfs_hotplug_event(dev);
-	if (dev->mode_config.funcs->output_poll_changed)
-		dev->mode_config.funcs->output_poll_changed(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
-
-#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
-static void output_poll_execute(struct work_struct *work)
-{
-	struct delayed_work *delayed_work = to_delayed_work(work);
-	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
-	struct drm_connector *connector;
-	enum drm_connector_status old_status;
-	bool repoll = false, changed = false;
-
-	if (!drm_kms_helper_poll)
-		return;
-
-	mutex_lock(&dev->mode_config.mutex);
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
-		/* Ignore forced connectors. */
-		if (connector->force)
-			continue;
-
-		/* Ignore HPD capable connectors and connectors where we don't
-		 * want any hotplug detection at all for polling. */
-		if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
-			continue;
-
-		repoll = true;
-
-		old_status = connector->status;
-		/* if we are connected and don't want to poll for disconnect
-		   skip it */
-		if (old_status == connector_status_connected &&
-		    !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
-			continue;
-
-		connector->status = connector->funcs->detect(connector, false);
-		if (old_status != connector->status) {
-			const char *old, *new;
-
-			old = drm_get_connector_status_name(old_status);
-			new = drm_get_connector_status_name(connector->status);
-
-			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
-				      "status updated from %s to %s\n",
-				      connector->base.id,
-				      drm_get_connector_name(connector),
-				      old, new);
-
-			changed = true;
-		}
-	}
-
-	mutex_unlock(&dev->mode_config.mutex);
-
-	if (changed)
-		drm_kms_helper_hotplug_event(dev);
-
-	if (repoll)
-		schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
-}
-
-/**
- * drm_kms_helper_poll_disable - disable output polling
- * @dev: drm_device
- *
- * This function disables the output polling work.
- *
- * Drivers can call this helper from their device suspend implementation. It is
- * not an error to call this even when output polling isn't enabled or arlready
- * disabled.
- */
-void drm_kms_helper_poll_disable(struct drm_device *dev)
-{
-	if (!dev->mode_config.poll_enabled)
-		return;
-	cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_disable);
-
-/**
- * drm_kms_helper_poll_enable - re-enable output polling.
- * @dev: drm_device
- *
- * This function re-enables the output polling work.
- *
- * Drivers can call this helper from their device resume implementation. It is
- * an error to call this when the output polling support has not yet been set
- * up.
- */
-void drm_kms_helper_poll_enable(struct drm_device *dev)
-{
-	bool poll = false;
-	struct drm_connector *connector;
-
-	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
-		return;
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
-					 DRM_CONNECTOR_POLL_DISCONNECT))
-			poll = true;
-	}
-
-	if (poll)
-		schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_enable);
-
-/**
- * drm_kms_helper_poll_init - initialize and enable output polling
- * @dev: drm_device
- *
- * This function intializes and then also enables output polling support for
- * @dev. Drivers which do not have reliable hotplug support in hardware can use
- * this helper infrastructure to regularly poll such connectors for changes in
- * their connection state.
- *
- * Drivers can control which connectors are polled by setting the
- * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On
- * connectors where probing live outputs can result in visual distortion drivers
- * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this.
- * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are
- * completely ignored by the polling logic.
- *
- * Note that a connector can be both polled and probed from the hotplug handler,
- * in case the hotplug interrupt is known to be unreliable.
- */
-void drm_kms_helper_poll_init(struct drm_device *dev)
-{
-	INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
-	dev->mode_config.poll_enabled = true;
-
-	drm_kms_helper_poll_enable(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_init);
-
-/**
- * drm_kms_helper_poll_fini - disable output polling and clean it up
- * @dev: drm_device
- */
-void drm_kms_helper_poll_fini(struct drm_device *dev)
-{
-	drm_kms_helper_poll_disable(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_fini);
-
-/**
- * drm_helper_hpd_irq_event - hotplug processing
- * @dev: drm_device
- *
- * Drivers can use this helper function to run a detect cycle on all connectors
- * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All
- * other connectors are ignored, which is useful to avoid reprobing fixed
- * panels.
- *
- * This helper function is useful for drivers which can't or don't track hotplug
- * interrupts for each connector.
- *
- * Drivers which support hotplug interrupts for each connector individually and
- * which have a more fine-grained detect logic should bypass this code and
- * directly call drm_kms_helper_hotplug_event() in case the connector state
- * changed.
- *
- * This function must be called from process context with no mode
- * setting locks held.
- *
- * Note that a connector can be both polled and probed from the hotplug handler,
- * in case the hotplug interrupt is known to be unreliable.
- */
-bool drm_helper_hpd_irq_event(struct drm_device *dev)
-{
-	struct drm_connector *connector;
-	enum drm_connector_status old_status;
-	bool changed = false;
-
-	if (!dev->mode_config.poll_enabled)
-		return false;
-
-	mutex_lock(&dev->mode_config.mutex);
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
-		/* Only handle HPD capable connectors. */
-		if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
-			continue;
-
-		old_status = connector->status;
-
-		connector->status = connector->funcs->detect(connector, false);
-		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
-			      connector->base.id,
-			      drm_get_connector_name(connector),
-			      drm_get_connector_status_name(old_status),
-			      drm_get_connector_status_name(connector->status));
-		if (old_status != connector->status)
-			changed = true;
-	}
-
-	mutex_unlock(&dev->mode_config.mutex);
-
-	if (changed)
-		drm_kms_helper_hotplug_event(dev);
-
-	return changed;
-}
-EXPORT_SYMBOL(drm_helper_hpd_irq_event);
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 2767148..4b6e6f3 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -577,7 +577,9 @@
 
 /*
  * Transfer a single I2C-over-AUX message and handle various error conditions,
- * retrying the transaction as appropriate.
+ * retrying the transaction as appropriate.  It is assumed that the
+ * aux->transfer function does not modify anything in the msg other than the
+ * reply field.
  */
 static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 {
@@ -665,11 +667,26 @@
 {
 	struct drm_dp_aux *aux = adapter->algo_data;
 	unsigned int i, j;
+	struct drm_dp_aux_msg msg;
+	int err = 0;
+
+	memset(&msg, 0, sizeof(msg));
 
 	for (i = 0; i < num; i++) {
-		struct drm_dp_aux_msg msg;
-		int err;
-
+		msg.address = msgs[i].addr;
+		msg.request = (msgs[i].flags & I2C_M_RD) ?
+			DP_AUX_I2C_READ :
+			DP_AUX_I2C_WRITE;
+		msg.request |= DP_AUX_I2C_MOT;
+		/* Send a bare address packet to start the transaction.
+		 * Zero sized messages specify an address only (bare
+		 * address) transaction.
+		 */
+		msg.buffer = NULL;
+		msg.size = 0;
+		err = drm_dp_i2c_do_msg(aux, &msg);
+		if (err < 0)
+			break;
 		/*
 		 * Many hardware implementations support FIFOs larger than a
 		 * single byte, but it has been empirically determined that
@@ -678,30 +695,28 @@
 		 * transferred byte-by-byte.
 		 */
 		for (j = 0; j < msgs[i].len; j++) {
-			memset(&msg, 0, sizeof(msg));
-			msg.address = msgs[i].addr;
-
-			msg.request = (msgs[i].flags & I2C_M_RD) ?
-					DP_AUX_I2C_READ :
-					DP_AUX_I2C_WRITE;
-
-			/*
-			 * All messages except the last one are middle-of-
-			 * transfer messages.
-			 */
-			if ((i < num - 1) || (j < msgs[i].len - 1))
-				msg.request |= DP_AUX_I2C_MOT;
-
 			msg.buffer = msgs[i].buf + j;
 			msg.size = 1;
 
 			err = drm_dp_i2c_do_msg(aux, &msg);
 			if (err < 0)
-				return err;
+				break;
 		}
+		if (err < 0)
+			break;
 	}
+	if (err >= 0)
+		err = num;
+	/* Send a bare address packet to close out the transaction.
+	 * Zero sized messages specify an address only (bare
+	 * address) transaction.
+	 */
+	msg.request &= ~DP_AUX_I2C_MOT;
+	msg.buffer = NULL;
+	msg.size = 0;
+	(void)drm_dp_i2c_do_msg(aux, &msg);
 
-	return num;
+	return err;
 }
 
 static const struct i2c_algorithm drm_dp_i2c_algo = {
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 71e2d3f..04a209e 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -207,8 +207,6 @@
 		return 0;
 	}
 
-	WARN(1, "no hole found for node 0x%lx + 0x%lx\n",
-	     node->start, node->size);
 	return -ENOSPC;
 }
 EXPORT_SYMBOL(drm_mm_reserve_node);
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index e768d35..d2b1c03 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -203,9 +203,9 @@
  *
  * Provides a default plane disable handler for primary planes.  This is handler
  * is called in response to a userspace SetPlane operation on the plane with a
- * NULL framebuffer parameter.  We call the driver's modeset handler with a NULL
- * framebuffer to disable the CRTC if no other planes are currently enabled.
- * If other planes are still enabled on the same CRTC, we return -EBUSY.
+ * NULL framebuffer parameter.  It unconditionally fails the disable call with
+ * -EINVAL the only way to disable the primary plane without driver support is
+ * to disable the entier CRTC. Which does not match the plane ->disable hook.
  *
  * Note that some hardware may be able to disable the primary plane without
  * disabling the whole CRTC.  Drivers for such hardware should provide their
@@ -214,34 +214,11 @@
  * disabled primary plane).
  *
  * RETURNS:
- * Zero on success, error code on failure
+ * Unconditionally returns -EINVAL.
  */
 int drm_primary_helper_disable(struct drm_plane *plane)
 {
-	struct drm_plane *p;
-	struct drm_mode_set set = {
-		.crtc = plane->crtc,
-		.fb = NULL,
-	};
-
-	if (plane->crtc == NULL || plane->fb == NULL)
-		/* Already disabled */
-		return 0;
-
-	list_for_each_entry(p, &plane->dev->mode_config.plane_list, head)
-		if (p != plane && p->fb) {
-			DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n");
-			return -EBUSY;
-		}
-
-	/*
-	 * N.B.  We call set_config() directly here rather than
-	 * drm_mode_set_config_internal() since drm_mode_setplane() already
-	 * handles the basic refcounting and we don't need the special
-	 * cross-CRTC refcounting (no chance of stealing connectors from
-	 * other CRTC's with this update).
-	 */
-	return plane->crtc->funcs->set_config(&set);
+	return -EINVAL;
 }
 EXPORT_SYMBOL(drm_primary_helper_disable);
 
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
new file mode 100644
index 0000000..e70f54d
--- /dev/null
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2006-2008 Intel Corporation
+ * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
+ *
+ * DRM core CRTC related functions
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Authors:
+ *      Keith Packard
+ *	Eric Anholt <eric@anholt.net>
+ *      Dave Airlie <airlied@linux.ie>
+ *      Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/export.h>
+#include <linux/moduleparam.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_edid.h>
+
+/**
+ * DOC: output probing helper overview
+ *
+ * This library provides some helper code for output probing. It provides an
+ * implementation of the core connector->fill_modes interface with
+ * drm_helper_probe_single_connector_modes.
+ *
+ * It also provides support for polling connectors with a work item and for
+ * generic hotplug interrupt handling where the driver doesn't or cannot keep
+ * track of a per-connector hpd interrupt.
+ *
+ * This helper library can be used independently of the modeset helper library.
+ * Drivers can also overwrite different parts e.g. use their own hotplug
+ * handling code to avoid probing unrelated outputs.
+ */
+
+static bool drm_kms_helper_poll = true;
+module_param_named(poll, drm_kms_helper_poll, bool, 0600);
+
+static void drm_mode_validate_flag(struct drm_connector *connector,
+				   int flags)
+{
+	struct drm_display_mode *mode;
+
+	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
+		      DRM_MODE_FLAG_3D_MASK))
+		return;
+
+	list_for_each_entry(mode, &connector->modes, head) {
+		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+				!(flags & DRM_MODE_FLAG_INTERLACE))
+			mode->status = MODE_NO_INTERLACE;
+		if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+				!(flags & DRM_MODE_FLAG_DBLSCAN))
+			mode->status = MODE_NO_DBLESCAN;
+		if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
+				!(flags & DRM_MODE_FLAG_3D_MASK))
+			mode->status = MODE_NO_STEREO;
+	}
+
+	return;
+}
+
+/**
+ * drm_helper_probe_single_connector_modes - get complete set of display modes
+ * @connector: connector to probe
+ * @maxX: max width for modes
+ * @maxY: max height for modes
+ *
+ * Based on the helper callbacks implemented by @connector try to detect all
+ * valid modes.  Modes will first be added to the connector's probed_modes list,
+ * then culled (based on validity and the @maxX, @maxY parameters) and put into
+ * the normal modes list.
+ *
+ * Intended to be use as a generic implementation of the ->fill_modes()
+ * @connector vfunc for drivers that use the crtc helpers for output mode
+ * filtering and detection.
+ *
+ * Returns:
+ * The number of modes found on @connector.
+ */
+int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
+					    uint32_t maxX, uint32_t maxY)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_mode *mode;
+	struct drm_connector_helper_funcs *connector_funcs =
+		connector->helper_private;
+	int count = 0;
+	int mode_flags = 0;
+	bool verbose_prune = true;
+
+	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
+			drm_get_connector_name(connector));
+	/* set all modes to the unverified state */
+	list_for_each_entry(mode, &connector->modes, head)
+		mode->status = MODE_UNVERIFIED;
+
+	if (connector->force) {
+		if (connector->force == DRM_FORCE_ON)
+			connector->status = connector_status_connected;
+		else
+			connector->status = connector_status_disconnected;
+		if (connector->funcs->force)
+			connector->funcs->force(connector);
+	} else {
+		connector->status = connector->funcs->detect(connector, true);
+	}
+
+	/* Re-enable polling in case the global poll config changed. */
+	if (drm_kms_helper_poll != dev->mode_config.poll_running)
+		drm_kms_helper_poll_enable(dev);
+
+	dev->mode_config.poll_running = drm_kms_helper_poll;
+
+	if (connector->status == connector_status_disconnected) {
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
+			connector->base.id, drm_get_connector_name(connector));
+		drm_mode_connector_update_edid_property(connector, NULL);
+		verbose_prune = false;
+		goto prune;
+	}
+
+#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
+	count = drm_load_edid_firmware(connector);
+	if (count == 0)
+#endif
+		count = (*connector_funcs->get_modes)(connector);
+
+	if (count == 0 && connector->status == connector_status_connected)
+		count = drm_add_modes_noedid(connector, 1024, 768);
+	if (count == 0)
+		goto prune;
+
+	drm_mode_connector_list_update(connector);
+
+	if (maxX && maxY)
+		drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
+
+	if (connector->interlace_allowed)
+		mode_flags |= DRM_MODE_FLAG_INTERLACE;
+	if (connector->doublescan_allowed)
+		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
+	if (connector->stereo_allowed)
+		mode_flags |= DRM_MODE_FLAG_3D_MASK;
+	drm_mode_validate_flag(connector, mode_flags);
+
+	list_for_each_entry(mode, &connector->modes, head) {
+		if (mode->status == MODE_OK)
+			mode->status = connector_funcs->mode_valid(connector,
+								   mode);
+	}
+
+prune:
+	drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
+
+	if (list_empty(&connector->modes))
+		return 0;
+
+	list_for_each_entry(mode, &connector->modes, head)
+		mode->vrefresh = drm_mode_vrefresh(mode);
+
+	drm_mode_sort(&connector->modes);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
+			drm_get_connector_name(connector));
+	list_for_each_entry(mode, &connector->modes, head) {
+		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+		drm_mode_debug_printmodeline(mode);
+	}
+
+	return count;
+}
+EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
+
+/**
+ * drm_kms_helper_hotplug_event - fire off KMS hotplug events
+ * @dev: drm_device whose connector state changed
+ *
+ * This function fires off the uevent for userspace and also calls the
+ * output_poll_changed function, which is most commonly used to inform the fbdev
+ * emulation code and allow it to update the fbcon output configuration.
+ *
+ * Drivers should call this from their hotplug handling code when a change is
+ * detected. Note that this function does not do any output detection of its
+ * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
+ * driver already.
+ *
+ * This function must be called from process context with no mode
+ * setting locks held.
+ */
+void drm_kms_helper_hotplug_event(struct drm_device *dev)
+{
+	/* send a uevent + call fbdev */
+	drm_sysfs_hotplug_event(dev);
+	if (dev->mode_config.funcs->output_poll_changed)
+		dev->mode_config.funcs->output_poll_changed(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
+
+#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
+static void output_poll_execute(struct work_struct *work)
+{
+	struct delayed_work *delayed_work = to_delayed_work(work);
+	struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
+	struct drm_connector *connector;
+	enum drm_connector_status old_status;
+	bool repoll = false, changed = false;
+
+	if (!drm_kms_helper_poll)
+		return;
+
+	mutex_lock(&dev->mode_config.mutex);
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+
+		/* Ignore forced connectors. */
+		if (connector->force)
+			continue;
+
+		/* Ignore HPD capable connectors and connectors where we don't
+		 * want any hotplug detection at all for polling. */
+		if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
+			continue;
+
+		repoll = true;
+
+		old_status = connector->status;
+		/* if we are connected and don't want to poll for disconnect
+		   skip it */
+		if (old_status == connector_status_connected &&
+		    !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
+			continue;
+
+		connector->status = connector->funcs->detect(connector, false);
+		if (old_status != connector->status) {
+			const char *old, *new;
+
+			old = drm_get_connector_status_name(old_status);
+			new = drm_get_connector_status_name(connector->status);
+
+			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
+				      "status updated from %s to %s\n",
+				      connector->base.id,
+				      drm_get_connector_name(connector),
+				      old, new);
+
+			changed = true;
+		}
+	}
+
+	mutex_unlock(&dev->mode_config.mutex);
+
+	if (changed)
+		drm_kms_helper_hotplug_event(dev);
+
+	if (repoll)
+		schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
+}
+
+/**
+ * drm_kms_helper_poll_disable - disable output polling
+ * @dev: drm_device
+ *
+ * This function disables the output polling work.
+ *
+ * Drivers can call this helper from their device suspend implementation. It is
+ * not an error to call this even when output polling isn't enabled or arlready
+ * disabled.
+ */
+void drm_kms_helper_poll_disable(struct drm_device *dev)
+{
+	if (!dev->mode_config.poll_enabled)
+		return;
+	cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_disable);
+
+/**
+ * drm_kms_helper_poll_enable - re-enable output polling.
+ * @dev: drm_device
+ *
+ * This function re-enables the output polling work.
+ *
+ * Drivers can call this helper from their device resume implementation. It is
+ * an error to call this when the output polling support has not yet been set
+ * up.
+ */
+void drm_kms_helper_poll_enable(struct drm_device *dev)
+{
+	bool poll = false;
+	struct drm_connector *connector;
+
+	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
+		return;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
+					 DRM_CONNECTOR_POLL_DISCONNECT))
+			poll = true;
+	}
+
+	if (poll)
+		schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_enable);
+
+/**
+ * drm_kms_helper_poll_init - initialize and enable output polling
+ * @dev: drm_device
+ *
+ * This function intializes and then also enables output polling support for
+ * @dev. Drivers which do not have reliable hotplug support in hardware can use
+ * this helper infrastructure to regularly poll such connectors for changes in
+ * their connection state.
+ *
+ * Drivers can control which connectors are polled by setting the
+ * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On
+ * connectors where probing live outputs can result in visual distortion drivers
+ * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this.
+ * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are
+ * completely ignored by the polling logic.
+ *
+ * Note that a connector can be both polled and probed from the hotplug handler,
+ * in case the hotplug interrupt is known to be unreliable.
+ */
+void drm_kms_helper_poll_init(struct drm_device *dev)
+{
+	INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
+	dev->mode_config.poll_enabled = true;
+
+	drm_kms_helper_poll_enable(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_init);
+
+/**
+ * drm_kms_helper_poll_fini - disable output polling and clean it up
+ * @dev: drm_device
+ */
+void drm_kms_helper_poll_fini(struct drm_device *dev)
+{
+	drm_kms_helper_poll_disable(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_fini);
+
+/**
+ * drm_helper_hpd_irq_event - hotplug processing
+ * @dev: drm_device
+ *
+ * Drivers can use this helper function to run a detect cycle on all connectors
+ * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All
+ * other connectors are ignored, which is useful to avoid reprobing fixed
+ * panels.
+ *
+ * This helper function is useful for drivers which can't or don't track hotplug
+ * interrupts for each connector.
+ *
+ * Drivers which support hotplug interrupts for each connector individually and
+ * which have a more fine-grained detect logic should bypass this code and
+ * directly call drm_kms_helper_hotplug_event() in case the connector state
+ * changed.
+ *
+ * This function must be called from process context with no mode
+ * setting locks held.
+ *
+ * Note that a connector can be both polled and probed from the hotplug handler,
+ * in case the hotplug interrupt is known to be unreliable.
+ */
+bool drm_helper_hpd_irq_event(struct drm_device *dev)
+{
+	struct drm_connector *connector;
+	enum drm_connector_status old_status;
+	bool changed = false;
+
+	if (!dev->mode_config.poll_enabled)
+		return false;
+
+	mutex_lock(&dev->mode_config.mutex);
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+
+		/* Only handle HPD capable connectors. */
+		if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
+			continue;
+
+		old_status = connector->status;
+
+		connector->status = connector->funcs->detect(connector, false);
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
+			      connector->base.id,
+			      drm_get_connector_name(connector),
+			      drm_get_connector_status_name(old_status),
+			      drm_get_connector_status_name(connector->status));
+		if (old_status != connector->status)
+			changed = true;
+	}
+
+	mutex_unlock(&dev->mode_config.mutex);
+
+	if (changed)
+		drm_kms_helper_hotplug_event(dev);
+
+	return changed;
+}
+EXPORT_SYMBOL(drm_helper_hpd_irq_event);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0905cd9..ec82f6b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1308,6 +1308,7 @@
 
 	struct {
 		u16 pwm_freq_hz;
+		bool present;
 		bool active_low_pwm;
 	} backlight;
 
@@ -2431,20 +2432,18 @@
 int i915_gem_context_enable(struct drm_i915_private *dev_priv);
 void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
 int i915_switch_context(struct intel_ring_buffer *ring,
-			struct drm_file *file, struct i915_hw_context *to);
+			struct i915_hw_context *to);
 struct i915_hw_context *
 i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
 void i915_gem_context_free(struct kref *ctx_ref);
 static inline void i915_gem_context_reference(struct i915_hw_context *ctx)
 {
-	if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
-		kref_get(&ctx->ref);
+	kref_get(&ctx->ref);
 }
 
 static inline void i915_gem_context_unreference(struct i915_hw_context *ctx)
 {
-	if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
-		kref_put(&ctx->ref, i915_gem_context_free);
+	kref_put(&ctx->ref, i915_gem_context_free);
 }
 
 static inline bool i915_gem_context_is_default(const struct i915_hw_context *c)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6370a76..2871ce7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2790,7 +2790,7 @@
 
 	/* Flush everything onto the inactive list. */
 	for_each_ring(ring, dev_priv, i) {
-		ret = i915_switch_context(ring, NULL, ring->default_context);
+		ret = i915_switch_context(ring, ring->default_context);
 		if (ret)
 			return ret;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 6043062..d72db15 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -96,9 +96,6 @@
 #define GEN6_CONTEXT_ALIGN (64<<10)
 #define GEN7_CONTEXT_ALIGN 4096
 
-static int do_switch(struct intel_ring_buffer *ring,
-		     struct i915_hw_context *to);
-
 static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
 {
 	struct drm_device *dev = ppgtt->base.dev;
@@ -185,13 +182,15 @@
 						   typeof(*ctx), ref);
 	struct i915_hw_ppgtt *ppgtt = NULL;
 
-	/* We refcount even the aliasing PPGTT to keep the code symmetric */
-	if (USES_PPGTT(ctx->obj->base.dev))
-		ppgtt = ctx_to_ppgtt(ctx);
+	if (ctx->obj) {
+		/* We refcount even the aliasing PPGTT to keep the code symmetric */
+		if (USES_PPGTT(ctx->obj->base.dev))
+			ppgtt = ctx_to_ppgtt(ctx);
 
-	/* XXX: Free up the object before tearing down the address space, in
-	 * case we're bound in the PPGTT */
-	drm_gem_object_unreference(&ctx->obj->base);
+		/* XXX: Free up the object before tearing down the address space, in
+		 * case we're bound in the PPGTT */
+		drm_gem_object_unreference(&ctx->obj->base);
+	}
 
 	if (ppgtt)
 		kref_put(&ppgtt->ref, ppgtt_release);
@@ -232,32 +231,32 @@
 		return ERR_PTR(-ENOMEM);
 
 	kref_init(&ctx->ref);
-	ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
-	INIT_LIST_HEAD(&ctx->link);
-	if (ctx->obj == NULL) {
-		kfree(ctx);
-		DRM_DEBUG_DRIVER("Context object allocated failed\n");
-		return ERR_PTR(-ENOMEM);
-	}
-
-	if (INTEL_INFO(dev)->gen >= 7) {
-		ret = i915_gem_object_set_cache_level(ctx->obj,
-						      I915_CACHE_L3_LLC);
-		/* Failure shouldn't ever happen this early */
-		if (WARN_ON(ret))
-			goto err_out;
-	}
-
 	list_add_tail(&ctx->link, &dev_priv->context_list);
 
-	/* Default context will never have a file_priv */
-	if (file_priv == NULL)
-		return ctx;
+	if (dev_priv->hw_context_size) {
+		ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
+		if (ctx->obj == NULL) {
+			ret = -ENOMEM;
+			goto err_out;
+		}
 
-	ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID, 0,
-			GFP_KERNEL);
-	if (ret < 0)
-		goto err_out;
+		if (INTEL_INFO(dev)->gen >= 7) {
+			ret = i915_gem_object_set_cache_level(ctx->obj,
+							      I915_CACHE_L3_LLC);
+			/* Failure shouldn't ever happen this early */
+			if (WARN_ON(ret))
+				goto err_out;
+		}
+	}
+
+	/* Default context will never have a file_priv */
+	if (file_priv != NULL) {
+		ret = idr_alloc(&file_priv->context_idr, ctx,
+				DEFAULT_CONTEXT_ID, 0, GFP_KERNEL);
+		if (ret < 0)
+			goto err_out;
+	} else
+		ret = DEFAULT_CONTEXT_ID;
 
 	ctx->file_priv = file_priv;
 	ctx->id = ret;
@@ -294,7 +293,7 @@
 	if (IS_ERR(ctx))
 		return ctx;
 
-	if (is_global_default_ctx) {
+	if (is_global_default_ctx && ctx->obj) {
 		/* We may need to do things with the shrinker which
 		 * require us to immediately switch back to the default
 		 * context. This can cause a problem as pinning the
@@ -342,7 +341,7 @@
 	return ctx;
 
 err_unpin:
-	if (is_global_default_ctx)
+	if (is_global_default_ctx && ctx->obj)
 		i915_gem_object_ggtt_unpin(ctx->obj);
 err_destroy:
 	i915_gem_context_unreference(ctx);
@@ -352,32 +351,22 @@
 void i915_gem_context_reset(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_ring_buffer *ring;
 	int i;
 
-	if (!HAS_HW_CONTEXTS(dev))
-		return;
-
 	/* Prevent the hardware from restoring the last context (which hung) on
 	 * the next switch */
 	for (i = 0; i < I915_NUM_RINGS; i++) {
-		struct i915_hw_context *dctx;
-		if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
-			continue;
+		struct intel_ring_buffer *ring = &dev_priv->ring[i];
+		struct i915_hw_context *dctx = ring->default_context;
 
 		/* Do a fake switch to the default context */
-		ring = &dev_priv->ring[i];
-		dctx = ring->default_context;
-		if (WARN_ON(!dctx))
+		if (ring->last_context == dctx)
 			continue;
 
 		if (!ring->last_context)
 			continue;
 
-		if (ring->last_context == dctx)
-			continue;
-
-		if (i == RCS) {
+		if (dctx->obj && i == RCS) {
 			WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
 						      get_context_alignment(dev), 0));
 			/* Fake a finish/inactive */
@@ -394,44 +383,35 @@
 int i915_gem_context_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_ring_buffer *ring;
+	struct i915_hw_context *ctx;
 	int i;
 
-	if (!HAS_HW_CONTEXTS(dev))
-		return 0;
-
 	/* Init should only be called once per module load. Eventually the
 	 * restriction on the context_disabled check can be loosened. */
 	if (WARN_ON(dev_priv->ring[RCS].default_context))
 		return 0;
 
-	dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
-
-	if (dev_priv->hw_context_size > (1<<20)) {
-		DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n");
-		return -E2BIG;
+	if (HAS_HW_CONTEXTS(dev)) {
+		dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
+		if (dev_priv->hw_context_size > (1<<20)) {
+			DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n",
+					 dev_priv->hw_context_size);
+			dev_priv->hw_context_size = 0;
+		}
 	}
 
-	dev_priv->ring[RCS].default_context =
-		i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
-
-	if (IS_ERR_OR_NULL(dev_priv->ring[RCS].default_context)) {
-		DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %ld\n",
-				 PTR_ERR(dev_priv->ring[RCS].default_context));
-		return PTR_ERR(dev_priv->ring[RCS].default_context);
+	ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
+	if (IS_ERR(ctx)) {
+		DRM_ERROR("Failed to create default global context (error %ld)\n",
+			  PTR_ERR(ctx));
+		return PTR_ERR(ctx);
 	}
 
-	for (i = RCS + 1; i < I915_NUM_RINGS; i++) {
-		if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
-			continue;
+	/* NB: RCS will hold a ref for all rings */
+	for (i = 0; i < I915_NUM_RINGS; i++)
+		dev_priv->ring[i].default_context = ctx;
 
-		ring = &dev_priv->ring[i];
-
-		/* NB: RCS will hold a ref for all rings */
-		ring->default_context = dev_priv->ring[RCS].default_context;
-	}
-
-	DRM_DEBUG_DRIVER("HW context support initialized\n");
+	DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake");
 	return 0;
 }
 
@@ -441,33 +421,30 @@
 	struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context;
 	int i;
 
-	if (!HAS_HW_CONTEXTS(dev))
-		return;
+	if (dctx->obj) {
+		/* The only known way to stop the gpu from accessing the hw context is
+		 * to reset it. Do this as the very last operation to avoid confusing
+		 * other code, leading to spurious errors. */
+		intel_gpu_reset(dev);
 
-	/* The only known way to stop the gpu from accessing the hw context is
-	 * to reset it. Do this as the very last operation to avoid confusing
-	 * other code, leading to spurious errors. */
-	intel_gpu_reset(dev);
-
-	/* When default context is created and switched to, base object refcount
-	 * will be 2 (+1 from object creation and +1 from do_switch()).
-	 * i915_gem_context_fini() will be called after gpu_idle() has switched
-	 * to default context. So we need to unreference the base object once
-	 * to offset the do_switch part, so that i915_gem_context_unreference()
-	 * can then free the base object correctly. */
-	WARN_ON(!dev_priv->ring[RCS].last_context);
-	if (dev_priv->ring[RCS].last_context == dctx) {
-		/* Fake switch to NULL context */
-		WARN_ON(dctx->obj->active);
-		i915_gem_object_ggtt_unpin(dctx->obj);
-		i915_gem_context_unreference(dctx);
-		dev_priv->ring[RCS].last_context = NULL;
+		/* When default context is created and switched to, base object refcount
+		 * will be 2 (+1 from object creation and +1 from do_switch()).
+		 * i915_gem_context_fini() will be called after gpu_idle() has switched
+		 * to default context. So we need to unreference the base object once
+		 * to offset the do_switch part, so that i915_gem_context_unreference()
+		 * can then free the base object correctly. */
+		WARN_ON(!dev_priv->ring[RCS].last_context);
+		if (dev_priv->ring[RCS].last_context == dctx) {
+			/* Fake switch to NULL context */
+			WARN_ON(dctx->obj->active);
+			i915_gem_object_ggtt_unpin(dctx->obj);
+			i915_gem_context_unreference(dctx);
+			dev_priv->ring[RCS].last_context = NULL;
+		}
 	}
 
 	for (i = 0; i < I915_NUM_RINGS; i++) {
 		struct intel_ring_buffer *ring = &dev_priv->ring[i];
-		if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
-			continue;
 
 		if (ring->last_context)
 			i915_gem_context_unreference(ring->last_context);
@@ -478,7 +455,6 @@
 
 	i915_gem_object_ggtt_unpin(dctx->obj);
 	i915_gem_context_unreference(dctx);
-	dev_priv->mm.aliasing_ppgtt = NULL;
 }
 
 int i915_gem_context_enable(struct drm_i915_private *dev_priv)
@@ -486,9 +462,6 @@
 	struct intel_ring_buffer *ring;
 	int ret, i;
 
-	if (!HAS_HW_CONTEXTS(dev_priv->dev))
-		return 0;
-
 	/* This is the only place the aliasing PPGTT gets enabled, which means
 	 * it has to happen before we bail on reset */
 	if (dev_priv->mm.aliasing_ppgtt) {
@@ -503,7 +476,7 @@
 	BUG_ON(!dev_priv->ring[RCS].default_context);
 
 	for_each_ring(ring, dev_priv, i) {
-		ret = do_switch(ring, ring->default_context);
+		ret = i915_switch_context(ring, ring->default_context);
 		if (ret)
 			return ret;
 	}
@@ -526,19 +499,6 @@
 int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
 {
 	struct drm_i915_file_private *file_priv = file->driver_priv;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (!HAS_HW_CONTEXTS(dev)) {
-		/* Cheat for hang stats */
-		file_priv->private_default_ctx =
-			kzalloc(sizeof(struct i915_hw_context), GFP_KERNEL);
-
-		if (file_priv->private_default_ctx == NULL)
-			return -ENOMEM;
-
-		file_priv->private_default_ctx->vm = &dev_priv->gtt.base;
-		return 0;
-	}
 
 	idr_init(&file_priv->context_idr);
 
@@ -559,14 +519,10 @@
 {
 	struct drm_i915_file_private *file_priv = file->driver_priv;
 
-	if (!HAS_HW_CONTEXTS(dev)) {
-		kfree(file_priv->private_default_ctx);
-		return;
-	}
-
 	idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
-	i915_gem_context_unreference(file_priv->private_default_ctx);
 	idr_destroy(&file_priv->context_idr);
+
+	i915_gem_context_unreference(file_priv->private_default_ctx);
 }
 
 struct i915_hw_context *
@@ -574,9 +530,6 @@
 {
 	struct i915_hw_context *ctx;
 
-	if (!HAS_HW_CONTEXTS(file_priv->dev_priv->dev))
-		return file_priv->private_default_ctx;
-
 	ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id);
 	if (!ctx)
 		return ERR_PTR(-ENOENT);
@@ -758,7 +711,6 @@
 /**
  * i915_switch_context() - perform a GPU context switch.
  * @ring: ring for which we'll execute the context switch
- * @file_priv: file_priv associated with the context, may be NULL
  * @to: the context to switch to
  *
  * The context life cycle is simple. The context refcount is incremented and
@@ -767,24 +719,30 @@
  * object while letting the normal object tracking destroy the backing BO.
  */
 int i915_switch_context(struct intel_ring_buffer *ring,
-			struct drm_file *file,
 			struct i915_hw_context *to)
 {
 	struct drm_i915_private *dev_priv = ring->dev->dev_private;
 
 	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
 
-	BUG_ON(file && to == NULL);
-
-	/* We have the fake context */
-	if (!HAS_HW_CONTEXTS(ring->dev)) {
-		ring->last_context = to;
+	if (to->obj == NULL) { /* We have the fake context */
+		if (to != ring->last_context) {
+			i915_gem_context_reference(to);
+			if (ring->last_context)
+				i915_gem_context_unreference(ring->last_context);
+			ring->last_context = to;
+		}
 		return 0;
 	}
 
 	return do_switch(ring, to);
 }
 
+static bool hw_context_enabled(struct drm_device *dev)
+{
+	return to_i915(dev)->hw_context_size;
+}
+
 int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 				  struct drm_file *file)
 {
@@ -793,7 +751,7 @@
 	struct i915_hw_context *ctx;
 	int ret;
 
-	if (!HAS_HW_CONTEXTS(dev))
+	if (!hw_context_enabled(dev))
 		return -ENODEV;
 
 	ret = i915_mutex_lock_interruptible(dev);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7447160..2c9d9cb 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1221,7 +1221,7 @@
 	if (ret)
 		goto err;
 
-	ret = i915_switch_context(ring, file, ctx);
+	ret = i915_switch_context(ring, ctx);
 	if (ret)
 		goto err;
 
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4867f4c..fa486c5 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -287,6 +287,9 @@
 	const struct bdb_lfp_backlight_data *backlight_data;
 	const struct bdb_lfp_backlight_data_entry *entry;
 
+	/* Err to enabling backlight if no backlight block. */
+	dev_priv->vbt.backlight.present = true;
+
 	backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
 	if (!backlight_data)
 		return;
@@ -299,6 +302,13 @@
 
 	entry = &backlight_data->data[panel_type];
 
+	dev_priv->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
+	if (!dev_priv->vbt.backlight.present) {
+		DRM_DEBUG_KMS("PWM backlight not present in VBT (type %u)\n",
+			      entry->type);
+		return;
+	}
+
 	dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
 	dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
 	DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, "
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 83b7629..f27f7b2 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -374,6 +374,9 @@
 	struct bdb_lvds_lfp_data_entry data[16];
 } __packed;
 
+#define BDB_BACKLIGHT_TYPE_NONE	0
+#define BDB_BACKLIGHT_TYPE_PWM	2
+
 struct bdb_lfp_backlight_data_entry {
 	u8 type:2;
 	u8 active_low_pwm:1;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a0dad1a..d2a5588 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -575,7 +575,8 @@
 	return ret;
 }
 
-#define HEADER_SIZE	4
+#define BARE_ADDRESS_SIZE	3
+#define HEADER_SIZE		(BARE_ADDRESS_SIZE + 1)
 static ssize_t
 intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 {
@@ -592,7 +593,7 @@
 	switch (msg->request & ~DP_AUX_I2C_MOT) {
 	case DP_AUX_NATIVE_WRITE:
 	case DP_AUX_I2C_WRITE:
-		txsize = HEADER_SIZE + msg->size;
+		txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE;
 		rxsize = 1;
 
 		if (WARN_ON(txsize > 20))
@@ -611,7 +612,7 @@
 
 	case DP_AUX_NATIVE_READ:
 	case DP_AUX_I2C_READ:
-		txsize = HEADER_SIZE;
+		txsize = msg->size ? HEADER_SIZE : BARE_ADDRESS_SIZE;
 		rxsize = msg->size + 1;
 
 		if (WARN_ON(rxsize > 20))
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index cb05840..0eead16 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1065,6 +1065,11 @@
 	unsigned long flags;
 	int ret;
 
+	if (!dev_priv->vbt.backlight.present) {
+		DRM_DEBUG_KMS("native backlight control not available per VBT\n");
+		return 0;
+	}
+
 	/* set level and max in panel struct */
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 	ret = dev_priv->display.setup_backlight(intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5874716..19e94c3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1545,6 +1545,16 @@
 
 	DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
 
+	if (IS_I915GM(dev) && enabled) {
+		struct intel_framebuffer *fb;
+
+		fb = to_intel_framebuffer(enabled->primary->fb);
+
+		/* self-refresh seems busted with untiled */
+		if (fb->obj->tiling_mode == I915_TILING_NONE)
+			enabled = NULL;
+	}
+
 	/*
 	 * Overlay gets an aggressive default since video jitter is bad.
 	 */
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index e9df94f..fb0b6b2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -109,7 +109,7 @@
 			return;
 		}
 
-		addr = (u64)(addr >> 8) << 8;
+		addr = (addr & 0xffffff00) << 8;
 		if (!addr) {
 			addr  = (u64)nv_rd32(bios, 0x001700) << 16;
 			addr += 0xf0000;
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 355157e..e3c47a8 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -33,6 +33,7 @@
 	int pipe;
 	enum omap_channel channel;
 	struct omap_overlay_manager_info info;
+	struct drm_encoder *current_encoder;
 
 	/*
 	 * Temporary: eventually this will go away, but it is needed
@@ -120,13 +121,25 @@
 {
 }
 
+static void set_enabled(struct drm_crtc *crtc, bool enable);
+
 static int omap_crtc_enable(struct omap_overlay_manager *mgr)
 {
+	struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
+
+	dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
+	dispc_mgr_set_timings(omap_crtc->channel,
+			&omap_crtc->timings);
+	set_enabled(&omap_crtc->base, true);
+
 	return 0;
 }
 
 static void omap_crtc_disable(struct omap_overlay_manager *mgr)
 {
+	struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
+
+	set_enabled(&omap_crtc->base, false);
 }
 
 static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
@@ -184,7 +197,6 @@
 	WARN_ON(omap_crtc->apply_irq.registered);
 	omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
 
-	omap_crtc->plane->funcs->destroy(omap_crtc->plane);
 	drm_crtc_cleanup(crtc);
 
 	kfree(omap_crtc);
@@ -338,17 +350,23 @@
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	struct drm_plane *primary = crtc->primary;
 	struct drm_gem_object *bo;
+	unsigned long flags;
 
 	DBG("%d -> %d (event=%p)", primary->fb ? primary->fb->base.id : -1,
 			fb->base.id, event);
 
+	spin_lock_irqsave(&dev->event_lock, flags);
+
 	if (omap_crtc->old_fb) {
+		spin_unlock_irqrestore(&dev->event_lock, flags);
 		dev_err(dev->dev, "already a pending flip\n");
 		return -EINVAL;
 	}
 
 	omap_crtc->event = event;
-	primary->fb = fb;
+	omap_crtc->old_fb = primary->fb = fb;
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
 
 	/*
 	 * Hold a reference temporarily until the crtc is updated
@@ -528,38 +546,46 @@
 	struct drm_device *dev = crtc->dev;
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	enum omap_channel channel = omap_crtc->channel;
-	struct omap_irq_wait *wait = NULL;
+	struct omap_irq_wait *wait;
+	u32 framedone_irq, vsync_irq;
+	int ret;
 
 	if (dispc_mgr_is_enabled(channel) == enable)
 		return;
 
-	/* ignore sync-lost irqs during enable/disable */
+	/*
+	 * Digit output produces some sync lost interrupts during the first
+	 * frame when enabling, so we need to ignore those.
+	 */
 	omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
 
-	if (dispc_mgr_get_framedone_irq(channel)) {
-		if (!enable) {
-			wait = omap_irq_wait_init(dev,
-					dispc_mgr_get_framedone_irq(channel), 1);
-		}
+	framedone_irq = dispc_mgr_get_framedone_irq(channel);
+	vsync_irq = dispc_mgr_get_vsync_irq(channel);
+
+	if (enable) {
+		wait = omap_irq_wait_init(dev, vsync_irq, 1);
 	} else {
 		/*
-		 * When we disable digit output, we need to wait until fields
-		 * are done.  Otherwise the DSS is still working, and turning
-		 * off the clocks prevents DSS from going to OFF mode. And when
-		 * enabling, we need to wait for the extra sync losts
+		 * When we disable the digit output, we need to wait for
+		 * FRAMEDONE to know that DISPC has finished with the output.
+		 *
+		 * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
+		 * that case we need to use vsync interrupt, and wait for both
+		 * even and odd frames.
 		 */
-		wait = omap_irq_wait_init(dev,
-				dispc_mgr_get_vsync_irq(channel), 2);
+
+		if (framedone_irq)
+			wait = omap_irq_wait_init(dev, framedone_irq, 1);
+		else
+			wait = omap_irq_wait_init(dev, vsync_irq, 2);
 	}
 
 	dispc_mgr_enable(channel, enable);
 
-	if (wait) {
-		int ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
-		if (ret) {
-			dev_err(dev->dev, "%s: timeout waiting for %s\n",
-					omap_crtc->name, enable ? "enable" : "disable");
-		}
+	ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
+	if (ret) {
+		dev_err(dev->dev, "%s: timeout waiting for %s\n",
+				omap_crtc->name, enable ? "enable" : "disable");
 	}
 
 	omap_irq_register(crtc->dev, &omap_crtc->error_irq);
@@ -586,8 +612,12 @@
 		}
 	}
 
+	if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder)
+		omap_encoder_set_enabled(omap_crtc->current_encoder, false);
+
+	omap_crtc->current_encoder = encoder;
+
 	if (!omap_crtc->enabled) {
-		set_enabled(&omap_crtc->base, false);
 		if (encoder)
 			omap_encoder_set_enabled(encoder, false);
 	} else {
@@ -596,13 +626,7 @@
 			omap_encoder_update(encoder, omap_crtc->mgr,
 					&omap_crtc->timings);
 			omap_encoder_set_enabled(encoder, true);
-			omap_crtc->full_update = false;
 		}
-
-		dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
-		dispc_mgr_set_timings(omap_crtc->channel,
-				&omap_crtc->timings);
-		set_enabled(&omap_crtc->base, true);
 	}
 
 	omap_crtc->full_update = false;
@@ -613,10 +637,30 @@
 	/* nothing needed for post-apply */
 }
 
+void omap_crtc_flush(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	int loops = 0;
+
+	while (!list_empty(&omap_crtc->pending_applies) ||
+		!list_empty(&omap_crtc->queued_applies) ||
+		omap_crtc->event || omap_crtc->old_fb) {
+
+		if (++loops > 10) {
+			dev_err(crtc->dev->dev,
+				"omap_crtc_flush() timeout\n");
+			break;
+		}
+
+		schedule_timeout_uninterruptible(msecs_to_jiffies(20));
+	}
+}
+
 static const char *channel_names[] = {
 		[OMAP_DSS_CHANNEL_LCD] = "lcd",
 		[OMAP_DSS_CHANNEL_DIGIT] = "tv",
 		[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
+		[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
 };
 
 void omap_crtc_pre_init(void)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index bf39fcc..c8270e4 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -513,12 +513,18 @@
 static int dev_unload(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
+	int i;
 
 	DBG("unload: dev=%p", dev);
 
 	drm_kms_helper_poll_fini(dev);
 
 	omap_fbdev_free(dev);
+
+	/* flush crtcs so the fbs get released */
+	for (i = 0; i < priv->num_crtcs; i++)
+		omap_crtc_flush(priv->crtcs[i]);
+
 	omap_modeset_free(dev);
 	omap_gem_deinit(dev);
 
@@ -696,10 +702,11 @@
 {
 	DBG("");
 
+	drm_put_dev(platform_get_drvdata(device));
+
 	omap_disconnect_dssdevs();
 	omap_crtc_pre_uninit();
 
-	drm_put_dev(platform_get_drvdata(device));
 	return 0;
 }
 
@@ -726,18 +733,33 @@
 
 static int __init omap_drm_init(void)
 {
+	int r;
+
 	DBG("init");
-	if (platform_driver_register(&omap_dmm_driver)) {
-		/* we can continue on without DMM.. so not fatal */
-		dev_err(NULL, "DMM registration failed\n");
+
+	r = platform_driver_register(&omap_dmm_driver);
+	if (r) {
+		pr_err("DMM driver registration failed\n");
+		return r;
 	}
-	return platform_driver_register(&pdev);
+
+	r = platform_driver_register(&pdev);
+	if (r) {
+		pr_err("omapdrm driver registration failed\n");
+		platform_driver_unregister(&omap_dmm_driver);
+		return r;
+	}
+
+	return 0;
 }
 
 static void __exit omap_drm_fini(void)
 {
 	DBG("fini");
+
 	platform_driver_unregister(&pdev);
+
+	platform_driver_unregister(&omap_dmm_driver);
 }
 
 /* need late_initcall() so we load after dss_driver's are loaded */
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 428b2981..284b80f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -163,6 +163,7 @@
 void omap_crtc_pre_uninit(void);
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 		struct drm_plane *plane, enum omap_channel channel, int id);
+void omap_crtc_flush(struct drm_crtc *crtc);
 
 struct drm_plane *omap_plane_init(struct drm_device *dev,
 		int plane_id, bool private_plane);
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index d2b8c49..8b01960 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -218,6 +218,20 @@
 		info->rotation_type = OMAP_DSS_ROT_TILER;
 		info->screen_width  = omap_gem_tiled_stride(plane->bo, orient);
 	} else {
+		switch (win->rotation & 0xf) {
+		case 0:
+		case BIT(DRM_ROTATE_0):
+			/* OK */
+			break;
+
+		default:
+			dev_warn(fb->dev->dev,
+				"rotation '%d' ignored for non-tiled fb\n",
+				win->rotation);
+			win->rotation = 0;
+			break;
+		}
+
 		info->paddr         = get_linear_addr(plane, format, 0, x, y);
 		info->rotation_type = OMAP_DSS_ROT_DMA;
 		info->screen_width  = plane->pitch;
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 002988d..1388ca7 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -371,6 +371,9 @@
 
 	fbdev = to_omap_fbdev(priv->fbdev);
 
+	/* release the ref taken in omap_fbdev_create() */
+	omap_gem_put_paddr(fbdev->bo);
+
 	/* this will free the backing object */
 	if (fbdev->fb) {
 		drm_framebuffer_unregister_private(fbdev->fb);
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index c8d9727..95dbce2 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -980,12 +980,9 @@
 #ifdef CONFIG_DEBUG_FS
 void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
 {
-	struct drm_device *dev = obj->dev;
 	struct omap_gem_object *omap_obj = to_omap_bo(obj);
 	uint64_t off;
 
-	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
-
 	off = drm_vma_node_start(&obj->vma_node);
 
 	seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d",
@@ -1050,10 +1047,10 @@
 {
 	struct omap_gem_object *omap_obj = waiter->omap_obj;
 	if ((waiter->op & OMAP_GEM_READ) &&
-			(omap_obj->sync->read_complete < waiter->read_target))
+			(omap_obj->sync->write_complete < waiter->write_target))
 		return true;
 	if ((waiter->op & OMAP_GEM_WRITE) &&
-			(omap_obj->sync->write_complete < waiter->write_target))
+			(omap_obj->sync->read_complete < waiter->read_target))
 		return true;
 	return false;
 }
@@ -1229,6 +1226,8 @@
 		}
 
 		spin_unlock(&sync_lock);
+
+		kfree(waiter);
 	}
 
 	/* no waiting.. */
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 046d5e6..3cf31ee 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -225,6 +225,11 @@
 		omap_plane->apply_done_cb.arg = arg;
 	}
 
+	if (plane->fb)
+		drm_framebuffer_unreference(plane->fb);
+
+	drm_framebuffer_reference(fb);
+
 	plane->fb = fb;
 	plane->crtc = crtc;
 
@@ -241,10 +246,13 @@
 	struct omap_plane *omap_plane = to_omap_plane(plane);
 	omap_plane->enabled = true;
 
-	if (plane->fb)
-		drm_framebuffer_unreference(plane->fb);
-
-	drm_framebuffer_reference(fb);
+	/* omap_plane_mode_set() takes adjusted src */
+	switch (omap_plane->win.rotation & 0xf) {
+	case BIT(DRM_ROTATE_90):
+	case BIT(DRM_ROTATE_270):
+		swap(src_w, src_h);
+		break;
+	}
 
 	return omap_plane_mode_set(plane, crtc, fb,
 			crtc_x, crtc_y, crtc_w, crtc_h,
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 8b0ab17..1593652 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -142,7 +142,8 @@
 	return recv_bytes;
 }
 
-#define HEADER_SIZE 4
+#define BARE_ADDRESS_SIZE 3
+#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
 
 static ssize_t
 radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
@@ -160,13 +161,19 @@
 	tx_buf[0] = msg->address & 0xff;
 	tx_buf[1] = msg->address >> 8;
 	tx_buf[2] = msg->request << 4;
-	tx_buf[3] = msg->size - 1;
+	tx_buf[3] = msg->size ? (msg->size - 1) : 0;
 
 	switch (msg->request & ~DP_AUX_I2C_MOT) {
 	case DP_AUX_NATIVE_WRITE:
 	case DP_AUX_I2C_WRITE:
+		/* tx_size needs to be 4 even for bare address packets since the atom
+		 * table needs the info in tx_buf[3].
+		 */
 		tx_size = HEADER_SIZE + msg->size;
-		tx_buf[3] |= tx_size << 4;
+		if (msg->size == 0)
+			tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+		else
+			tx_buf[3] |= tx_size << 4;
 		memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size);
 		ret = radeon_process_aux_ch(chan,
 					    tx_buf, tx_size, NULL, 0, delay, &ack);
@@ -176,8 +183,14 @@
 		break;
 	case DP_AUX_NATIVE_READ:
 	case DP_AUX_I2C_READ:
+		/* tx_size needs to be 4 even for bare address packets since the atom
+		 * table needs the info in tx_buf[3].
+		 */
 		tx_size = HEADER_SIZE;
-		tx_buf[3] |= tx_size << 4;
+		if (msg->size == 0)
+			tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+		else
+			tx_buf[3] |= tx_size << 4;
 		ret = radeon_process_aux_ch(chan,
 					    tx_buf, tx_size, msg->buffer, msg->size, delay, &ack);
 		break;
@@ -186,7 +199,7 @@
 		break;
 	}
 
-	if (ret > 0)
+	if (ret >= 0)
 		msg->reply = ack >> 4;
 
 	return ret;
@@ -194,98 +207,15 @@
 
 void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
 {
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
-
-	dig_connector->dp_i2c_bus->aux.dev = radeon_connector->base.kdev;
-	dig_connector->dp_i2c_bus->aux.transfer = radeon_dp_aux_transfer;
-}
-
-int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
-			 u8 write_byte, u8 *read_byte)
-{
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	struct radeon_i2c_chan *auxch = i2c_get_adapdata(adapter);
-	u16 address = algo_data->address;
-	u8 msg[5];
-	u8 reply[2];
-	unsigned retry;
-	int msg_bytes;
-	int reply_bytes = 1;
 	int ret;
-	u8 ack;
 
-	/* Set up the address */
-	msg[0] = address;
-	msg[1] = address >> 8;
+	radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
+	radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer;
+	ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux);
+	if (!ret)
+		radeon_connector->ddc_bus->has_aux = true;
 
-	/* Set up the command byte */
-	if (mode & MODE_I2C_READ) {
-		msg[2] = DP_AUX_I2C_READ << 4;
-		msg_bytes = 4;
-		msg[3] = msg_bytes << 4;
-	} else {
-		msg[2] = DP_AUX_I2C_WRITE << 4;
-		msg_bytes = 5;
-		msg[3] = msg_bytes << 4;
-		msg[4] = write_byte;
-	}
-
-	/* special handling for start/stop */
-	if (mode & (MODE_I2C_START | MODE_I2C_STOP))
-		msg[3] = 3 << 4;
-
-	/* Set MOT bit for all but stop */
-	if ((mode & MODE_I2C_STOP) == 0)
-		msg[2] |= DP_AUX_I2C_MOT << 4;
-
-	for (retry = 0; retry < 7; retry++) {
-		ret = radeon_process_aux_ch(auxch,
-					    msg, msg_bytes, reply, reply_bytes, 0, &ack);
-		if (ret == -EBUSY)
-			continue;
-		else if (ret < 0) {
-			DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
-			return ret;
-		}
-
-		switch ((ack >> 4) & DP_AUX_NATIVE_REPLY_MASK) {
-		case DP_AUX_NATIVE_REPLY_ACK:
-			/* I2C-over-AUX Reply field is only valid
-			 * when paired with AUX ACK.
-			 */
-			break;
-		case DP_AUX_NATIVE_REPLY_NACK:
-			DRM_DEBUG_KMS("aux_ch native nack\n");
-			return -EREMOTEIO;
-		case DP_AUX_NATIVE_REPLY_DEFER:
-			DRM_DEBUG_KMS("aux_ch native defer\n");
-			usleep_range(500, 600);
-			continue;
-		default:
-			DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack);
-			return -EREMOTEIO;
-		}
-
-		switch ((ack >> 4) & DP_AUX_I2C_REPLY_MASK) {
-		case DP_AUX_I2C_REPLY_ACK:
-			if (mode == MODE_I2C_READ)
-				*read_byte = reply[0];
-			return ret;
-		case DP_AUX_I2C_REPLY_NACK:
-			DRM_DEBUG_KMS("aux_i2c nack\n");
-			return -EREMOTEIO;
-		case DP_AUX_I2C_REPLY_DEFER:
-			DRM_DEBUG_KMS("aux_i2c defer\n");
-			usleep_range(400, 500);
-			break;
-		default:
-			DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack);
-			return -EREMOTEIO;
-		}
-	}
-
-	DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
-	return -EREMOTEIO;
+	WARN(ret, "drm_dp_aux_register_i2c_bus() failed with error %d\n", ret);
 }
 
 /***** general DP utility functions *****/
@@ -420,12 +350,11 @@
 
 u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
 {
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 	struct drm_device *dev = radeon_connector->base.dev;
 	struct radeon_device *rdev = dev->dev_private;
 
 	return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
-					 dig_connector->dp_i2c_bus->rec.i2c_id, 0);
+					 radeon_connector->ddc_bus->rec.i2c_id, 0);
 }
 
 static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
@@ -436,11 +365,11 @@
 	if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
 		return;
 
-	if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_SINK_OUI, buf, 3))
+	if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3))
 		DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
 			      buf[0], buf[1], buf[2]);
 
-	if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_BRANCH_OUI, buf, 3))
+	if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3))
 		DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
 			      buf[0], buf[1], buf[2]);
 }
@@ -451,7 +380,7 @@
 	u8 msg[DP_DPCD_SIZE];
 	int ret, i;
 
-	ret = drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_DPCD_REV, msg,
+	ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
 			       DP_DPCD_SIZE);
 	if (ret > 0) {
 		memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
@@ -489,7 +418,7 @@
 
 	if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
 		/* DP bridge chips */
-		drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+		drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
 				  DP_EDP_CONFIGURATION_CAP, &tmp);
 		if (tmp & 1)
 			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
@@ -500,7 +429,7 @@
 			panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
 	} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
 		/* eDP */
-		drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+		drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
 				  DP_EDP_CONFIGURATION_CAP, &tmp);
 		if (tmp & 1)
 			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
@@ -554,7 +483,8 @@
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
 
-	if (drm_dp_dpcd_read_link_status(&dig->dp_i2c_bus->aux, link_status) <= 0)
+	if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status)
+	    <= 0)
 		return false;
 	if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
 		return false;
@@ -574,7 +504,7 @@
 
 	/* power up/down the sink */
 	if (dig_connector->dpcd[0] >= 0x11) {
-		drm_dp_dpcd_writeb(&dig_connector->dp_i2c_bus->aux,
+		drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux,
 				   DP_SET_POWER, power_state);
 		usleep_range(1000, 2000);
 	}
@@ -878,7 +808,7 @@
 	else
 		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
 
-	drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, DP_MAX_LANE_COUNT, &tmp);
+	drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp);
 	if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
 		dp_info.tp3_supported = true;
 	else
@@ -890,7 +820,7 @@
 	dp_info.connector = connector;
 	dp_info.dp_lane_count = dig_connector->dp_lane_count;
 	dp_info.dp_clock = dig_connector->dp_clock;
-	dp_info.aux = &dig_connector->dp_i2c_bus->aux;
+	dp_info.aux = &radeon_connector->ddc_bus->aux;
 
 	if (radeon_dp_link_train_init(&dp_info))
 		goto done;
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index cad89a9..10dae41 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -21,8 +21,10 @@
  *
  */
 
+#include <linux/firmware.h>
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_ucode.h"
 #include "cikd.h"
 #include "r600_dpm.h"
 #include "ci_dpm.h"
@@ -202,24 +204,29 @@
 	struct ci_power_info *pi = ci_get_pi(rdev);
 
 	switch (rdev->pdev->device) {
+	case 0x6649:
 	case 0x6650:
+	case 0x6651:
 	case 0x6658:
 	case 0x665C:
+	case 0x665D:
 	default:
 		pi->powertune_defaults = &defaults_bonaire_xt;
 		break;
-	case 0x6651:
-	case 0x665D:
-		pi->powertune_defaults = &defaults_bonaire_pro;
-		break;
 	case 0x6640:
-		pi->powertune_defaults = &defaults_saturn_xt;
-		break;
 	case 0x6641:
-		pi->powertune_defaults = &defaults_saturn_pro;
+	case 0x6646:
+	case 0x6647:
+		pi->powertune_defaults = &defaults_saturn_xt;
 		break;
 	case 0x67B8:
 	case 0x67B0:
+		pi->powertune_defaults = &defaults_hawaii_xt;
+		break;
+	case 0x67BA:
+	case 0x67B1:
+		pi->powertune_defaults = &defaults_hawaii_pro;
+		break;
 	case 0x67A0:
 	case 0x67A1:
 	case 0x67A2:
@@ -228,11 +235,7 @@
 	case 0x67AA:
 	case 0x67B9:
 	case 0x67BE:
-		pi->powertune_defaults = &defaults_hawaii_xt;
-		break;
-	case 0x67BA:
-	case 0x67B1:
-		pi->powertune_defaults = &defaults_hawaii_pro;
+		pi->powertune_defaults = &defaults_bonaire_xt;
 		break;
 	}
 
@@ -5146,6 +5149,12 @@
 	pi->mclk_dpm_key_disabled = 0;
 	pi->pcie_dpm_key_disabled = 0;
 
+	/* mclk dpm is unstable on some R7 260X cards with the old mc ucode */
+	if ((rdev->pdev->device == 0x6658) &&
+	    (rdev->mc_fw->size == (BONAIRE_MC_UCODE_SIZE * 4))) {
+		pi->mclk_dpm_key_disabled = 1;
+	}
+
 	pi->caps_sclk_ds = true;
 
 	pi->mclk_strobe_mode_threshold = 40000;
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 745143c..199eb19 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -38,6 +38,7 @@
 MODULE_FIRMWARE("radeon/BONAIRE_ce.bin");
 MODULE_FIRMWARE("radeon/BONAIRE_mec.bin");
 MODULE_FIRMWARE("radeon/BONAIRE_mc.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_mc2.bin");
 MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin");
 MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin");
 MODULE_FIRMWARE("radeon/BONAIRE_smc.bin");
@@ -46,6 +47,7 @@
 MODULE_FIRMWARE("radeon/HAWAII_ce.bin");
 MODULE_FIRMWARE("radeon/HAWAII_mec.bin");
 MODULE_FIRMWARE("radeon/HAWAII_mc.bin");
+MODULE_FIRMWARE("radeon/HAWAII_mc2.bin");
 MODULE_FIRMWARE("radeon/HAWAII_rlc.bin");
 MODULE_FIRMWARE("radeon/HAWAII_sdma.bin");
 MODULE_FIRMWARE("radeon/HAWAII_smc.bin");
@@ -1703,20 +1705,20 @@
 	const __be32 *fw_data;
 	u32 running, blackout = 0;
 	u32 *io_mc_regs;
-	int i, ucode_size, regs_size;
+	int i, regs_size, ucode_size;
 
 	if (!rdev->mc_fw)
 		return -EINVAL;
 
+	ucode_size = rdev->mc_fw->size / 4;
+
 	switch (rdev->family) {
 	case CHIP_BONAIRE:
 		io_mc_regs = (u32 *)&bonaire_io_mc_regs;
-		ucode_size = CIK_MC_UCODE_SIZE;
 		regs_size = BONAIRE_IO_MC_REGS_SIZE;
 		break;
 	case CHIP_HAWAII:
 		io_mc_regs = (u32 *)&hawaii_io_mc_regs;
-		ucode_size = HAWAII_MC_UCODE_SIZE;
 		regs_size = HAWAII_IO_MC_REGS_SIZE;
 		break;
 	default:
@@ -1783,7 +1785,7 @@
 	const char *chip_name;
 	size_t pfp_req_size, me_req_size, ce_req_size,
 		mec_req_size, rlc_req_size, mc_req_size = 0,
-		sdma_req_size, smc_req_size = 0;
+		sdma_req_size, smc_req_size = 0, mc2_req_size = 0;
 	char fw_name[30];
 	int err;
 
@@ -1797,7 +1799,8 @@
 		ce_req_size = CIK_CE_UCODE_SIZE * 4;
 		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
 		rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
-		mc_req_size = CIK_MC_UCODE_SIZE * 4;
+		mc_req_size = BONAIRE_MC_UCODE_SIZE * 4;
+		mc2_req_size = BONAIRE_MC2_UCODE_SIZE * 4;
 		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
 		smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4);
 		break;
@@ -1809,6 +1812,7 @@
 		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
 		rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
 		mc_req_size = HAWAII_MC_UCODE_SIZE * 4;
+		mc2_req_size = HAWAII_MC2_UCODE_SIZE * 4;
 		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
 		smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4);
 		break;
@@ -1904,16 +1908,22 @@
 
 	/* No SMC, MC ucode on APUs */
 	if (!(rdev->flags & RADEON_IS_IGP)) {
-		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
 		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
-		if (err)
-			goto out;
-		if (rdev->mc_fw->size != mc_req_size) {
+		if (err) {
+			snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+			err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+			if (err)
+				goto out;
+		}
+		if ((rdev->mc_fw->size != mc_req_size) &&
+		    (rdev->mc_fw->size != mc2_req_size)){
 			printk(KERN_ERR
 			       "cik_mc: Bogus length %zu in firmware \"%s\"\n",
 			       rdev->mc_fw->size, fw_name);
 			err = -EINVAL;
 		}
+		DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
 
 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
 		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c
index 94e8587..0a65dc7 100644
--- a/drivers/gpu/drm/radeon/dce6_afmt.c
+++ b/drivers/gpu/drm/radeon/dce6_afmt.c
@@ -309,11 +309,17 @@
 
 	rdev->audio.enabled = true;
 
-	if (ASIC_IS_DCE8(rdev))
+	if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */
+		rdev->audio.num_pins = 7;
+	else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */
+		rdev->audio.num_pins = 3;
+	else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */
+		rdev->audio.num_pins = 7;
+	else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */
 		rdev->audio.num_pins = 6;
-	else if (ASIC_IS_DCE61(rdev))
-		rdev->audio.num_pins = 4;
-	else
+	else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */
+		rdev->audio.num_pins = 2;
+	else /* SI: 6 streams, 6 endpoints */
 		rdev->audio.num_pins = 6;
 
 	for (i = 0; i < rdev->audio.num_pins; i++) {
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f21db7a..b58e1af 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -739,7 +739,7 @@
 	struct cik_irq_stat_regs cik;
 };
 
-#define RADEON_MAX_HPD_PINS 6
+#define RADEON_MAX_HPD_PINS 7
 #define RADEON_MAX_CRTCS 6
 #define RADEON_MAX_AFMT_BLOCKS 7
 
@@ -2321,6 +2321,7 @@
 	bool have_disp_power_ref;
 };
 
+bool radeon_is_px(struct drm_device *dev);
 int radeon_device_init(struct radeon_device *rdev,
 		       struct drm_device *ddev,
 		       struct pci_dev *pdev,
@@ -2631,6 +2632,9 @@
 #define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND))
 #define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN))
 #define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE))
+#define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI))
+#define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE))
+#define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI))
 
 #define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \
 			      (rdev->ddev->pdev->device == 0x6850) || \
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index fa9a9c0..dedea72 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -59,7 +59,7 @@
 	u16 mux;
 } __packed;
 
-bool radeon_is_px(void) {
+bool radeon_has_atpx(void) {
 	return radeon_atpx_priv.atpx_detected;
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index c566b48..ea50e0a 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1261,21 +1261,6 @@
 	.force = radeon_dvi_force,
 };
 
-static void radeon_dp_connector_destroy(struct drm_connector *connector)
-{
-	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
-
-	if (radeon_connector->edid)
-		kfree(radeon_connector->edid);
-	if (radeon_dig_connector->dp_i2c_bus)
-		radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
-	kfree(radeon_connector->con_priv);
-	drm_sysfs_connector_remove(connector);
-	drm_connector_cleanup(connector);
-	kfree(connector);
-}
-
 static int radeon_dp_get_modes(struct drm_connector *connector)
 {
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1553,7 +1538,7 @@
 	.detect = radeon_dp_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.set_property = radeon_connector_set_property,
-	.destroy = radeon_dp_connector_destroy,
+	.destroy = radeon_connector_destroy,
 	.force = radeon_dvi_force,
 };
 
@@ -1562,7 +1547,7 @@
 	.detect = radeon_dp_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.set_property = radeon_lvds_set_property,
-	.destroy = radeon_dp_connector_destroy,
+	.destroy = radeon_connector_destroy,
 	.force = radeon_dvi_force,
 };
 
@@ -1571,7 +1556,7 @@
 	.detect = radeon_dp_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.set_property = radeon_lvds_set_property,
-	.destroy = radeon_dp_connector_destroy,
+	.destroy = radeon_connector_destroy,
 	.force = radeon_dvi_force,
 };
 
@@ -1668,17 +1653,10 @@
 		radeon_dig_connector->igp_lane_info = igp_lane_info;
 		radeon_connector->con_priv = radeon_dig_connector;
 		if (i2c_bus->valid) {
-			/* add DP i2c bus */
-			if (connector_type == DRM_MODE_CONNECTOR_eDP)
-				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
-			else
-				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
-			if (radeon_dig_connector->dp_i2c_bus)
+			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+			if (radeon_connector->ddc_bus)
 				has_aux = true;
 			else
-				DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
-			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
-			if (!radeon_connector->ddc_bus)
 				DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
 		}
 		switch (connector_type) {
@@ -1893,10 +1871,6 @@
 			drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
 			drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
 			if (i2c_bus->valid) {
-				/* add DP i2c bus */
-				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
-				if (!radeon_dig_connector->dp_i2c_bus)
-					DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
 				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
 				if (radeon_connector->ddc_bus)
 					has_aux = true;
@@ -1942,14 +1916,10 @@
 			drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type);
 			drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
 			if (i2c_bus->valid) {
-				/* add DP i2c bus */
-				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
-				if (radeon_dig_connector->dp_i2c_bus)
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (radeon_connector->ddc_bus)
 					has_aux = true;
 				else
-					DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
-				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
-				if (!radeon_connector->ddc_bus)
 					DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
 			}
 			drm_object_attach_property(&radeon_connector->base.base,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 835516d..511fe26 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -102,11 +102,14 @@
 	"LAST",
 };
 
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
-#else
-static inline bool radeon_is_px(void) { return false; }
-#endif
+bool radeon_is_px(struct drm_device *dev)
+{
+	struct radeon_device *rdev = dev->dev_private;
+
+	if (rdev->flags & RADEON_IS_PX)
+		return true;
+	return false;
+}
 
 /**
  * radeon_program_register_sequence - program an array of registers.
@@ -1082,7 +1085,7 @@
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	if (radeon_is_px() && state == VGA_SWITCHEROO_OFF)
+	if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF)
 		return;
 
 	if (state == VGA_SWITCHEROO_ON) {
@@ -1301,9 +1304,7 @@
 	 * ignore it */
 	vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
 
-	if (radeon_runtime_pm == 1)
-		runtime = true;
-	if ((radeon_runtime_pm == -1) && radeon_is_px())
+	if (rdev->flags & RADEON_IS_PX)
 		runtime = true;
 	vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
 	if (runtime)
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 386cfa4..2f7cbb9 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -759,19 +759,18 @@
 
 	if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
 	    ENCODER_OBJECT_ID_NONE) {
-		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
-		if (dig->dp_i2c_bus)
+		if (radeon_connector->ddc_bus->has_aux)
 			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-							      &dig->dp_i2c_bus->adapter);
+							      &radeon_connector->ddc_bus->aux.ddc);
 	} else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
 		   (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
 		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
 
 		if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
-		     dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus)
+		     dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
+		    radeon_connector->ddc_bus->has_aux)
 			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-							      &dig->dp_i2c_bus->adapter);
+							      &radeon_connector->ddc_bus->aux.ddc);
 		else if (radeon_connector->ddc_bus && !radeon_connector->edid)
 			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
 							      &radeon_connector->ddc_bus->adapter);
@@ -865,7 +864,7 @@
 	unsigned post_div_min, post_div_max, post_div;
 	unsigned ref_div_min, ref_div_max, ref_div;
 	unsigned post_div_best, diff_best;
-	unsigned nom, den, tmp;
+	unsigned nom, den;
 
 	/* determine allowed feedback divider range */
 	fb_div_min = pll->min_feedback_div;
@@ -937,23 +936,27 @@
 	}
 	post_div = post_div_best;
 
+	/* limit reference * post divider to a maximum */
+	ref_div_max = min(210 / post_div, ref_div_max);
+
 	/* get matching reference and feedback divider */
-	ref_div = max(den / post_div, 1u);
-	fb_div = nom;
+	ref_div = max(DIV_ROUND_CLOSEST(den, post_div), 1u);
+	fb_div = DIV_ROUND_CLOSEST(nom * ref_div * post_div, den);
 
 	/* we're almost done, but reference and feedback
 	   divider might be to large now */
 
-	tmp = ref_div;
+	nom = fb_div;
+	den = ref_div;
 
         if (fb_div > fb_div_max) {
-		ref_div = ref_div * fb_div_max / fb_div;
+		ref_div = DIV_ROUND_CLOSEST(den * fb_div_max, nom);
 		fb_div = fb_div_max;
 	}
 
 	if (ref_div > ref_div_max) {
 		ref_div = ref_div_max;
-		fb_div = nom * ref_div_max / tmp;
+		fb_div = DIV_ROUND_CLOSEST(nom * ref_div_max, den);
 	}
 
 	/* reduce the numbers to a simpler ratio once more */
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index d0eba48..c00a2f5 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -115,6 +115,7 @@
 				      unsigned int flags,
 				      int *vpos, int *hpos, ktime_t *stime,
 				      ktime_t *etime);
+extern bool radeon_is_px(struct drm_device *dev);
 extern const struct drm_ioctl_desc radeon_ioctls_kms[];
 extern int radeon_max_kms_ioctl;
 int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -144,11 +145,9 @@
 #if defined(CONFIG_VGA_SWITCHEROO)
 void radeon_register_atpx_handler(void);
 void radeon_unregister_atpx_handler(void);
-bool radeon_is_px(void);
 #else
 static inline void radeon_register_atpx_handler(void) {}
 static inline void radeon_unregister_atpx_handler(void) {}
-static inline bool radeon_is_px(void) { return false; }
 #endif
 
 int radeon_no_wb;
@@ -186,7 +185,7 @@
 MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx");
 module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444);
 
-MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing");
+MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
 module_param_named(vramlimit, radeon_vram_limit, int, 0600);
 
 MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)");
@@ -405,12 +404,7 @@
 	struct drm_device *drm_dev = pci_get_drvdata(pdev);
 	int ret;
 
-	if (radeon_runtime_pm == 0) {
-		pm_runtime_forbid(dev);
-		return -EBUSY;
-	}
-
-	if (radeon_runtime_pm == -1 && !radeon_is_px()) {
+	if (!radeon_is_px(drm_dev)) {
 		pm_runtime_forbid(dev);
 		return -EBUSY;
 	}
@@ -434,10 +428,7 @@
 	struct drm_device *drm_dev = pci_get_drvdata(pdev);
 	int ret;
 
-	if (radeon_runtime_pm == 0)
-		return -EINVAL;
-
-	if (radeon_runtime_pm == -1 && !radeon_is_px())
+	if (!radeon_is_px(drm_dev))
 		return -EINVAL;
 
 	drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
@@ -462,14 +453,7 @@
 	struct drm_device *drm_dev = pci_get_drvdata(pdev);
 	struct drm_crtc *crtc;
 
-	if (radeon_runtime_pm == 0) {
-		pm_runtime_forbid(dev);
-		return -EBUSY;
-	}
-
-	/* are we PX enabled? */
-	if (radeon_runtime_pm == -1 && !radeon_is_px()) {
-		DRM_DEBUG_DRIVER("failing to power off - not px\n");
+	if (!radeon_is_px(drm_dev)) {
 		pm_runtime_forbid(dev);
 		return -EBUSY;
 	}
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h
index 614ad54..9da5da4 100644
--- a/drivers/gpu/drm/radeon/radeon_family.h
+++ b/drivers/gpu/drm/radeon/radeon_family.h
@@ -115,6 +115,7 @@
 	RADEON_NEW_MEMMAP = 0x00400000UL,
 	RADEON_IS_PCI = 0x00800000UL,
 	RADEON_IS_IGPGART = 0x01000000UL,
+	RADEON_IS_PX = 0x02000000UL,
 };
 
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index e24ca6a..7b94414 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -64,8 +64,7 @@
 		radeon_router_select_ddc_port(radeon_connector);
 
 	if (use_aux) {
-		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-		ret = i2c_transfer(&dig->dp_i2c_bus->adapter, msgs, 2);
+		ret = i2c_transfer(&radeon_connector->ddc_bus->aux.ddc, msgs, 2);
 	} else {
 		ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
 	}
@@ -950,16 +949,16 @@
 		/* set the radeon bit adapter */
 		snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
 			 "Radeon i2c bit bus %s", name);
-		i2c->adapter.algo_data = &i2c->algo.bit;
-		i2c->algo.bit.pre_xfer = pre_xfer;
-		i2c->algo.bit.post_xfer = post_xfer;
-		i2c->algo.bit.setsda = set_data;
-		i2c->algo.bit.setscl = set_clock;
-		i2c->algo.bit.getsda = get_data;
-		i2c->algo.bit.getscl = get_clock;
-		i2c->algo.bit.udelay = 10;
-		i2c->algo.bit.timeout = usecs_to_jiffies(2200);	/* from VESA */
-		i2c->algo.bit.data = i2c;
+		i2c->adapter.algo_data = &i2c->bit;
+		i2c->bit.pre_xfer = pre_xfer;
+		i2c->bit.post_xfer = post_xfer;
+		i2c->bit.setsda = set_data;
+		i2c->bit.setscl = set_clock;
+		i2c->bit.getsda = get_data;
+		i2c->bit.getscl = get_clock;
+		i2c->bit.udelay = 10;
+		i2c->bit.timeout = usecs_to_jiffies(2200);	/* from VESA */
+		i2c->bit.data = i2c;
 		ret = i2c_bit_add_bus(&i2c->adapter);
 		if (ret) {
 			DRM_ERROR("Failed to register bit i2c %s\n", name);
@@ -974,46 +973,13 @@
 
 }
 
-struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
-					     struct radeon_i2c_bus_rec *rec,
-					     const char *name)
-{
-	struct radeon_i2c_chan *i2c;
-	int ret;
-
-	i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
-	if (i2c == NULL)
-		return NULL;
-
-	i2c->rec = *rec;
-	i2c->adapter.owner = THIS_MODULE;
-	i2c->adapter.class = I2C_CLASS_DDC;
-	i2c->adapter.dev.parent = &dev->pdev->dev;
-	i2c->dev = dev;
-	snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
-		 "Radeon aux bus %s", name);
-	i2c_set_adapdata(&i2c->adapter, i2c);
-	i2c->adapter.algo_data = &i2c->algo.dp;
-	i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
-	i2c->algo.dp.address = 0;
-	ret = i2c_dp_aux_add_bus(&i2c->adapter);
-	if (ret) {
-		DRM_INFO("Failed to register i2c %s\n", name);
-		goto out_free;
-	}
-
-	return i2c;
-out_free:
-	kfree(i2c);
-	return NULL;
-
-}
-
 void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
 {
 	if (!i2c)
 		return;
 	i2c_del_adapter(&i2c->adapter);
+	if (i2c->has_aux)
+		drm_dp_aux_unregister_i2c_bus(&i2c->aux);
 	kfree(i2c);
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 3e49342..fb3d13f 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -35,9 +35,9 @@
 #include <linux/pm_runtime.h>
 
 #if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
+bool radeon_has_atpx(void);
 #else
-static inline bool radeon_is_px(void) { return false; }
+static inline bool radeon_has_atpx(void) { return false; }
 #endif
 
 /**
@@ -107,6 +107,13 @@
 		flags |= RADEON_IS_PCI;
 	}
 
+	if (radeon_runtime_pm == 1)
+		flags |= RADEON_IS_PX;
+	else if ((radeon_runtime_pm == -1) &&
+		 radeon_has_atpx() &&
+		 ((flags & RADEON_IS_IGP) == 0))
+		flags |= RADEON_IS_PX;
+
 	/* radeon_device_init should report only fatal error
 	 * like memory allocation failure or iomapping failure,
 	 * or memory manager initialization failure, it must
@@ -137,8 +144,7 @@
 				"Error during ACPI methods call\n");
 	}
 
-	if ((radeon_runtime_pm == 1) ||
-	    ((radeon_runtime_pm == -1) && radeon_is_px())) {
+	if (radeon_is_px(dev)) {
 		pm_runtime_use_autosuspend(dev->dev);
 		pm_runtime_set_autosuspend_delay(dev->dev, 5000);
 		pm_runtime_set_active(dev->dev);
@@ -568,12 +574,17 @@
 		}
 
 		r = radeon_vm_init(rdev, &fpriv->vm);
-		if (r)
+		if (r) {
+			kfree(fpriv);
 			return r;
+		}
 
 		r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
-		if (r)
+		if (r) {
+			radeon_vm_fini(rdev, &fpriv->vm);
+			kfree(fpriv);
 			return r;
+		}
 
 		/* map the ib pool buffer read only into
 		 * virtual address space */
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 832d9fa..6ddf31a 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -187,12 +187,10 @@
 struct radeon_i2c_chan {
 	struct i2c_adapter adapter;
 	struct drm_device *dev;
-	union {
-		struct i2c_algo_bit_data bit;
-		struct i2c_algo_dp_aux_data dp;
-	} algo;
+	struct i2c_algo_bit_data bit;
 	struct radeon_i2c_bus_rec rec;
 	struct drm_dp_aux aux;
+	bool has_aux;
 };
 
 /* mostly for macs, but really any system without connector tables */
@@ -440,7 +438,6 @@
 struct radeon_connector_atom_dig {
 	uint32_t igp_lane_info;
 	/* displayport */
-	struct radeon_i2c_chan *dp_i2c_bus;
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
 	u8 dp_sink_type;
 	int dp_clock;
@@ -702,8 +699,6 @@
 					   uint8_t lane_set);
 extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
 extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder);
-extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
-				u8 write_byte, u8 *read_byte);
 void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
 
 extern void radeon_i2c_init(struct radeon_device *rdev);
@@ -715,9 +710,6 @@
 			   const char *name);
 extern struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev,
 						 struct radeon_i2c_bus_rec *i2c_bus);
-extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
-						    struct radeon_i2c_bus_rec *rec,
-						    const char *name);
 extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
 						 struct radeon_i2c_bus_rec *rec,
 						 const char *name);
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h
index a77cd27..58d1293 100644
--- a/drivers/gpu/drm/radeon/radeon_ucode.h
+++ b/drivers/gpu/drm/radeon/radeon_ucode.h
@@ -57,9 +57,14 @@
 #define BTC_MC_UCODE_SIZE            6024
 #define CAYMAN_MC_UCODE_SIZE         6037
 #define SI_MC_UCODE_SIZE             7769
+#define TAHITI_MC_UCODE_SIZE         7808
+#define PITCAIRN_MC_UCODE_SIZE       7775
+#define VERDE_MC_UCODE_SIZE          7875
 #define OLAND_MC_UCODE_SIZE          7863
-#define CIK_MC_UCODE_SIZE            7866
+#define BONAIRE_MC_UCODE_SIZE        7866
+#define BONAIRE_MC2_UCODE_SIZE       7948
 #define HAWAII_MC_UCODE_SIZE         7933
+#define HAWAII_MC2_UCODE_SIZE        8091
 
 /* SDMA */
 #define CIK_SDMA_UCODE_SIZE          1050
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c
index 76e9904..ced53dd 100644
--- a/drivers/gpu/drm/radeon/radeon_vce.c
+++ b/drivers/gpu/drm/radeon/radeon_vce.c
@@ -613,7 +613,7 @@
 			   struct radeon_fence *fence)
 {
 	struct radeon_ring *ring = &rdev->ring[fence->ring];
-	uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
+	uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
 
 	radeon_ring_write(ring, VCE_CMD_FENCE);
 	radeon_ring_write(ring, addr);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index d589475..ac708e0 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -39,30 +39,35 @@
 MODULE_FIRMWARE("radeon/TAHITI_me.bin");
 MODULE_FIRMWARE("radeon/TAHITI_ce.bin");
 MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
+MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
 MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
 MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
+MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
 MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
 MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
 MODULE_FIRMWARE("radeon/VERDE_me.bin");
 MODULE_FIRMWARE("radeon/VERDE_ce.bin");
 MODULE_FIRMWARE("radeon/VERDE_mc.bin");
+MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
 MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
 MODULE_FIRMWARE("radeon/VERDE_smc.bin");
 MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
 MODULE_FIRMWARE("radeon/OLAND_me.bin");
 MODULE_FIRMWARE("radeon/OLAND_ce.bin");
 MODULE_FIRMWARE("radeon/OLAND_mc.bin");
+MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
 MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
 MODULE_FIRMWARE("radeon/OLAND_smc.bin");
 MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
 MODULE_FIRMWARE("radeon/HAINAN_me.bin");
 MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
 MODULE_FIRMWARE("radeon/HAINAN_mc.bin");
+MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
 MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
 MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
 
@@ -1467,36 +1472,33 @@
 	const __be32 *fw_data;
 	u32 running, blackout = 0;
 	u32 *io_mc_regs;
-	int i, ucode_size, regs_size;
+	int i, regs_size, ucode_size;
 
 	if (!rdev->mc_fw)
 		return -EINVAL;
 
+	ucode_size = rdev->mc_fw->size / 4;
+
 	switch (rdev->family) {
 	case CHIP_TAHITI:
 		io_mc_regs = (u32 *)&tahiti_io_mc_regs;
-		ucode_size = SI_MC_UCODE_SIZE;
 		regs_size = TAHITI_IO_MC_REGS_SIZE;
 		break;
 	case CHIP_PITCAIRN:
 		io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
-		ucode_size = SI_MC_UCODE_SIZE;
 		regs_size = TAHITI_IO_MC_REGS_SIZE;
 		break;
 	case CHIP_VERDE:
 	default:
 		io_mc_regs = (u32 *)&verde_io_mc_regs;
-		ucode_size = SI_MC_UCODE_SIZE;
 		regs_size = TAHITI_IO_MC_REGS_SIZE;
 		break;
 	case CHIP_OLAND:
 		io_mc_regs = (u32 *)&oland_io_mc_regs;
-		ucode_size = OLAND_MC_UCODE_SIZE;
 		regs_size = TAHITI_IO_MC_REGS_SIZE;
 		break;
 	case CHIP_HAINAN:
 		io_mc_regs = (u32 *)&hainan_io_mc_regs;
-		ucode_size = OLAND_MC_UCODE_SIZE;
 		regs_size = TAHITI_IO_MC_REGS_SIZE;
 		break;
 	}
@@ -1552,7 +1554,7 @@
 	const char *chip_name;
 	const char *rlc_chip_name;
 	size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
-	size_t smc_req_size;
+	size_t smc_req_size, mc2_req_size;
 	char fw_name[30];
 	int err;
 
@@ -1567,6 +1569,7 @@
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = SI_MC_UCODE_SIZE * 4;
+		mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
 		smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_PITCAIRN:
@@ -1577,6 +1580,7 @@
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = SI_MC_UCODE_SIZE * 4;
+		mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
 		smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_VERDE:
@@ -1587,6 +1591,7 @@
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = SI_MC_UCODE_SIZE * 4;
+		mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
 		smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_OLAND:
@@ -1596,7 +1601,7 @@
 		me_req_size = SI_PM4_UCODE_SIZE * 4;
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
-		mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
 		smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_HAINAN:
@@ -1606,7 +1611,7 @@
 		me_req_size = SI_PM4_UCODE_SIZE * 4;
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
-		mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
 		smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
 		break;
 	default: BUG();
@@ -1659,16 +1664,22 @@
 		err = -EINVAL;
 	}
 
-	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
 	err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
-	if (err)
-		goto out;
-	if (rdev->mc_fw->size != mc_req_size) {
+	if (err) {
+		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+		if (err)
+			goto out;
+	}
+	if ((rdev->mc_fw->size != mc_req_size) &&
+	    (rdev->mc_fw->size != mc2_req_size)) {
 		printk(KERN_ERR
 		       "si_mc: Bogus length %zu in firmware \"%s\"\n",
 		       rdev->mc_fw->size, fw_name);
 		err = -EINVAL;
 	}
+	DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
 
 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
 	err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index d536ed3..005c19b 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -99,55 +99,73 @@
 static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
 				    struct drm_dp_aux_msg *msg)
 {
-	unsigned long value = DPAUX_DP_AUXCTL_TRANSACTREQ;
 	unsigned long timeout = msecs_to_jiffies(250);
 	struct tegra_dpaux *dpaux = to_dpaux(aux);
 	unsigned long status;
 	ssize_t ret = 0;
+	u32 value;
 
-	if (msg->size < 1 || msg->size > 16)
+	/* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */
+	if (msg->size > 16)
 		return -EINVAL;
 
-	tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
+	/*
+	 * Allow zero-sized messages only for I2C, in which case they specify
+	 * address-only transactions.
+	 */
+	if (msg->size < 1) {
+		switch (msg->request & ~DP_AUX_I2C_MOT) {
+		case DP_AUX_I2C_WRITE:
+		case DP_AUX_I2C_READ:
+			value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	} else {
+		/* For non-zero-sized messages, set the CMDLEN field. */
+		value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
+	}
 
 	switch (msg->request & ~DP_AUX_I2C_MOT) {
 	case DP_AUX_I2C_WRITE:
 		if (msg->request & DP_AUX_I2C_MOT)
-			value = DPAUX_DP_AUXCTL_CMD_MOT_WR;
+			value |= DPAUX_DP_AUXCTL_CMD_MOT_WR;
 		else
-			value = DPAUX_DP_AUXCTL_CMD_I2C_WR;
+			value |= DPAUX_DP_AUXCTL_CMD_I2C_WR;
 
 		break;
 
 	case DP_AUX_I2C_READ:
 		if (msg->request & DP_AUX_I2C_MOT)
-			value = DPAUX_DP_AUXCTL_CMD_MOT_RD;
+			value |= DPAUX_DP_AUXCTL_CMD_MOT_RD;
 		else
-			value = DPAUX_DP_AUXCTL_CMD_I2C_RD;
+			value |= DPAUX_DP_AUXCTL_CMD_I2C_RD;
 
 		break;
 
 	case DP_AUX_I2C_STATUS:
 		if (msg->request & DP_AUX_I2C_MOT)
-			value = DPAUX_DP_AUXCTL_CMD_MOT_RQ;
+			value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
 		else
-			value = DPAUX_DP_AUXCTL_CMD_I2C_RQ;
+			value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ;
 
 		break;
 
 	case DP_AUX_NATIVE_WRITE:
-		value = DPAUX_DP_AUXCTL_CMD_AUX_WR;
+		value |= DPAUX_DP_AUXCTL_CMD_AUX_WR;
 		break;
 
 	case DP_AUX_NATIVE_READ:
-		value = DPAUX_DP_AUXCTL_CMD_AUX_RD;
+		value |= DPAUX_DP_AUXCTL_CMD_AUX_RD;
 		break;
 
 	default:
 		return -EINVAL;
 	}
 
-	value |= DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
+	tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
 	tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
 
 	if ((msg->request & DP_AUX_I2C_READ) == 0) {
@@ -198,7 +216,7 @@
 		break;
 	}
 
-	if (msg->reply == DP_AUX_NATIVE_REPLY_ACK) {
+	if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
 		if (msg->request & DP_AUX_I2C_READ) {
 			size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK;
 
diff --git a/drivers/gpu/drm/tegra/dpaux.h b/drivers/gpu/drm/tegra/dpaux.h
index 4f5bf10..806e245 100644
--- a/drivers/gpu/drm/tegra/dpaux.h
+++ b/drivers/gpu/drm/tegra/dpaux.h
@@ -32,6 +32,7 @@
 #define DPAUX_DP_AUXCTL_CMD_I2C_RQ (2 << 12)
 #define DPAUX_DP_AUXCTL_CMD_I2C_RD (1 << 12)
 #define DPAUX_DP_AUXCTL_CMD_I2C_WR (0 << 12)
+#define DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY (1 << 8)
 #define DPAUX_DP_AUXCTL_CMDLEN(x) ((x) & 0xff)
 
 #define DPAUX_DP_AUXSTAT 0x31
diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c
index db9017a..498b37e 100644
--- a/drivers/gpu/host1x/hw/intr_hw.c
+++ b/drivers/gpu/host1x/hw/intr_hw.c
@@ -47,7 +47,7 @@
 	unsigned long reg;
 	int i, id;
 
-	for (i = 0; i <= BIT_WORD(host->info->nb_pts); i++) {
+	for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
 		reg = host1x_sync_readl(host,
 			HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
 		for_each_set_bit(id, &reg, BITS_PER_LONG) {
@@ -64,7 +64,7 @@
 {
 	u32 i;
 
-	for (i = 0; i <= BIT_WORD(host->info->nb_pts); ++i) {
+	for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) {
 		host1x_sync_writel(host, 0xffffffffu,
 			HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i));
 		host1x_sync_writel(host, 0xffffffffu,
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 9e806420..10a2c08 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -718,6 +718,9 @@
 	case HID_MAIN_ITEM_TAG_END_COLLECTION:
 		break;
 	case HID_MAIN_ITEM_TAG_INPUT:
+		/* ignore constant inputs, they will be ignored by hid-input */
+		if (data & HID_MAIN_ITEM_CONSTANT)
+			break;
 		for (i = 0; i < parser->local.usage_index; i++)
 			hid_scan_input_usage(parser, parser->local.usage[i]);
 		break;
@@ -1821,8 +1824,6 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index bd22126..c8af720 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -455,7 +455,8 @@
 
 #define USB_VENDOR_ID_INTEL_0		0x8086
 #define USB_VENDOR_ID_INTEL_1		0x8087
-#define USB_DEVICE_ID_INTEL_HID_SENSOR	0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_0	0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_1	0x0a04
 
 #define USB_VENDOR_ID_STM_0             0x0483
 #define USB_DEVICE_ID_STM_HID_SENSOR    0x91d1
@@ -629,8 +630,6 @@
 #define USB_DEVICE_ID_MS_PRESENTER_8K_USB	0x0713
 #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K	0x0730
 #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500	0x076c
-#define USB_DEVICE_ID_MS_TOUCH_COVER_2	0x07a7
-#define USB_DEVICE_ID_MS_TYPE_COVER_2	0x07a9
 
 #define USB_VENDOR_ID_MOJO		0x8282
 #define USB_DEVICE_ID_RETRO_ADAPTER	0x3201
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 6fd58175..8ba17a9 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -274,10 +274,6 @@
 		.driver_data = MS_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
 		.driver_data = MS_DUPLICATE_USAGES },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2),
-		.driver_data = 0 },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2),
-		.driver_data = 0 },
 
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
 		.driver_data = MS_PRESENTER },
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 5182031..af8244b 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -697,10 +697,13 @@
 
 static const struct hid_device_id sensor_hub_devices[] = {
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
-			USB_DEVICE_ID_INTEL_HID_SENSOR),
+			USB_DEVICE_ID_INTEL_HID_SENSOR_0),
 			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
-			USB_DEVICE_ID_INTEL_HID_SENSOR),
+			USB_DEVICE_ID_INTEL_HID_SENSOR_0),
+			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
+	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
+			USB_DEVICE_ID_INTEL_HID_SENSOR_1),
 			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
 			USB_DEVICE_ID_STM_HID_SENSOR),
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 69204af..908de27 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1721,8 +1721,6 @@
 	if (sc->quirks & SONY_LED_SUPPORT)
 		sony_leds_remove(hdev);
 
-	if (sc->worker_initialized)
-		cancel_work_sync(&sc->state_worker);
 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
 		hid_hw_close(hdev);
 		sony_battery_remove(sc);
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index f2d7bf9..2e7801a 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -55,6 +55,9 @@
 	case (VERSION_WIN8):
 		return VERSION_WIN7;
 
+	case (VERSION_WIN8_1):
+		return VERSION_WIN8;
+
 	case (VERSION_WS2008):
 	default:
 		return VERSION_INVAL;
@@ -77,7 +80,7 @@
 	msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
 	msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
 	msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
-	if (version == VERSION_WIN8)
+	if (version == VERSION_WIN8_1)
 		msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
 
 	/*
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 02436d5..185452a 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -173,12 +173,15 @@
 	add_timer(&ep->timer);
 }
 
-static void stop_ep_timer(struct c4iw_ep *ep)
+static int stop_ep_timer(struct c4iw_ep *ep)
 {
 	PDBG("%s ep %p stopping\n", __func__, ep);
 	del_timer_sync(&ep->timer);
-	if (!test_and_set_bit(TIMEOUT, &ep->com.flags))
+	if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
 		c4iw_put_ep(&ep->com);
+		return 0;
+	}
+	return 1;
 }
 
 static int c4iw_l2t_send(struct c4iw_rdev *rdev, struct sk_buff *skb,
@@ -1165,12 +1168,11 @@
 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
 
 	/*
-	 * Stop mpa timer.  If it expired, then the state has
-	 * changed and we bail since ep_timeout already aborted
-	 * the connection.
+	 * Stop mpa timer.  If it expired, then
+	 * we ignore the MPA reply.  process_timeout()
+	 * will abort the connection.
 	 */
-	stop_ep_timer(ep);
-	if (ep->com.state != MPA_REQ_SENT)
+	if (stop_ep_timer(ep))
 		return;
 
 	/*
@@ -1375,15 +1377,12 @@
 
 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
 
-	if (ep->com.state != MPA_REQ_WAIT)
-		return;
-
 	/*
 	 * If we get more than the supported amount of private data
 	 * then we must fail this connection.
 	 */
 	if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		abort_connection(ep, skb, GFP_KERNEL);
 		return;
 	}
@@ -1413,13 +1412,13 @@
 	if (mpa->revision > mpa_rev) {
 		printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d,"
 		       " Received = %d\n", __func__, mpa_rev, mpa->revision);
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		abort_connection(ep, skb, GFP_KERNEL);
 		return;
 	}
 
 	if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) {
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		abort_connection(ep, skb, GFP_KERNEL);
 		return;
 	}
@@ -1430,7 +1429,7 @@
 	 * Fail if there's too much private data.
 	 */
 	if (plen > MPA_MAX_PRIVATE_DATA) {
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		abort_connection(ep, skb, GFP_KERNEL);
 		return;
 	}
@@ -1439,7 +1438,7 @@
 	 * If plen does not account for pkt size
 	 */
 	if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		abort_connection(ep, skb, GFP_KERNEL);
 		return;
 	}
@@ -1496,18 +1495,24 @@
 	     ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,
 	     ep->mpa_attr.p2p_type);
 
-	__state_set(&ep->com, MPA_REQ_RCVD);
-	stop_ep_timer(ep);
+	/*
+	 * If the endpoint timer already expired, then we ignore
+	 * the start request.  process_timeout() will abort
+	 * the connection.
+	 */
+	if (!stop_ep_timer(ep)) {
+		__state_set(&ep->com, MPA_REQ_RCVD);
 
-	/* drive upcall */
-	mutex_lock(&ep->parent_ep->com.mutex);
-	if (ep->parent_ep->com.state != DEAD) {
-		if (connect_request_upcall(ep))
+		/* drive upcall */
+		mutex_lock(&ep->parent_ep->com.mutex);
+		if (ep->parent_ep->com.state != DEAD) {
+			if (connect_request_upcall(ep))
+				abort_connection(ep, skb, GFP_KERNEL);
+		} else {
 			abort_connection(ep, skb, GFP_KERNEL);
-	} else {
-		abort_connection(ep, skb, GFP_KERNEL);
+		}
+		mutex_unlock(&ep->parent_ep->com.mutex);
 	}
-	mutex_unlock(&ep->parent_ep->com.mutex);
 	return;
 }
 
@@ -2265,7 +2270,7 @@
 		disconnect = 0;
 		break;
 	case MORIBUND:
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		if (ep->com.cm_id && ep->com.qp) {
 			attrs.next_state = C4IW_QP_STATE_IDLE;
 			c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
@@ -2325,10 +2330,10 @@
 	case CONNECTING:
 		break;
 	case MPA_REQ_WAIT:
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		break;
 	case MPA_REQ_SENT:
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		if (mpa_rev == 1 || (mpa_rev == 2 && ep->tried_with_mpa_v1))
 			connect_reply_upcall(ep, -ECONNRESET);
 		else {
@@ -2433,7 +2438,7 @@
 		__state_set(&ep->com, MORIBUND);
 		break;
 	case MORIBUND:
-		stop_ep_timer(ep);
+		(void)stop_ep_timer(ep);
 		if ((ep->com.cm_id) && (ep->com.qp)) {
 			attrs.next_state = C4IW_QP_STATE_IDLE;
 			c4iw_modify_qp(ep->com.qp->rhp,
@@ -3028,7 +3033,7 @@
 		if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) {
 			close = 1;
 			if (abrupt) {
-				stop_ep_timer(ep);
+				(void)stop_ep_timer(ep);
 				ep->com.state = ABORTING;
 			} else
 				ep->com.state = MORIBUND;
@@ -3462,6 +3467,16 @@
 		__state_set(&ep->com, ABORTING);
 		close_complete_upcall(ep, -ETIMEDOUT);
 		break;
+	case ABORTING:
+	case DEAD:
+
+		/*
+		 * These states are expected if the ep timed out at the same
+		 * time as another thread was calling stop_ep_timer().
+		 * So we silently do nothing for these states.
+		 */
+		abort = 0;
+		break;
 	default:
 		WARN(1, "%s unexpected state ep %p tid %u state %u\n",
 			__func__, ep, ep->hwtid, ep->com.state);
@@ -3483,6 +3498,8 @@
 
 		tmp = timeout_list.next;
 		list_del(tmp);
+		tmp->next = NULL;
+		tmp->prev = NULL;
 		spin_unlock_irq(&timeout_lock);
 		ep = list_entry(tmp, struct c4iw_ep, entry);
 		process_timeout(ep);
@@ -3499,6 +3516,7 @@
 	unsigned int opcode;
 	int ret;
 
+	process_timedout_eps();
 	while ((skb = skb_dequeue(&rxq))) {
 		rpl = cplhdr(skb);
 		dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
@@ -3508,8 +3526,8 @@
 		ret = work_handlers[opcode](dev, skb);
 		if (!ret)
 			kfree_skb(skb);
+		process_timedout_eps();
 	}
-	process_timedout_eps();
 }
 
 static DECLARE_WORK(skb_work, process_work);
@@ -3521,8 +3539,13 @@
 
 	spin_lock(&timeout_lock);
 	if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
-		list_add_tail(&ep->entry, &timeout_list);
-		kickit = 1;
+		/*
+		 * Only insert if it is not already on the list.
+		 */
+		if (!ep->entry.next) {
+			list_add_tail(&ep->entry, &timeout_list);
+			kickit = 1;
+		}
 	}
 	spin_unlock(&timeout_lock);
 	if (kickit)
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c
index ce468e5..cfaa56a 100644
--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -235,27 +235,21 @@
 	struct t4_cq *cq = &chp->cq;
 	int idx;
 	struct t4_swsqe *swsqe;
-	int error = (qhp->attr.state != C4IW_QP_STATE_CLOSING &&
-			qhp->attr.state != C4IW_QP_STATE_IDLE);
 
 	if (wq->sq.flush_cidx == -1)
 		wq->sq.flush_cidx = wq->sq.cidx;
 	idx = wq->sq.flush_cidx;
 	BUG_ON(idx >= wq->sq.size);
 	while (idx != wq->sq.pidx) {
-		if (error) {
-			swsqe = &wq->sq.sw_sq[idx];
-			BUG_ON(swsqe->flushed);
-			swsqe->flushed = 1;
-			insert_sq_cqe(wq, cq, swsqe);
-			if (wq->sq.oldest_read == swsqe) {
-				BUG_ON(swsqe->opcode != FW_RI_READ_REQ);
-				advance_oldest_read(wq);
-			}
-			flushed++;
-		} else {
-			t4_sq_consume(wq);
+		swsqe = &wq->sq.sw_sq[idx];
+		BUG_ON(swsqe->flushed);
+		swsqe->flushed = 1;
+		insert_sq_cqe(wq, cq, swsqe);
+		if (wq->sq.oldest_read == swsqe) {
+			BUG_ON(swsqe->opcode != FW_RI_READ_REQ);
+			advance_oldest_read(wq);
 		}
+		flushed++;
 		if (++idx == wq->sq.size)
 			idx = 0;
 	}
@@ -678,7 +672,7 @@
 static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)
 {
 	struct c4iw_qp *qhp = NULL;
-	struct t4_cqe cqe = {0, 0}, *rd_cqe;
+	struct t4_cqe uninitialized_var(cqe), *rd_cqe;
 	struct t4_wq *wq;
 	u32 credit = 0;
 	u8 cqe_flushed;
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 9489a38..f4fa50a 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -682,7 +682,10 @@
 	idr_destroy(&ctx->dev->hwtid_idr);
 	idr_destroy(&ctx->dev->stid_idr);
 	idr_destroy(&ctx->dev->atid_idr);
-	iounmap(ctx->dev->rdev.oc_mw_kva);
+	if (ctx->dev->rdev.bar2_kva)
+		iounmap(ctx->dev->rdev.bar2_kva);
+	if (ctx->dev->rdev.oc_mw_kva)
+		iounmap(ctx->dev->rdev.oc_mw_kva);
 	ib_dealloc_device(&ctx->dev->ibdev);
 	ctx->dev = NULL;
 }
@@ -722,11 +725,31 @@
 	}
 	devp->rdev.lldi = *infop;
 
-	devp->rdev.oc_mw_pa = pci_resource_start(devp->rdev.lldi.pdev, 2) +
-		(pci_resource_len(devp->rdev.lldi.pdev, 2) -
-		 roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size));
-	devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
-					       devp->rdev.lldi.vr->ocq.size);
+	/*
+	 * For T5 devices, we map all of BAR2 with WC.
+	 * For T4 devices with onchip qp mem, we map only that part
+	 * of BAR2 with WC.
+	 */
+	devp->rdev.bar2_pa = pci_resource_start(devp->rdev.lldi.pdev, 2);
+	if (is_t5(devp->rdev.lldi.adapter_type)) {
+		devp->rdev.bar2_kva = ioremap_wc(devp->rdev.bar2_pa,
+			pci_resource_len(devp->rdev.lldi.pdev, 2));
+		if (!devp->rdev.bar2_kva) {
+			pr_err(MOD "Unable to ioremap BAR2\n");
+			return ERR_PTR(-EINVAL);
+		}
+	} else if (ocqp_supported(infop)) {
+		devp->rdev.oc_mw_pa =
+			pci_resource_start(devp->rdev.lldi.pdev, 2) +
+			pci_resource_len(devp->rdev.lldi.pdev, 2) -
+			roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size);
+		devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
+			devp->rdev.lldi.vr->ocq.size);
+		if (!devp->rdev.oc_mw_kva) {
+			pr_err(MOD "Unable to ioremap onchip mem\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
 
 	PDBG(KERN_INFO MOD "ocq memory: "
 	       "hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n",
@@ -1003,9 +1026,11 @@
 static void resume_rc_qp(struct c4iw_qp *qp)
 {
 	spin_lock(&qp->lock);
-	t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc);
+	t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc,
+		      is_t5(qp->rhp->rdev.lldi.adapter_type), NULL);
 	qp->wq.sq.wq_pidx_inc = 0;
-	t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc);
+	t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc,
+		      is_t5(qp->rhp->rdev.lldi.adapter_type), NULL);
 	qp->wq.rq.wq_pidx_inc = 0;
 	spin_unlock(&qp->lock);
 }
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index e872203..7b8c580 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -149,6 +149,8 @@
 	struct gen_pool *ocqp_pool;
 	u32 flags;
 	struct cxgb4_lld_info lldi;
+	unsigned long bar2_pa;
+	void __iomem *bar2_kva;
 	unsigned long oc_mw_pa;
 	void __iomem *oc_mw_kva;
 	struct c4iw_stats stats;
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index f9ca072..ec7a298 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -259,8 +259,12 @@
 
 	if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) {
 		stag_idx = c4iw_get_resource(&rdev->resource.tpt_table);
-		if (!stag_idx)
+		if (!stag_idx) {
+			mutex_lock(&rdev->stats.lock);
+			rdev->stats.stag.fail++;
+			mutex_unlock(&rdev->stats.lock);
 			return -ENOMEM;
+		}
 		mutex_lock(&rdev->stats.lock);
 		rdev->stats.stag.cur += 32;
 		if (rdev->stats.stag.cur > rdev->stats.stag.max)
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index 7942925..a94a3e1 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -328,7 +328,7 @@
 	props->max_mr = c4iw_num_stags(&dev->rdev);
 	props->max_pd = T4_MAX_NUM_PD;
 	props->local_ca_ack_delay = 0;
-	props->max_fast_reg_page_list_len = T4_MAX_FR_DEPTH;
+	props->max_fast_reg_page_list_len = t4_max_fr_depth(use_dsgl);
 
 	return 0;
 }
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index cb76eb5..7b5114c 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -212,13 +212,23 @@
 
 	wq->db = rdev->lldi.db_reg;
 	wq->gts = rdev->lldi.gts_reg;
-	if (user) {
-		wq->sq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) +
-					(wq->sq.qid << rdev->qpshift);
-		wq->sq.udb &= PAGE_MASK;
-		wq->rq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) +
-					(wq->rq.qid << rdev->qpshift);
-		wq->rq.udb &= PAGE_MASK;
+	if (user || is_t5(rdev->lldi.adapter_type)) {
+		u32 off;
+
+		off = (wq->sq.qid << rdev->qpshift) & PAGE_MASK;
+		if (user) {
+			wq->sq.udb = (u64 __iomem *)(rdev->bar2_pa + off);
+		} else {
+			off += 128 * (wq->sq.qid & rdev->qpmask) + 8;
+			wq->sq.udb = (u64 __iomem *)(rdev->bar2_kva + off);
+		}
+		off = (wq->rq.qid << rdev->qpshift) & PAGE_MASK;
+		if (user) {
+			wq->rq.udb = (u64 __iomem *)(rdev->bar2_pa + off);
+		} else {
+			off += 128 * (wq->rq.qid & rdev->qpmask) + 8;
+			wq->rq.udb = (u64 __iomem *)(rdev->bar2_kva + off);
+		}
 	}
 	wq->rdev = rdev;
 	wq->rq.msn = 1;
@@ -299,9 +309,10 @@
 	if (ret)
 		goto free_dma;
 
-	PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%llx rqudb 0x%llx\n",
+	PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%lx rqudb 0x%lx\n",
 	     __func__, wq->sq.qid, wq->rq.qid, wq->db,
-	     (unsigned long long)wq->sq.udb, (unsigned long long)wq->rq.udb);
+	     (__force unsigned long) wq->sq.udb,
+	     (__force unsigned long) wq->rq.udb);
 
 	return 0;
 free_dma:
@@ -425,6 +436,8 @@
 	default:
 		return -EINVAL;
 	}
+	wqe->send.r3 = 0;
+	wqe->send.r4 = 0;
 
 	plen = 0;
 	if (wr->num_sge) {
@@ -555,7 +568,8 @@
 	int pbllen = roundup(wr->wr.fast_reg.page_list_len * sizeof(u64), 32);
 	int rem;
 
-	if (wr->wr.fast_reg.page_list_len > T4_MAX_FR_DEPTH)
+	if (wr->wr.fast_reg.page_list_len >
+	    t4_max_fr_depth(use_dsgl))
 		return -EINVAL;
 
 	wqe->fr.qpbinde_to_dcacpu = 0;
@@ -650,9 +664,10 @@
 
 	spin_lock_irqsave(&qhp->rhp->lock, flags);
 	spin_lock(&qhp->lock);
-	if (qhp->rhp->db_state == NORMAL) {
-		t4_ring_sq_db(&qhp->wq, inc);
-	} else {
+	if (qhp->rhp->db_state == NORMAL)
+		t4_ring_sq_db(&qhp->wq, inc,
+			      is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL);
+	else {
 		add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry);
 		qhp->wq.sq.wq_pidx_inc += inc;
 	}
@@ -667,9 +682,10 @@
 
 	spin_lock_irqsave(&qhp->rhp->lock, flags);
 	spin_lock(&qhp->lock);
-	if (qhp->rhp->db_state == NORMAL) {
-		t4_ring_rq_db(&qhp->wq, inc);
-	} else {
+	if (qhp->rhp->db_state == NORMAL)
+		t4_ring_rq_db(&qhp->wq, inc,
+			      is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL);
+	else {
 		add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry);
 		qhp->wq.rq.wq_pidx_inc += inc;
 	}
@@ -686,7 +702,7 @@
 	enum fw_wr_opcodes fw_opcode = 0;
 	enum fw_ri_wr_flags fw_flags;
 	struct c4iw_qp *qhp;
-	union t4_wr *wqe;
+	union t4_wr *wqe = NULL;
 	u32 num_wrs;
 	struct t4_swsqe *swsqe;
 	unsigned long flag;
@@ -792,7 +808,8 @@
 		idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE);
 	}
 	if (!qhp->rhp->rdev.status_page->db_off) {
-		t4_ring_sq_db(&qhp->wq, idx);
+		t4_ring_sq_db(&qhp->wq, idx,
+			      is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe);
 		spin_unlock_irqrestore(&qhp->lock, flag);
 	} else {
 		spin_unlock_irqrestore(&qhp->lock, flag);
@@ -806,7 +823,7 @@
 {
 	int err = 0;
 	struct c4iw_qp *qhp;
-	union t4_recv_wr *wqe;
+	union t4_recv_wr *wqe = NULL;
 	u32 num_wrs;
 	u8 len16 = 0;
 	unsigned long flag;
@@ -858,7 +875,8 @@
 		num_wrs--;
 	}
 	if (!qhp->rhp->rdev.status_page->db_off) {
-		t4_ring_rq_db(&qhp->wq, idx);
+		t4_ring_rq_db(&qhp->wq, idx,
+			      is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe);
 		spin_unlock_irqrestore(&qhp->lock, flag);
 	} else {
 		spin_unlock_irqrestore(&qhp->lock, flag);
@@ -1352,6 +1370,7 @@
 		switch (attrs->next_state) {
 		case C4IW_QP_STATE_CLOSING:
 			BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2);
+			t4_set_wq_in_error(&qhp->wq);
 			set_state(qhp, C4IW_QP_STATE_CLOSING);
 			ep = qhp->ep;
 			if (!internal) {
@@ -1359,18 +1378,18 @@
 				disconnect = 1;
 				c4iw_get_ep(&qhp->ep->com);
 			}
-			t4_set_wq_in_error(&qhp->wq);
 			ret = rdma_fini(rhp, qhp, ep);
 			if (ret)
 				goto err;
 			break;
 		case C4IW_QP_STATE_TERMINATE:
+			t4_set_wq_in_error(&qhp->wq);
 			set_state(qhp, C4IW_QP_STATE_TERMINATE);
 			qhp->attr.layer_etype = attrs->layer_etype;
 			qhp->attr.ecode = attrs->ecode;
-			t4_set_wq_in_error(&qhp->wq);
 			ep = qhp->ep;
 			disconnect = 1;
+			c4iw_get_ep(&qhp->ep->com);
 			if (!internal)
 				terminate = 1;
 			else {
@@ -1378,11 +1397,10 @@
 				if (ret)
 					goto err;
 			}
-			c4iw_get_ep(&qhp->ep->com);
 			break;
 		case C4IW_QP_STATE_ERROR:
-			set_state(qhp, C4IW_QP_STATE_ERROR);
 			t4_set_wq_in_error(&qhp->wq);
+			set_state(qhp, C4IW_QP_STATE_ERROR);
 			if (!internal) {
 				abort = 1;
 				disconnect = 1;
@@ -1677,11 +1695,11 @@
 		mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize);
 		insert_mmap(ucontext, mm2);
 		mm3->key = uresp.sq_db_gts_key;
-		mm3->addr = qhp->wq.sq.udb;
+		mm3->addr = (__force unsigned long) qhp->wq.sq.udb;
 		mm3->len = PAGE_SIZE;
 		insert_mmap(ucontext, mm3);
 		mm4->key = uresp.rq_db_gts_key;
-		mm4->addr = qhp->wq.rq.udb;
+		mm4->addr = (__force unsigned long) qhp->wq.rq.udb;
 		mm4->len = PAGE_SIZE;
 		insert_mmap(ucontext, mm4);
 		if (mm5) {
diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c
index cdef4d7..67df71a 100644
--- a/drivers/infiniband/hw/cxgb4/resource.c
+++ b/drivers/infiniband/hw/cxgb4/resource.c
@@ -179,8 +179,12 @@
 		kfree(entry);
 	} else {
 		qid = c4iw_get_resource(&rdev->resource.qid_table);
-		if (!qid)
+		if (!qid) {
+			mutex_lock(&rdev->stats.lock);
+			rdev->stats.qid.fail++;
+			mutex_unlock(&rdev->stats.lock);
 			goto out;
+		}
 		mutex_lock(&rdev->stats.lock);
 		rdev->stats.qid.cur += rdev->qpmask + 1;
 		mutex_unlock(&rdev->stats.lock);
@@ -322,8 +326,8 @@
 	unsigned long addr = gen_pool_alloc(rdev->rqt_pool, size << 6);
 	PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size << 6);
 	if (!addr)
-		printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n",
-		       pci_name(rdev->lldi.pdev));
+		pr_warn_ratelimited(MOD "%s: Out of RQT memory\n",
+				    pci_name(rdev->lldi.pdev));
 	mutex_lock(&rdev->stats.lock);
 	if (addr) {
 		rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT);
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h
index eeca8b1..2178f31 100644
--- a/drivers/infiniband/hw/cxgb4/t4.h
+++ b/drivers/infiniband/hw/cxgb4/t4.h
@@ -84,7 +84,14 @@
 			sizeof(struct fw_ri_isgl)) / sizeof(struct fw_ri_sge))
 #define T4_MAX_FR_IMMD ((T4_SQ_NUM_BYTES - sizeof(struct fw_ri_fr_nsmr_wr) - \
 			sizeof(struct fw_ri_immd)) & ~31UL)
-#define T4_MAX_FR_DEPTH (1024 / sizeof(u64))
+#define T4_MAX_FR_IMMD_DEPTH (T4_MAX_FR_IMMD / sizeof(u64))
+#define T4_MAX_FR_DSGL 1024
+#define T4_MAX_FR_DSGL_DEPTH (T4_MAX_FR_DSGL / sizeof(u64))
+
+static inline int t4_max_fr_depth(int use_dsgl)
+{
+	return use_dsgl ? T4_MAX_FR_DSGL_DEPTH : T4_MAX_FR_IMMD_DEPTH;
+}
 
 #define T4_RQ_NUM_SLOTS 2
 #define T4_RQ_NUM_BYTES (T4_EQ_ENTRY_SIZE * T4_RQ_NUM_SLOTS)
@@ -292,7 +299,7 @@
 	unsigned long phys_addr;
 	struct t4_swsqe *sw_sq;
 	struct t4_swsqe *oldest_read;
-	u64 udb;
+	u64 __iomem *udb;
 	size_t memsize;
 	u32 qid;
 	u16 in_use;
@@ -314,7 +321,7 @@
 	dma_addr_t dma_addr;
 	DEFINE_DMA_UNMAP_ADDR(mapping);
 	struct t4_swrqe *sw_rq;
-	u64 udb;
+	u64 __iomem *udb;
 	size_t memsize;
 	u32 qid;
 	u32 msn;
@@ -435,15 +442,67 @@
 		return wq->sq.size * T4_SQ_NUM_SLOTS;
 }
 
-static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc)
+/* This function copies 64 byte coalesced work request to memory
+ * mapped BAR2 space. For coalesced WRs, the SGE fetches data
+ * from the FIFO instead of from Host.
+ */
+static inline void pio_copy(u64 __iomem *dst, u64 *src)
 {
+	int count = 8;
+
+	while (count) {
+		writeq(*src, dst);
+		src++;
+		dst++;
+		count--;
+	}
+}
+
+static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc, u8 t5,
+				 union t4_wr *wqe)
+{
+
+	/* Flush host queue memory writes. */
 	wmb();
+	if (t5) {
+		if (inc == 1 && wqe) {
+			PDBG("%s: WC wq->sq.pidx = %d\n",
+			     __func__, wq->sq.pidx);
+			pio_copy(wq->sq.udb + 7, (void *)wqe);
+		} else {
+			PDBG("%s: DB wq->sq.pidx = %d\n",
+			     __func__, wq->sq.pidx);
+			writel(PIDX_T5(inc), wq->sq.udb);
+		}
+
+		/* Flush user doorbell area writes. */
+		wmb();
+		return;
+	}
 	writel(QID(wq->sq.qid) | PIDX(inc), wq->db);
 }
 
-static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc)
+static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc, u8 t5,
+				 union t4_recv_wr *wqe)
 {
+
+	/* Flush host queue memory writes. */
 	wmb();
+	if (t5) {
+		if (inc == 1 && wqe) {
+			PDBG("%s: WC wq->rq.pidx = %d\n",
+			     __func__, wq->rq.pidx);
+			pio_copy(wq->rq.udb + 7, (void *)wqe);
+		} else {
+			PDBG("%s: DB wq->rq.pidx = %d\n",
+			     __func__, wq->rq.pidx);
+			writel(PIDX_T5(inc), wq->rq.udb);
+		}
+
+		/* Flush user doorbell area writes. */
+		wmb();
+		return;
+	}
 	writel(QID(wq->rq.qid) | PIDX(inc), wq->db);
 }
 
@@ -568,6 +627,9 @@
 		printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid);
 		BUG_ON(1);
 	} else if (t4_valid_cqe(cq, &cq->queue[cq->cidx])) {
+
+		/* Ensure CQE is flushed to memory */
+		rmb();
 		*cqe = &cq->queue[cq->cidx];
 		ret = 0;
 	} else
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index fa6dc87..364d4b6 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -282,6 +282,8 @@
 		props->sig_guard_cap = IB_GUARD_T10DIF_CRC |
 				       IB_GUARD_T10DIF_CSUM;
 	}
+	if (flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)
+		props->device_cap_flags |= IB_DEVICE_BLOCK_MULTICAST_LOOPBACK;
 
 	props->vendor_id	   = be32_to_cpup((__be32 *)(out_mad->data + 36)) &
 		0xffffff;
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index ae788d27..dc930ed 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -807,6 +807,15 @@
 	spin_lock_init(&qp->sq.lock);
 	spin_lock_init(&qp->rq.lock);
 
+	if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
+		if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)) {
+			mlx5_ib_dbg(dev, "block multicast loopback isn't supported\n");
+			return -EINVAL;
+		} else {
+			qp->flags |= MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK;
+		}
+	}
+
 	if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
 		qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;
 
@@ -878,6 +887,9 @@
 	if (qp->wq_sig)
 		in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_ENABLE_SIG);
 
+	if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK)
+		in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_BLOCK_MCAST);
+
 	if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
 		int rcqe_sz;
 		int scqe_sz;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 87897b9..ded76c1 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -858,13 +858,9 @@
 	entries[1].entry = 1;
 	entries[2].entry = 2;
 
-	err = pci_enable_msix(mdev->pdev, entries, ARRAY_SIZE(entries));
-	if (err) {
-		if (err > 0)
-			mthca_info(mdev, "Only %d MSI-X vectors available, "
-				   "not using MSI-X\n", err);
+	err = pci_enable_msix_exact(mdev->pdev, entries, ARRAY_SIZE(entries));
+	if (err)
 		return err;
-	}
 
 	mdev->eq_table.eq[MTHCA_EQ_COMP ].msi_x_vector = entries[0].vector;
 	mdev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector = entries[1].vector;
diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c
index c8d9c4a..61a0046 100644
--- a/drivers/infiniband/hw/qib/qib_pcie.c
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -197,46 +197,47 @@
 			   struct qib_msix_entry *qib_msix_entry)
 {
 	int ret;
-	u32 tabsize = 0;
-	u16 msix_flags;
+	int nvec = *msixcnt;
 	struct msix_entry *msix_entry;
 	int i;
 
+	ret = pci_msix_vec_count(dd->pcidev);
+	if (ret < 0)
+		goto do_intx;
+
+	nvec = min(nvec, ret);
+
 	/* We can't pass qib_msix_entry array to qib_msix_setup
 	 * so use a dummy msix_entry array and copy the allocated
 	 * irq back to the qib_msix_entry array. */
-	msix_entry = kmalloc(*msixcnt * sizeof(*msix_entry), GFP_KERNEL);
-	if (!msix_entry) {
-		ret = -ENOMEM;
+	msix_entry = kmalloc(nvec * sizeof(*msix_entry), GFP_KERNEL);
+	if (!msix_entry)
 		goto do_intx;
-	}
-	for (i = 0; i < *msixcnt; i++)
+
+	for (i = 0; i < nvec; i++)
 		msix_entry[i] = qib_msix_entry[i].msix;
 
-	pci_read_config_word(dd->pcidev, pos + PCI_MSIX_FLAGS, &msix_flags);
-	tabsize = 1 + (msix_flags & PCI_MSIX_FLAGS_QSIZE);
-	if (tabsize > *msixcnt)
-		tabsize = *msixcnt;
-	ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize);
-	if (ret > 0) {
-		tabsize = ret;
-		ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize);
-	}
-do_intx:
-	if (ret) {
-		qib_dev_err(dd,
-			"pci_enable_msix %d vectors failed: %d, falling back to INTx\n",
-			tabsize, ret);
-		tabsize = 0;
-	}
-	for (i = 0; i < tabsize; i++)
+	ret = pci_enable_msix_range(dd->pcidev, msix_entry, 1, nvec);
+	if (ret < 0)
+		goto free_msix_entry;
+	else
+		nvec = ret;
+
+	for (i = 0; i < nvec; i++)
 		qib_msix_entry[i].msix = msix_entry[i];
+
 	kfree(msix_entry);
-	*msixcnt = tabsize;
+	*msixcnt = nvec;
+	return;
 
-	if (ret)
-		qib_enable_intx(dd->pcidev);
+free_msix_entry:
+	kfree(msix_entry);
 
+do_intx:
+	qib_dev_err(dd, "pci_enable_msix_range %d vectors failed: %d, "
+			"falling back to INTx\n", nvec, ret);
+	*msixcnt = 0;
+	qib_enable_intx(dd->pcidev);
 }
 
 /**
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index 37dab0b..7d35287 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -228,12 +229,17 @@
 static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc)
 {
 	u32 stat, hwirq;
+	struct irq_chip *host_chip = irq_desc_get_chip(desc);
 	struct vic_device *vic = irq_desc_get_handler_data(desc);
 
+	chained_irq_enter(host_chip, desc);
+
 	while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
 		hwirq = ffs(stat) - 1;
 		generic_handle_irq(irq_find_mapping(vic->domain, hwirq));
 	}
+
+	chained_irq_exit(host_chip, desc);
 }
 
 /*
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
index 8527743..3fdda3a 100644
--- a/drivers/irqchip/spear-shirq.c
+++ b/drivers/irqchip/spear-shirq.c
@@ -5,7 +5,7 @@
  * Viresh Kumar <viresh.linux@gmail.com>
  *
  * Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index 51dae91..96d1df0 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -425,7 +425,7 @@
 				if (cs->debug & L1_DEB_MONITOR)
 					debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]);
 			}
-		AfterMOX1:
+		AfterMOX1: ;
 #endif
 		}
 	}
diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c
index d1278b5..0049269 100644
--- a/drivers/mcb/mcb-parse.c
+++ b/drivers/mcb/mcb-parse.c
@@ -141,6 +141,7 @@
 		default:
 			pr_err("Invalid chameleon descriptor type 0x%x\n",
 				dtype);
+			kfree(header);
 			return -EINVAL;
 		}
 		num_cells++;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 25247a8..ad1b9be 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4370,8 +4370,7 @@
 		sh->group = NULL;
 	}
 	list_del_init(&sh->lru);
-	atomic_inc(&sh->count);
-	BUG_ON(atomic_read(&sh->count) != 1);
+	BUG_ON(atomic_inc_return(&sh->count) != 1);
 	return sh;
 }
 
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1cb7408..8baff0e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -300,8 +300,8 @@
 	depends on SGI_GRU
 	default n
 	---help---
-	This option enables addition debugging code for the SGI GRU driver. If
-	you are unsure, say N.
+	This option enables additional debugging code for the SGI GRU driver.
+	If you are unsure, say N.
 
 config APDS9802ALS
 	tristate "Medfield Avago APDS9802 ALS Sensor module"
diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h
index 5e4dbd2..0e608a2 100644
--- a/drivers/misc/genwqe/card_base.h
+++ b/drivers/misc/genwqe/card_base.h
@@ -337,6 +337,44 @@
 };
 
 /**
+ * struct genwqe_sgl - Scatter gather list describing user-space memory
+ * @sgl:            scatter gather list needs to be 128 byte aligned
+ * @sgl_dma_addr:   dma address of sgl
+ * @sgl_size:       size of area used for sgl
+ * @user_addr:      user-space address of memory area
+ * @user_size:      size of user-space memory area
+ * @page:           buffer for partial pages if needed
+ * @page_dma_addr:  dma address partial pages
+ */
+struct genwqe_sgl {
+	dma_addr_t sgl_dma_addr;
+	struct sg_entry *sgl;
+	size_t sgl_size;	/* size of sgl */
+
+	void __user *user_addr; /* user-space base-address */
+	size_t user_size;       /* size of memory area */
+
+	unsigned long nr_pages;
+	unsigned long fpage_offs;
+	size_t fpage_size;
+	size_t lpage_size;
+
+	void *fpage;
+	dma_addr_t fpage_dma_addr;
+
+	void *lpage;
+	dma_addr_t lpage_dma_addr;
+};
+
+int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+			  void __user *user_addr, size_t user_size);
+
+int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+		     dma_addr_t *dma_list);
+
+int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl);
+
+/**
  * struct ddcb_requ - Kernel internal representation of the DDCB request
  * @cmd:          User space representation of the DDCB execution request
  */
@@ -347,9 +385,7 @@
 	struct ddcb_queue *queue;	  /* associated queue */
 
 	struct dma_mapping  dma_mappings[DDCB_FIXUPS];
-	struct sg_entry     *sgl[DDCB_FIXUPS];
-	dma_addr_t	    sgl_dma_addr[DDCB_FIXUPS];
-	size_t		    sgl_size[DDCB_FIXUPS];
+	struct genwqe_sgl sgls[DDCB_FIXUPS];
 
 	/* kernel/user shared content */
 	struct genwqe_ddcb_cmd cmd;	/* ddcb_no for this request */
@@ -453,22 +489,6 @@
 int  genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m,
 			struct ddcb_requ *req);
 
-struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages,
-				 dma_addr_t *dma_addr, size_t *sgl_size);
-
-void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
-		    dma_addr_t dma_addr, size_t size);
-
-int genwqe_setup_sgl(struct genwqe_dev *cd,
-		    unsigned long offs,
-		    unsigned long size,
-		    struct sg_entry *sgl, /* genwqe sgl */
-		    dma_addr_t dma_addr, size_t sgl_size,
-		    dma_addr_t *dma_list, int page_offs, int num_pages);
-
-int genwqe_check_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
-		     int size);
-
 static inline bool dma_mapping_used(struct dma_mapping *m)
 {
 	if (!m)
diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c
index 6f1acc0..c8046db 100644
--- a/drivers/misc/genwqe/card_ddcb.c
+++ b/drivers/misc/genwqe/card_ddcb.c
@@ -305,6 +305,8 @@
 			break;
 
 		new = (old | DDCB_NEXT_BE32);
+
+		wmb();
 		icrc_hsi_shi = cmpxchg(&prev_ddcb->icrc_hsi_shi_32, old, new);
 
 		if (icrc_hsi_shi == old)
@@ -314,6 +316,8 @@
 	/* Queue must be re-started by updating QUEUE_OFFSET */
 	ddcb_mark_tapped(pddcb);
 	num = (u64)ddcb_no << 8;
+
+	wmb();
 	__genwqe_writeq(cd, queue->IO_QUEUE_OFFSET, num); /* start queue */
 
 	return RET_DDCB_TAPPED;
@@ -1306,7 +1310,7 @@
  */
 int genwqe_finish_queue(struct genwqe_dev *cd)
 {
-	int i, rc, in_flight;
+	int i, rc = 0, in_flight;
 	int waitmax = genwqe_ddcb_software_timeout;
 	struct pci_dev *pci_dev = cd->pci_dev;
 	struct ddcb_queue *queue = &cd->queue;
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c
index 2c2c9cc..1d2f163 100644
--- a/drivers/misc/genwqe/card_dev.c
+++ b/drivers/misc/genwqe/card_dev.c
@@ -531,7 +531,9 @@
 	case '1':
 		cmdopts = 0x1C;
 		break;		/* download/erase_first/part_1 */
-	case 'v':		/* cmdopts = 0x0c (VPD) */
+	case 'v':
+		cmdopts = 0x0C;
+		break;		/* download/erase_first/vpd */
 	default:
 		return -EINVAL;
 	}
@@ -665,6 +667,8 @@
 		cmdopts = 0x1A;
 		break;		/* upload/part_1 */
 	case 'v':
+		cmdopts = 0x0A;
+		break;		/* upload/vpd */
 	default:
 		return -EINVAL;
 	}
@@ -836,15 +840,8 @@
 			__genwqe_del_mapping(cfile, dma_map);
 			genwqe_user_vunmap(cd, dma_map, req);
 		}
-		if (req->sgl[i] != NULL) {
-			genwqe_free_sgl(cd, req->sgl[i],
-				       req->sgl_dma_addr[i],
-				       req->sgl_size[i]);
-			req->sgl[i] = NULL;
-			req->sgl_dma_addr[i] = 0x0;
-			req->sgl_size[i] = 0;
-		}
-
+		if (req->sgls[i].sgl != NULL)
+			genwqe_free_sync_sgl(cd, &req->sgls[i]);
 	}
 	return 0;
 }
@@ -913,7 +910,7 @@
 
 		case ATS_TYPE_SGL_RDWR:
 		case ATS_TYPE_SGL_RD: {
-			int page_offs, nr_pages, offs;
+			int page_offs;
 
 			u_addr = be64_to_cpu(*((__be64 *)
 					       &cmd->asiv[asiv_offs]));
@@ -951,27 +948,18 @@
 				page_offs = 0;
 			}
 
-			offs = offset_in_page(u_addr);
-			nr_pages = DIV_ROUND_UP(offs + u_size, PAGE_SIZE);
-
 			/* create genwqe style scatter gather list */
-			req->sgl[i] = genwqe_alloc_sgl(cd, m->nr_pages,
-						      &req->sgl_dma_addr[i],
-						      &req->sgl_size[i]);
-			if (req->sgl[i] == NULL) {
-				rc = -ENOMEM;
+			rc = genwqe_alloc_sync_sgl(cd, &req->sgls[i],
+						   (void __user *)u_addr,
+						   u_size);
+			if (rc != 0)
 				goto err_out;
-			}
-			genwqe_setup_sgl(cd, offs, u_size,
-					req->sgl[i],
-					req->sgl_dma_addr[i],
-					req->sgl_size[i],
-					m->dma_list,
-					page_offs,
-					nr_pages);
+
+			genwqe_setup_sgl(cd, &req->sgls[i],
+					 &m->dma_list[page_offs]);
 
 			*((__be64 *)&cmd->asiv[asiv_offs]) =
-				cpu_to_be64(req->sgl_dma_addr[i]);
+				cpu_to_be64(req->sgls[i].sgl_dma_addr);
 
 			break;
 		}
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index 6b1a6ef..d049d27 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -275,67 +275,107 @@
 	return roundup(len, PAGE_SIZE);
 }
 
-struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages,
-				  dma_addr_t *dma_addr, size_t *sgl_size)
+/**
+ * genwqe_alloc_sync_sgl() - Allocate memory for sgl and overlapping pages
+ *
+ * Allocates memory for sgl and overlapping pages. Pages which might
+ * overlap other user-space memory blocks are being cached for DMAs,
+ * such that we do not run into syncronization issues. Data is copied
+ * from user-space into the cached pages.
+ */
+int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+			  void __user *user_addr, size_t user_size)
 {
+	int rc;
 	struct pci_dev *pci_dev = cd->pci_dev;
-	struct sg_entry *sgl;
 
-	*sgl_size = genwqe_sgl_size(num_pages);
-	if (get_order(*sgl_size) > MAX_ORDER) {
+	sgl->fpage_offs = offset_in_page((unsigned long)user_addr);
+	sgl->fpage_size = min_t(size_t, PAGE_SIZE-sgl->fpage_offs, user_size);
+	sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE);
+	sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE;
+
+	dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld "
+		"fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n",
+		__func__, user_addr, user_size, sgl->nr_pages,
+		sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size);
+
+	sgl->user_addr = user_addr;
+	sgl->user_size = user_size;
+	sgl->sgl_size = genwqe_sgl_size(sgl->nr_pages);
+
+	if (get_order(sgl->sgl_size) > MAX_ORDER) {
 		dev_err(&pci_dev->dev,
 			"[%s] err: too much memory requested!\n", __func__);
-		return NULL;
+		return -ENOMEM;
 	}
 
-	sgl = __genwqe_alloc_consistent(cd, *sgl_size, dma_addr);
-	if (sgl == NULL) {
+	sgl->sgl = __genwqe_alloc_consistent(cd, sgl->sgl_size,
+					     &sgl->sgl_dma_addr);
+	if (sgl->sgl == NULL) {
 		dev_err(&pci_dev->dev,
 			"[%s] err: no memory available!\n", __func__);
-		return NULL;
+		return -ENOMEM;
 	}
 
-	return sgl;
+	/* Only use buffering on incomplete pages */
+	if ((sgl->fpage_size != 0) && (sgl->fpage_size != PAGE_SIZE)) {
+		sgl->fpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
+						       &sgl->fpage_dma_addr);
+		if (sgl->fpage == NULL)
+			goto err_out;
+
+		/* Sync with user memory */
+		if (copy_from_user(sgl->fpage + sgl->fpage_offs,
+				   user_addr, sgl->fpage_size)) {
+			rc = -EFAULT;
+			goto err_out;
+		}
+	}
+	if (sgl->lpage_size != 0) {
+		sgl->lpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
+						       &sgl->lpage_dma_addr);
+		if (sgl->lpage == NULL)
+			goto err_out1;
+
+		/* Sync with user memory */
+		if (copy_from_user(sgl->lpage, user_addr + user_size -
+				   sgl->lpage_size, sgl->lpage_size)) {
+			rc = -EFAULT;
+			goto err_out1;
+		}
+	}
+	return 0;
+
+ err_out1:
+	__genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
+				 sgl->fpage_dma_addr);
+ err_out:
+	__genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
+				 sgl->sgl_dma_addr);
+	return -ENOMEM;
 }
 
-int genwqe_setup_sgl(struct genwqe_dev *cd,
-		     unsigned long offs,
-		     unsigned long size,
-		     struct sg_entry *sgl,
-		     dma_addr_t dma_addr, size_t sgl_size,
-		     dma_addr_t *dma_list, int page_offs, int num_pages)
+int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+		     dma_addr_t *dma_list)
 {
 	int i = 0, j = 0, p;
 	unsigned long dma_offs, map_offs;
-	struct pci_dev *pci_dev = cd->pci_dev;
 	dma_addr_t prev_daddr = 0;
 	struct sg_entry *s, *last_s = NULL;
-
-	/* sanity checks */
-	if (offs > PAGE_SIZE) {
-		dev_err(&pci_dev->dev,
-			"[%s] too large start offs %08lx\n", __func__, offs);
-		return -EFAULT;
-	}
-	if (sgl_size < genwqe_sgl_size(num_pages)) {
-		dev_err(&pci_dev->dev,
-			"[%s] sgl_size too small %08lx for %d pages\n",
-			__func__, sgl_size, num_pages);
-		return -EFAULT;
-	}
+	size_t size = sgl->user_size;
 
 	dma_offs = 128;		/* next block if needed/dma_offset */
-	map_offs = offs;	/* offset in first page */
+	map_offs = sgl->fpage_offs; /* offset in first page */
 
-	s = &sgl[0];		/* first set of 8 entries */
+	s = &sgl->sgl[0];	/* first set of 8 entries */
 	p = 0;			/* page */
-	while (p < num_pages) {
+	while (p < sgl->nr_pages) {
 		dma_addr_t daddr;
 		unsigned int size_to_map;
 
 		/* always write the chaining entry, cleanup is done later */
 		j = 0;
-		s[j].target_addr = cpu_to_be64(dma_addr + dma_offs);
+		s[j].target_addr = cpu_to_be64(sgl->sgl_dma_addr + dma_offs);
 		s[j].len	 = cpu_to_be32(128);
 		s[j].flags	 = cpu_to_be32(SG_CHAINED);
 		j++;
@@ -343,7 +383,17 @@
 		while (j < 8) {
 			/* DMA mapping for requested page, offs, size */
 			size_to_map = min(size, PAGE_SIZE - map_offs);
-			daddr = dma_list[page_offs + p] + map_offs;
+
+			if ((p == 0) && (sgl->fpage != NULL)) {
+				daddr = sgl->fpage_dma_addr + map_offs;
+
+			} else if ((p == sgl->nr_pages - 1) &&
+				   (sgl->lpage != NULL)) {
+				daddr = sgl->lpage_dma_addr;
+			} else {
+				daddr = dma_list[p] + map_offs;
+			}
+
 			size -= size_to_map;
 			map_offs = 0;
 
@@ -358,7 +408,7 @@
 							  size_to_map);
 
 				p++; /* process next page */
-				if (p == num_pages)
+				if (p == sgl->nr_pages)
 					goto fixup;  /* nothing to do */
 
 				prev_daddr = daddr + size_to_map;
@@ -374,7 +424,7 @@
 			j++;
 
 			p++;	/* process next page */
-			if (p == num_pages)
+			if (p == sgl->nr_pages)
 				goto fixup;  /* nothing to do */
 		}
 		dma_offs += 128;
@@ -395,10 +445,50 @@
 	return 0;
 }
 
-void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
-		    dma_addr_t dma_addr, size_t size)
+/**
+ * genwqe_free_sync_sgl() - Free memory for sgl and overlapping pages
+ *
+ * After the DMA transfer has been completed we free the memory for
+ * the sgl and the cached pages. Data is being transfered from cached
+ * pages into user-space buffers.
+ */
+int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl)
 {
-	__genwqe_free_consistent(cd, size, sg_list, dma_addr);
+	int rc;
+	struct pci_dev *pci_dev = cd->pci_dev;
+
+	if (sgl->fpage) {
+		if (copy_to_user(sgl->user_addr, sgl->fpage + sgl->fpage_offs,
+				 sgl->fpage_size)) {
+			dev_err(&pci_dev->dev, "[%s] err: copying fpage!\n",
+				__func__);
+			rc = -EFAULT;
+		}
+		__genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
+					 sgl->fpage_dma_addr);
+		sgl->fpage = NULL;
+		sgl->fpage_dma_addr = 0;
+	}
+	if (sgl->lpage) {
+		if (copy_to_user(sgl->user_addr + sgl->user_size -
+				 sgl->lpage_size, sgl->lpage,
+				 sgl->lpage_size)) {
+			dev_err(&pci_dev->dev, "[%s] err: copying lpage!\n",
+				__func__);
+			rc = -EFAULT;
+		}
+		__genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage,
+					 sgl->lpage_dma_addr);
+		sgl->lpage = NULL;
+		sgl->lpage_dma_addr = 0;
+	}
+	__genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
+				 sgl->sgl_dma_addr);
+
+	sgl->sgl = NULL;
+	sgl->sgl_dma_addr = 0x0;
+	sgl->sgl_size = 0;
+	return rc;
 }
 
 /**
diff --git a/drivers/misc/genwqe/genwqe_driver.h b/drivers/misc/genwqe/genwqe_driver.h
index 46e916b..cd52631 100644
--- a/drivers/misc/genwqe/genwqe_driver.h
+++ b/drivers/misc/genwqe/genwqe_driver.h
@@ -36,7 +36,7 @@
 #include <asm/byteorder.h>
 #include <linux/genwqe/genwqe_card.h>
 
-#define DRV_VERS_STRING		"2.0.0"
+#define DRV_VERS_STRING		"2.0.15"
 
 /*
  * Static minor number assignement, until we decide/implement
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index 66f411a..cabc043 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -115,6 +115,11 @@
 #define MEI_DEV_ID_LPT_HR     0x8CBA  /* Lynx Point H Refresh */
 
 #define MEI_DEV_ID_WPT_LP     0x9CBA  /* Wildcat Point LP */
+
+/* Host Firmware Status Registers in PCI Config Space */
+#define PCI_CFG_HFS_1         0x40
+#define PCI_CFG_HFS_2         0x48
+
 /*
  * MEI HW Section
  */
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 29b5af8..4e3cba6d 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -455,8 +455,7 @@
 
 		cl->status = 0;
 		list_del(&cb->list);
-		if (MEI_WRITING == cl->writing_state &&
-		    cb->fop_type == MEI_FOP_WRITE &&
+		if (cb->fop_type == MEI_FOP_WRITE &&
 		    cl != &dev->iamthif_cl) {
 			cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
 			cl->writing_state = MEI_WRITE_COMPLETE;
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index b35594d..1474131 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -644,8 +644,7 @@
 		goto out;
 	}
 
-	if (MEI_WRITE_COMPLETE == cl->writing_state)
-		mask |= (POLLIN | POLLRDNORM);
+	mask |= (POLLIN | POLLRDNORM);
 
 out:
 	mutex_unlock(&dev->device_lock);
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 1c8fd3a..95889e2 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -97,15 +97,31 @@
 				const struct pci_device_id *ent)
 {
 	u32 reg;
-	if (ent->device == MEI_DEV_ID_PBG_1) {
-		pci_read_config_dword(pdev, 0x48, &reg);
-		/* make sure that bit 9 is up and bit 10 is down */
-		if ((reg & 0x600) == 0x200) {
-			dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
-			return false;
-		}
+	/* Cougar Point || Patsburg */
+	if (ent->device == MEI_DEV_ID_CPT_1 ||
+	    ent->device == MEI_DEV_ID_PBG_1) {
+		pci_read_config_dword(pdev, PCI_CFG_HFS_2, &reg);
+		/* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
+		if ((reg & 0x600) == 0x200)
+			goto no_mei;
 	}
+
+	/* Lynx Point */
+	if (ent->device == MEI_DEV_ID_LPT_H  ||
+	    ent->device == MEI_DEV_ID_LPT_W  ||
+	    ent->device == MEI_DEV_ID_LPT_HR) {
+		/* Read ME FW Status check for SPS Firmware */
+		pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
+		/* if bits [19:16] = 15, running SPS Firmware */
+		if ((reg & 0xf0000) == 0xf0000)
+			goto no_mei;
+	}
+
 	return true;
+
+no_mei:
+	dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
+	return false;
 }
 /**
  * mei_probe - Device Initialization Routine
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index 363da96..c4176b0 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -6,7 +6,7 @@
  *
  * Copyright © 2010 STMicroelectronics.
  * Ashish Priyadarshi
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
@@ -1089,5 +1089,5 @@
 module_platform_driver(spear_smi_driver);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
 MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index b667a51..9a0d61e 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2440,7 +2440,7 @@
 		goto err_free;
 	}
 
-	slave_agg_no = bond_xmit_hash(bond, skb, slaves_in_agg);
+	slave_agg_no = bond_xmit_hash(bond, skb) % slaves_in_agg;
 	first_ok_slave = NULL;
 
 	bond_for_each_slave_rcu(bond, slave, iter) {
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 9f69e81..70de039 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1347,6 +1347,77 @@
 		rlb_deinitialize(bond);
 }
 
+static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
+		struct slave *tx_slave)
+{
+	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+	struct ethhdr *eth_data = eth_hdr(skb);
+
+	if (!tx_slave) {
+		/* unbalanced or unassigned, send through primary */
+		tx_slave = rcu_dereference(bond->curr_active_slave);
+		if (bond->params.tlb_dynamic_lb)
+			bond_info->unbalanced_load += skb->len;
+	}
+
+	if (tx_slave && SLAVE_IS_OK(tx_slave)) {
+		if (tx_slave != rcu_dereference(bond->curr_active_slave)) {
+			ether_addr_copy(eth_data->h_source,
+					tx_slave->dev->dev_addr);
+		}
+
+		bond_dev_queue_xmit(bond, skb, tx_slave->dev);
+		goto out;
+	}
+
+	if (tx_slave && bond->params.tlb_dynamic_lb) {
+		_lock_tx_hashtbl(bond);
+		__tlb_clear_slave(bond, tx_slave, 0);
+		_unlock_tx_hashtbl(bond);
+	}
+
+	/* no suitable interface, frame not sent */
+	dev_kfree_skb_any(skb);
+out:
+	return NETDEV_TX_OK;
+}
+
+int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
+{
+	struct bonding *bond = netdev_priv(bond_dev);
+	struct ethhdr *eth_data;
+	struct slave *tx_slave = NULL;
+	u32 hash_index;
+
+	skb_reset_mac_header(skb);
+	eth_data = eth_hdr(skb);
+
+	/* Do not TX balance any multicast or broadcast */
+	if (!is_multicast_ether_addr(eth_data->h_dest)) {
+		switch (skb->protocol) {
+		case htons(ETH_P_IP):
+		case htons(ETH_P_IPX):
+		    /* In case of IPX, it will falback to L2 hash */
+		case htons(ETH_P_IPV6):
+			hash_index = bond_xmit_hash(bond, skb);
+			if (bond->params.tlb_dynamic_lb) {
+				tx_slave = tlb_choose_channel(bond,
+							      hash_index & 0xFF,
+							      skb->len);
+			} else {
+				struct list_head *iter;
+				int idx = hash_index % bond->slave_cnt;
+
+				bond_for_each_slave_rcu(bond, tx_slave, iter)
+					if (--idx < 0)
+						break;
+			}
+			break;
+		}
+	}
+	return bond_do_alb_xmit(skb, bond, tx_slave);
+}
+
 int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
@@ -1355,7 +1426,7 @@
 	struct slave *tx_slave = NULL;
 	static const __be32 ip_bcast = htonl(0xffffffff);
 	int hash_size = 0;
-	int do_tx_balance = 1;
+	bool do_tx_balance = true;
 	u32 hash_index = 0;
 	const u8 *hash_start = NULL;
 	struct ipv6hdr *ip6hdr;
@@ -1370,7 +1441,7 @@
 		if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) ||
 		    (iph->daddr == ip_bcast) ||
 		    (iph->protocol == IPPROTO_IGMP)) {
-			do_tx_balance = 0;
+			do_tx_balance = false;
 			break;
 		}
 		hash_start = (char *)&(iph->daddr);
@@ -1382,7 +1453,7 @@
 		 * that here just in case.
 		 */
 		if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast)) {
-			do_tx_balance = 0;
+			do_tx_balance = false;
 			break;
 		}
 
@@ -1390,7 +1461,7 @@
 		 * broadcasts in IPv4.
 		 */
 		if (ether_addr_equal_64bits(eth_data->h_dest, mac_v6_allmcast)) {
-			do_tx_balance = 0;
+			do_tx_balance = false;
 			break;
 		}
 
@@ -1400,7 +1471,7 @@
 		 */
 		ip6hdr = ipv6_hdr(skb);
 		if (ipv6_addr_any(&ip6hdr->saddr)) {
-			do_tx_balance = 0;
+			do_tx_balance = false;
 			break;
 		}
 
@@ -1410,7 +1481,7 @@
 	case ETH_P_IPX:
 		if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) {
 			/* something is wrong with this packet */
-			do_tx_balance = 0;
+			do_tx_balance = false;
 			break;
 		}
 
@@ -1419,7 +1490,7 @@
 			 * this family since it has an "ARP" like
 			 * mechanism
 			 */
-			do_tx_balance = 0;
+			do_tx_balance = false;
 			break;
 		}
 
@@ -1427,12 +1498,12 @@
 		hash_size = ETH_ALEN;
 		break;
 	case ETH_P_ARP:
-		do_tx_balance = 0;
+		do_tx_balance = false;
 		if (bond_info->rlb_enabled)
 			tx_slave = rlb_arp_xmit(skb, bond);
 		break;
 	default:
-		do_tx_balance = 0;
+		do_tx_balance = false;
 		break;
 	}
 
@@ -1441,32 +1512,7 @@
 		tx_slave = tlb_choose_channel(bond, hash_index, skb->len);
 	}
 
-	if (!tx_slave) {
-		/* unbalanced or unassigned, send through primary */
-		tx_slave = rcu_dereference(bond->curr_active_slave);
-		bond_info->unbalanced_load += skb->len;
-	}
-
-	if (tx_slave && SLAVE_IS_OK(tx_slave)) {
-		if (tx_slave != rcu_dereference(bond->curr_active_slave)) {
-			ether_addr_copy(eth_data->h_source,
-					tx_slave->dev->dev_addr);
-		}
-
-		bond_dev_queue_xmit(bond, skb, tx_slave->dev);
-		goto out;
-	}
-
-	if (tx_slave) {
-		_lock_tx_hashtbl(bond);
-		__tlb_clear_slave(bond, tx_slave, 0);
-		_unlock_tx_hashtbl(bond);
-	}
-
-	/* no suitable interface, frame not sent */
-	dev_kfree_skb_any(skb);
-out:
-	return NETDEV_TX_OK;
+	return bond_do_alb_xmit(skb, bond, tx_slave);
 }
 
 void bond_alb_monitor(struct work_struct *work)
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index e09dd4bf..5fc76c0 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -175,6 +175,7 @@
 void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
 int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
 void bond_alb_monitor(struct work_struct *);
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
 void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 69aff72..9d08e00 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3015,20 +3015,18 @@
  * bond_xmit_hash - generate a hash value based on the xmit policy
  * @bond: bonding device
  * @skb: buffer to use for headers
- * @count: modulo value
  *
  * This function will extract the necessary headers from the skb buffer and use
  * them to generate a hash based on the xmit_policy set in the bonding device
- * which will be reduced modulo count before returning.
  */
-int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count)
+u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb)
 {
 	struct flow_keys flow;
 	u32 hash;
 
 	if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 ||
 	    !bond_flow_dissect(bond, skb, &flow))
-		return bond_eth_hash(skb) % count;
+		return bond_eth_hash(skb);
 
 	if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23 ||
 	    bond->params.xmit_policy == BOND_XMIT_POLICY_ENCAP23)
@@ -3039,7 +3037,7 @@
 	hash ^= (hash >> 16);
 	hash ^= (hash >> 8);
 
-	return hash % count;
+	return hash;
 }
 
 /*-------------------------- Device entry points ----------------------------*/
@@ -3098,7 +3096,8 @@
 		 */
 		if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB)))
 			return -ENOMEM;
-		queue_delayed_work(bond->wq, &bond->alb_work, 0);
+		if (bond->params.tlb_dynamic_lb)
+			queue_delayed_work(bond->wq, &bond->alb_work, 0);
 	}
 
 	if (bond->params.miimon)  /* link check interval, in milliseconds. */
@@ -3666,7 +3665,7 @@
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 
-	bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb, bond->slave_cnt));
+	bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb) % bond->slave_cnt);
 
 	return NETDEV_TX_OK;
 }
@@ -3776,8 +3775,9 @@
 	case BOND_MODE_8023AD:
 		return bond_3ad_xmit_xor(skb, dev);
 	case BOND_MODE_ALB:
-	case BOND_MODE_TLB:
 		return bond_alb_xmit(skb, dev);
+	case BOND_MODE_TLB:
+		return bond_tlb_xmit(skb, dev);
 	default:
 		/* Should never happen, mode already checked */
 		pr_err("%s: Error: Unknown bonding mode %d\n",
@@ -3998,7 +3998,8 @@
 
 	if (xmit_hash_policy) {
 		if ((bond_mode != BOND_MODE_XOR) &&
-		    (bond_mode != BOND_MODE_8023AD)) {
+		    (bond_mode != BOND_MODE_8023AD) &&
+		    (bond_mode != BOND_MODE_TLB)) {
 			pr_info("xmit_hash_policy param is irrelevant in mode %s\n",
 				bond_mode_name(bond_mode));
 		} else {
@@ -4304,6 +4305,7 @@
 	params->min_links = min_links;
 	params->lp_interval = lp_interval;
 	params->packets_per_slave = packets_per_slave;
+	params->tlb_dynamic_lb = 1; /* Default value */
 	if (packets_per_slave > 0) {
 		params->reciprocal_packets_per_slave =
 			reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 724e30f..9fba7a1 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -70,6 +70,8 @@
 				const struct bond_opt_value *newval);
 static int bond_option_slaves_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
+static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
+				  const struct bond_opt_value *newval);
 
 
 static const struct bond_opt_value bond_mode_tbl[] = {
@@ -179,6 +181,12 @@
 	{ NULL,      -1,      0},
 };
 
+static const struct bond_opt_value bond_tlb_dynamic_lb_tbl[] = {
+	{ "off", 0,  0},
+	{ "on",  1,  BOND_VALFLAG_DEFAULT},
+	{ NULL,  -1, 0}
+};
+
 static const struct bond_option bond_opts[] = {
 	[BOND_OPT_MODE] = {
 		.id = BOND_OPT_MODE,
@@ -199,7 +207,7 @@
 	[BOND_OPT_XMIT_HASH] = {
 		.id = BOND_OPT_XMIT_HASH,
 		.name = "xmit_hash_policy",
-		.desc = "balance-xor and 802.3ad hashing method",
+		.desc = "balance-xor, 802.3ad, and tlb hashing method",
 		.values = bond_xmit_hashtype_tbl,
 		.set = bond_option_xmit_hash_policy_set
 	},
@@ -364,6 +372,15 @@
 		.flags = BOND_OPTFLAG_RAWVAL,
 		.set = bond_option_slaves_set
 	},
+	[BOND_OPT_TLB_DYNAMIC_LB] = {
+		.id = BOND_OPT_TLB_DYNAMIC_LB,
+		.name = "dynamic_lb",
+		.desc = "Enable dynamic flow shuffling",
+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_TLB)),
+		.values = bond_tlb_dynamic_lb_tbl,
+		.flags = BOND_OPTFLAG_IFDOWN,
+		.set = bond_option_tlb_dynamic_lb_set,
+	},
 	{ }
 };
 
@@ -1337,3 +1354,13 @@
 	ret = -EPERM;
 	goto out;
 }
+
+static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
+					  const struct bond_opt_value *newval)
+{
+	pr_info("%s: Setting dynamic-lb to %s (%llu)\n",
+		bond->dev->name, newval->string, newval->value);
+	bond->params.tlb_dynamic_lb = newval->value;
+
+	return 0;
+}
diff --git a/drivers/net/bonding/bond_options.h b/drivers/net/bonding/bond_options.h
index 12be9e1..c1860f0 100644
--- a/drivers/net/bonding/bond_options.h
+++ b/drivers/net/bonding/bond_options.h
@@ -62,6 +62,7 @@
 	BOND_OPT_RESEND_IGMP,
 	BOND_OPT_LP_INTERVAL,
 	BOND_OPT_SLAVES,
+	BOND_OPT_TLB_DYNAMIC_LB,
 	BOND_OPT_LAST
 };
 
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 0e8b268..431892f 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1039,6 +1039,34 @@
 static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
 		   bonding_show_lp_interval, bonding_store_lp_interval);
 
+static ssize_t bonding_show_tlb_dynamic_lb(struct device *d,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct bonding *bond = to_bond(d);
+	return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb);
+}
+
+static ssize_t bonding_store_tlb_dynamic_lb(struct device *d,
+					    struct device_attribute *attr,
+					    const char *buf,
+					    size_t count)
+{
+	struct bonding *bond = to_bond(d);
+	int ret;
+
+	ret = bond_opt_tryset_rtnl(bond, BOND_OPT_TLB_DYNAMIC_LB,
+				   (char *)buf);
+	if (!ret)
+		ret = count;
+
+	return ret;
+}
+
+static DEVICE_ATTR(tlb_dynamic_lb, S_IRUGO | S_IWUSR,
+		   bonding_show_tlb_dynamic_lb,
+		   bonding_store_tlb_dynamic_lb);
+
 static ssize_t bonding_show_packets_per_slave(struct device *d,
 					      struct device_attribute *attr,
 					      char *buf)
@@ -1099,6 +1127,7 @@
 	&dev_attr_min_links.attr,
 	&dev_attr_lp_interval.attr,
 	&dev_attr_packets_per_slave.attr,
+	&dev_attr_tlb_dynamic_lb.attr,
 	NULL,
 };
 
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index b8bdd0a..c1c7c2f 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -174,6 +174,7 @@
 	int resend_igmp;
 	int lp_interval;
 	int packets_per_slave;
+	int tlb_dynamic_lb;
 	struct reciprocal_value reciprocal_packets_per_slave;
 };
 
@@ -499,7 +500,7 @@
 void bond_sysfs_slave_del(struct slave *slave);
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
 int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count);
+u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb);
 void bond_select_active_slave(struct bonding *bond);
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_create_debugfs(void);
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 9e7d95d..4aacaa9 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -77,12 +77,6 @@
 	  Driver for TI HECC (High End CAN Controller) module found on many
 	  TI devices. The device specifications are available from www.ti.com
 
-config CAN_MCP251X
-	tristate "Microchip MCP251x SPI CAN controllers"
-	depends on SPI && HAS_DMA
-	---help---
-	  Driver for the Microchip MCP251x SPI CAN controllers.
-
 config CAN_BFIN
 	depends on BF534 || BF536 || BF537 || BF538 || BF539 || BF54x
 	tristate "Analog Devices Blackfin on-chip CAN"
@@ -133,6 +127,8 @@
 
 source "drivers/net/can/cc770/Kconfig"
 
+source "drivers/net/can/spi/Kconfig"
+
 source "drivers/net/can/usb/Kconfig"
 
 source "drivers/net/can/softing/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index c744039..c420588 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -10,6 +10,7 @@
 
 can-dev-$(CONFIG_CAN_LEDS)	+= led.o
 
+obj-y				+= spi/
 obj-y				+= usb/
 obj-y				+= softing/
 
@@ -19,7 +20,6 @@
 obj-$(CONFIG_CAN_CC770)		+= cc770/
 obj-$(CONFIG_CAN_AT91)		+= at91_can.o
 obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
-obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
 obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_FLEXCAN)	+= flexcan.o
diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c
index bce0be5..7ab384f 100644
--- a/drivers/net/can/c_can/c_can_pci.c
+++ b/drivers/net/can/c_can/c_can_pci.c
@@ -19,9 +19,13 @@
 
 #include "c_can.h"
 
+#define PCI_DEVICE_ID_PCH_CAN	0x8818
+#define PCH_PCI_SOFT_RESET	0x01fc
+
 enum c_can_pci_reg_align {
 	C_CAN_REG_ALIGN_16,
 	C_CAN_REG_ALIGN_32,
+	C_CAN_REG_32,
 };
 
 struct c_can_pci_data {
@@ -31,6 +35,10 @@
 	enum c_can_pci_reg_align reg_align;
 	/* Set the frequency */
 	unsigned int freq;
+	/* PCI bar number */
+	int bar;
+	/* Callback for reset */
+	void (*init)(const struct c_can_priv *priv, bool enable);
 };
 
 /*
@@ -63,6 +71,29 @@
 	writew(val, priv->base + 2 * priv->regs[index]);
 }
 
+static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv,
+				    enum reg index)
+{
+	return (u16)ioread32(priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_pci_write_reg_32bit(struct c_can_priv *priv,
+				      enum reg index, u16 val)
+{
+	iowrite32((u32)val, priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable)
+{
+	if (enable) {
+		u32 __iomem *addr = priv->base + PCH_PCI_SOFT_RESET;
+
+		/* write to sw reset register */
+		iowrite32(1, addr);
+		iowrite32(0, addr);
+	}
+}
+
 static int c_can_pci_probe(struct pci_dev *pdev,
 			   const struct pci_device_id *ent)
 {
@@ -87,7 +118,8 @@
 	pci_set_master(pdev);
 	pci_enable_msi(pdev);
 
-	addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
+	addr = pci_iomap(pdev, c_can_pci_data->bar,
+			 pci_resource_len(pdev, c_can_pci_data->bar));
 	if (!addr) {
 		dev_err(&pdev->dev,
 			"device has no PCI memory resources, "
@@ -142,11 +174,17 @@
 		priv->read_reg = c_can_pci_read_reg_aligned_to_16bit;
 		priv->write_reg = c_can_pci_write_reg_aligned_to_16bit;
 		break;
+	case C_CAN_REG_32:
+		priv->read_reg = c_can_pci_read_reg_32bit;
+		priv->write_reg = c_can_pci_write_reg_32bit;
+		break;
 	default:
 		ret = -EINVAL;
 		goto out_free_c_can;
 	}
 
+	priv->raminit = c_can_pci_data->init;
+
 	ret = register_c_can_dev(dev);
 	if (ret) {
 		dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
@@ -193,6 +231,15 @@
 	.type = BOSCH_C_CAN,
 	.reg_align = C_CAN_REG_ALIGN_32,
 	.freq = 52000000, /* 52 Mhz */
+	.bar = 0,
+};
+
+static struct c_can_pci_data c_can_pch = {
+	.type = BOSCH_C_CAN,
+	.reg_align = C_CAN_REG_32,
+	.freq = 50000000, /* 50 MHz */
+	.init = c_can_pci_reset_pch,
+	.bar = 1,
 };
 
 #define C_CAN_ID(_vend, _dev, _driverdata) {		\
@@ -202,6 +249,8 @@
 static DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = {
 	C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN,
 		 c_can_sta2x11),
+	C_CAN_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_CAN,
+		 c_can_pch),
 	{},
 };
 static struct pci_driver c_can_pci_driver = {
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index 7d8c8f3..bacd236 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -556,15 +556,6 @@
 /*
  * netdev sysfs
  */
-static ssize_t show_channel(struct device *dev, struct device_attribute *attr,
-		char *buf)
-{
-	struct net_device *ndev = to_net_dev(dev);
-	struct softing_priv *priv = netdev2softing(ndev);
-
-	return sprintf(buf, "%i\n", priv->index);
-}
-
 static ssize_t show_chip(struct device *dev, struct device_attribute *attr,
 		char *buf)
 {
@@ -609,12 +600,10 @@
 	return count;
 }
 
-static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
 static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL);
 static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output);
 
 static const struct attribute *const netdev_sysfs_attrs[] = {
-	&dev_attr_channel.attr,
 	&dev_attr_chip.attr,
 	&dev_attr_output.attr,
 	NULL,
@@ -679,17 +668,20 @@
 {
 	int ret;
 
-	netdev->sysfs_groups[0] = &netdev_sysfs_group;
 	ret = register_candev(netdev);
 	if (ret) {
 		dev_alert(&netdev->dev, "register failed\n");
 		return ret;
 	}
+	if (sysfs_create_group(&netdev->dev.kobj, &netdev_sysfs_group) < 0)
+		netdev_alert(netdev, "sysfs group failed\n");
+
 	return 0;
 }
 
 static void softing_netdev_cleanup(struct net_device *netdev)
 {
+	sysfs_remove_group(&netdev->dev.kobj, &netdev_sysfs_group);
 	unregister_candev(netdev);
 	free_candev(netdev);
 }
@@ -721,8 +713,6 @@
 DEV_ATTR_RO_STR(hardware, pdat->name);
 DEV_ATTR_RO(hardware_version, id.hw_version);
 DEV_ATTR_RO(license, id.license);
-DEV_ATTR_RO(frequency, id.freq);
-DEV_ATTR_RO(txpending, tx.pending);
 
 static struct attribute *softing_pdev_attrs[] = {
 	&dev_attr_serial.attr,
@@ -731,8 +721,6 @@
 	&dev_attr_hardware.attr,
 	&dev_attr_hardware_version.attr,
 	&dev_attr_license.attr,
-	&dev_attr_frequency.attr,
-	&dev_attr_txpending.attr,
 	NULL,
 };
 
diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig
new file mode 100644
index 0000000..148cae5
--- /dev/null
+++ b/drivers/net/can/spi/Kconfig
@@ -0,0 +1,10 @@
+menu "CAN SPI interfaces"
+	depends on SPI
+
+config CAN_MCP251X
+	tristate "Microchip MCP251x SPI CAN controllers"
+	depends on HAS_DMA
+	---help---
+	  Driver for the Microchip MCP251x SPI CAN controllers.
+
+endmenu
diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile
new file mode 100644
index 0000000..90bcacf
--- /dev/null
+++ b/drivers/net/can/spi/Makefile
@@ -0,0 +1,8 @@
+#
+#  Makefile for the Linux Controller Area Network SPI drivers.
+#
+
+
+obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/spi/mcp251x.c
similarity index 96%
rename from drivers/net/can/mcp251x.c
rename to drivers/net/can/spi/mcp251x.c
index 28c11f8..bc235f9 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -214,6 +214,8 @@
 
 #define TX_ECHO_SKB_MAX	1
 
+#define MCP251X_OST_DELAY_MS	(5)
+
 #define DEVICE_NAME "mcp251x"
 
 static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
@@ -624,50 +626,45 @@
 static int mcp251x_hw_reset(struct spi_device *spi)
 {
 	struct mcp251x_priv *priv = spi_get_drvdata(spi);
+	u8 reg;
 	int ret;
-	unsigned long timeout;
+
+	/* Wait for oscillator startup timer after power up */
+	mdelay(MCP251X_OST_DELAY_MS);
 
 	priv->spi_tx_buf[0] = INSTRUCTION_RESET;
-	ret = spi_write(spi, priv->spi_tx_buf, 1);
-	if (ret) {
-		dev_err(&spi->dev, "reset failed: ret = %d\n", ret);
-		return -EIO;
-	}
+	ret = mcp251x_spi_trans(spi, 1);
+	if (ret)
+		return ret;
 
-	/* Wait for reset to finish */
-	timeout = jiffies + HZ;
-	mdelay(10);
-	while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK)
-	       != CANCTRL_REQOP_CONF) {
-		schedule();
-		if (time_after(jiffies, timeout)) {
-			dev_err(&spi->dev, "MCP251x didn't"
-				" enter in conf mode after reset\n");
-			return -EBUSY;
-		}
-	}
+	/* Wait for oscillator startup timer after reset */
+	mdelay(MCP251X_OST_DELAY_MS);
+	
+	reg = mcp251x_read_reg(spi, CANSTAT);
+	if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
+		return -ENODEV;
+
 	return 0;
 }
 
 static int mcp251x_hw_probe(struct spi_device *spi)
 {
-	int st1, st2;
+	u8 ctrl;
+	int ret;
 
-	mcp251x_hw_reset(spi);
+	ret = mcp251x_hw_reset(spi);
+	if (ret)
+		return ret;
 
-	/*
-	 * Please note that these are "magic values" based on after
-	 * reset defaults taken from data sheet which allows us to see
-	 * if we really have a chip on the bus (we avoid common all
-	 * zeroes or all ones situations)
-	 */
-	st1 = mcp251x_read_reg(spi, CANSTAT) & 0xEE;
-	st2 = mcp251x_read_reg(spi, CANCTRL) & 0x17;
+	ctrl = mcp251x_read_reg(spi, CANCTRL);
 
-	dev_dbg(&spi->dev, "CANSTAT 0x%02x CANCTRL 0x%02x\n", st1, st2);
+	dev_dbg(&spi->dev, "CANCTRL 0x%02x\n", ctrl);
 
-	/* Check for power up default values */
-	return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
+	/* Check for power up default value */
+	if ((ctrl & 0x17) != 0x07)
+		return -ENODEV;
+
+	return 0;
 }
 
 static int mcp251x_power_enable(struct regulator *reg, int enable)
@@ -776,7 +773,6 @@
 
 	mutex_lock(&priv->mcp_lock);
 	if (priv->after_suspend) {
-		mdelay(10);
 		mcp251x_hw_reset(spi);
 		mcp251x_setup(net, priv, spi);
 		if (priv->after_suspend & AFTER_SUSPEND_RESTART) {
@@ -1032,8 +1028,8 @@
 	struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev);
 	struct net_device *net;
 	struct mcp251x_priv *priv;
-	int freq, ret = -ENODEV;
 	struct clk *clk;
+	int freq, ret;
 
 	clk = devm_clk_get(&spi->dev, NULL);
 	if (IS_ERR(clk)) {
@@ -1076,6 +1072,18 @@
 	priv->net = net;
 	priv->clk = clk;
 
+	spi_set_drvdata(spi, priv);
+
+	/* Configure the SPI bus */
+	spi->bits_per_word = 8;
+	if (mcp251x_is_2510(spi))
+		spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
+	else
+		spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
+	ret = spi_setup(spi);
+	if (ret)
+		goto out_clk;
+
 	priv->power = devm_regulator_get(&spi->dev, "vdd");
 	priv->transceiver = devm_regulator_get(&spi->dev, "xceiver");
 	if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
@@ -1088,8 +1096,6 @@
 	if (ret)
 		goto out_clk;
 
-	spi_set_drvdata(spi, priv);
-
 	priv->spi = spi;
 	mutex_init(&priv->mcp_lock);
 
@@ -1134,20 +1140,11 @@
 
 	SET_NETDEV_DEV(net, &spi->dev);
 
-	/* Configure the SPI bus */
-	spi->mode = spi->mode ? : SPI_MODE_0;
-	if (mcp251x_is_2510(spi))
-		spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
-	else
-		spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
-	spi->bits_per_word = 8;
-	spi_setup(spi);
-
 	/* Here is OK to not lock the MCP, no one knows about it yet */
-	if (!mcp251x_hw_probe(spi)) {
-		ret = -ENODEV;
+	ret = mcp251x_hw_probe(spi);
+	if (ret)
 		goto error_probe;
-	}
+
 	mcp251x_hw_sleep(spi);
 
 	ret = register_candev(net);
@@ -1156,7 +1153,7 @@
 
 	devm_can_led_init(net);
 
-	return ret;
+	return 0;
 
 error_probe:
 	if (mcp251x_enable_dma)
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig
index fc96a3d..0b918eb 100644
--- a/drivers/net/can/usb/Kconfig
+++ b/drivers/net/can/usb/Kconfig
@@ -19,7 +19,7 @@
 	  This driver adds support for Kvaser CAN/USB devices like Kvaser
 	  Leaf Light.
 
-	  The driver gives support for the following devices:
+	  The driver provides support for the following devices:
 	    - Kvaser Leaf Light
 	    - Kvaser Leaf Professional HS
 	    - Kvaser Leaf SemiPro HS
@@ -36,6 +36,8 @@
 	    - Kvaser Leaf Light "China"
 	    - Kvaser BlackBird SemiPro
 	    - Kvaser USBcan R
+	    - Kvaser Leaf Light v2
+	    - Kvaser Mini PCI Express HS
 
 	  If unsure, say N.
 
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 4ca46ed..541fb7a 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -53,6 +53,8 @@
 #define USB_OEM_MERCURY_PRODUCT_ID	34
 #define USB_OEM_LEAF_PRODUCT_ID		35
 #define USB_CAN_R_PRODUCT_ID		39
+#define USB_LEAF_LITE_V2_PRODUCT_ID	288
+#define USB_MINI_PCIE_HS_PRODUCT_ID	289
 
 /* USB devices features */
 #define KVASER_HAS_SILENT_MODE		BIT(0)
@@ -356,6 +358,8 @@
 		.driver_info = KVASER_HAS_TXRX_ERRORS },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID),
 		.driver_info = KVASER_HAS_TXRX_ERRORS },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) },
+	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, kvaser_usb_table);
@@ -379,38 +383,43 @@
 	void *buf;
 	int actual_len;
 	int err;
-	int pos = 0;
+	int pos;
+	unsigned long to = jiffies + msecs_to_jiffies(USB_RECV_TIMEOUT);
 
 	buf = kzalloc(RX_BUFFER_SIZE, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
-	err = usb_bulk_msg(dev->udev,
-			   usb_rcvbulkpipe(dev->udev,
-					   dev->bulk_in->bEndpointAddress),
-			   buf, RX_BUFFER_SIZE, &actual_len,
-			   USB_RECV_TIMEOUT);
-	if (err < 0)
-		goto end;
-
-	while (pos <= actual_len - MSG_HEADER_LEN) {
-		tmp = buf + pos;
-
-		if (!tmp->len)
-			break;
-
-		if (pos + tmp->len > actual_len) {
-			dev_err(dev->udev->dev.parent, "Format error\n");
-			break;
-		}
-
-		if (tmp->id == id) {
-			memcpy(msg, tmp, tmp->len);
+	do {
+		err = usb_bulk_msg(dev->udev,
+				   usb_rcvbulkpipe(dev->udev,
+					dev->bulk_in->bEndpointAddress),
+				   buf, RX_BUFFER_SIZE, &actual_len,
+				   USB_RECV_TIMEOUT);
+		if (err < 0)
 			goto end;
-		}
 
-		pos += tmp->len;
-	}
+		pos = 0;
+		while (pos <= actual_len - MSG_HEADER_LEN) {
+			tmp = buf + pos;
+
+			if (!tmp->len)
+				break;
+
+			if (pos + tmp->len > actual_len) {
+				dev_err(dev->udev->dev.parent,
+					"Format error\n");
+				break;
+			}
+
+			if (tmp->id == id) {
+				memcpy(msg, tmp, tmp->len);
+				goto end;
+			}
+
+			pos += tmp->len;
+		}
+	} while (time_before(jiffies, to));
 
 	err = -EINVAL;
 
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index 41ee5b6..69c4251 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -289,7 +289,7 @@
 
 static int mv88e6123_61_65_setup(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int i;
 	int ret;
 
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index dadfafb..953bc6a 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -155,7 +155,7 @@
 
 static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int addr = REG_PORT(p);
 	u16 val;
 
@@ -274,7 +274,7 @@
 
 static int mv88e6131_setup(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int i;
 	int ret;
 
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 17314ed..9ce2146 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -74,7 +74,7 @@
 
 int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
 	mutex_lock(&ps->smi_mutex);
@@ -118,7 +118,7 @@
 
 int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
 	mutex_lock(&ps->smi_mutex);
@@ -256,7 +256,7 @@
 
 static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
 	mutex_lock(&ps->ppu_mutex);
@@ -283,7 +283,7 @@
 
 static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
 	/* Schedule a timer to re-enable the PHY polling unit. */
 	mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
@@ -292,7 +292,7 @@
 
 void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
 	mutex_init(&ps->ppu_mutex);
 	INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
@@ -463,7 +463,7 @@
 				 int nr_stats, struct mv88e6xxx_hw_stat *stats,
 				 int port, uint64_t *data)
 {
-	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 	int i;
 
diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c
index 3df1866..0e38a03 100644
--- a/drivers/net/ethernet/altera/altera_msgdma.c
+++ b/drivers/net/ethernet/altera/altera_msgdma.c
@@ -32,10 +32,8 @@
 void msgdma_reset(struct altera_tse_private *priv)
 {
 	int counter;
-	struct msgdma_csr *txcsr =
-		(struct msgdma_csr *)priv->tx_dma_csr;
-	struct msgdma_csr *rxcsr =
-		(struct msgdma_csr *)priv->rx_dma_csr;
+	struct msgdma_csr *txcsr = priv->tx_dma_csr;
+	struct msgdma_csr *rxcsr = priv->rx_dma_csr;
 
 	/* Reset Rx mSGDMA */
 	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
@@ -133,8 +131,7 @@
 	u32 ready = 0;
 	u32 inuse;
 	u32 status;
-	struct msgdma_csr *txcsr =
-		(struct msgdma_csr *)priv->tx_dma_csr;
+	struct msgdma_csr *txcsr = priv->tx_dma_csr;
 
 	/* Get number of sent descriptors */
 	inuse = ioread32(&txcsr->rw_fill_level) & 0xffff;
@@ -186,10 +183,8 @@
 	u32 rxstatus = 0;
 	u32 pktlength;
 	u32 pktstatus;
-	struct msgdma_csr *rxcsr =
-		(struct msgdma_csr *)priv->rx_dma_csr;
-	struct msgdma_response *rxresp =
-		(struct msgdma_response *)priv->rx_dma_resp;
+	struct msgdma_csr *rxcsr = priv->rx_dma_csr;
+	struct msgdma_response *rxresp = priv->rx_dma_resp;
 
 	if (ioread32(&rxcsr->resp_fill_level) & 0xffff) {
 		pktlength = ioread32(&rxresp->bytes_transferred);
diff --git a/drivers/net/ethernet/altera/altera_sgdma.c b/drivers/net/ethernet/altera/altera_sgdma.c
index 0ee9663..519f0f0 100644
--- a/drivers/net/ethernet/altera/altera_sgdma.c
+++ b/drivers/net/ethernet/altera/altera_sgdma.c
@@ -112,12 +112,12 @@
  */
 void sgdma_reset(struct altera_tse_private *priv)
 {
-	u32 *ptxdescripmem = (u32 *)priv->tx_dma_desc;
+	u32 *ptxdescripmem = priv->tx_dma_desc;
 	u32 txdescriplen   = priv->txdescmem;
-	u32 *prxdescripmem = (u32 *)priv->rx_dma_desc;
+	u32 *prxdescripmem = priv->rx_dma_desc;
 	u32 rxdescriplen   = priv->rxdescmem;
-	struct sgdma_csr *ptxsgdma = (struct sgdma_csr *)priv->tx_dma_csr;
-	struct sgdma_csr *prxsgdma = (struct sgdma_csr *)priv->rx_dma_csr;
+	struct sgdma_csr *ptxsgdma = priv->tx_dma_csr;
+	struct sgdma_csr *prxsgdma = priv->rx_dma_csr;
 
 	/* Initialize descriptor memory to 0 */
 	memset(ptxdescripmem, 0, txdescriplen);
@@ -132,14 +132,14 @@
 
 void sgdma_enable_rxirq(struct altera_tse_private *priv)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
+	struct sgdma_csr *csr = priv->rx_dma_csr;
 	priv->rxctrlreg |= SGDMA_CTRLREG_INTEN;
 	tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN);
 }
 
 void sgdma_enable_txirq(struct altera_tse_private *priv)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+	struct sgdma_csr *csr = priv->tx_dma_csr;
 	priv->txctrlreg |= SGDMA_CTRLREG_INTEN;
 	tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN);
 }
@@ -156,13 +156,13 @@
 
 void sgdma_clear_rxirq(struct altera_tse_private *priv)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
+	struct sgdma_csr *csr = priv->rx_dma_csr;
 	tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT);
 }
 
 void sgdma_clear_txirq(struct altera_tse_private *priv)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+	struct sgdma_csr *csr = priv->tx_dma_csr;
 	tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT);
 }
 
@@ -174,8 +174,7 @@
 int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 {
 	int pktstx = 0;
-	struct sgdma_descrip *descbase =
-		(struct sgdma_descrip *)priv->tx_dma_desc;
+	struct sgdma_descrip *descbase = priv->tx_dma_desc;
 
 	struct sgdma_descrip *cdesc = &descbase[0];
 	struct sgdma_descrip *ndesc = &descbase[1];
@@ -208,7 +207,7 @@
 u32 sgdma_tx_completions(struct altera_tse_private *priv)
 {
 	u32 ready = 0;
-	struct sgdma_descrip *desc = (struct sgdma_descrip *)priv->tx_dma_desc;
+	struct sgdma_descrip *desc = priv->tx_dma_desc;
 
 	if (!sgdma_txbusy(priv) &&
 	    ((desc->control & SGDMA_CONTROL_HW_OWNED) == 0) &&
@@ -231,8 +230,8 @@
  */
 u32 sgdma_rx_status(struct altera_tse_private *priv)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
-	struct sgdma_descrip *base = (struct sgdma_descrip *)priv->rx_dma_desc;
+	struct sgdma_csr *csr = priv->rx_dma_csr;
+	struct sgdma_descrip *base = priv->rx_dma_desc;
 	struct sgdma_descrip *desc = NULL;
 	int pktsrx;
 	unsigned int rxstatus = 0;
@@ -312,10 +311,8 @@
  */
 static int sgdma_async_read(struct altera_tse_private *priv)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
-	struct sgdma_descrip *descbase =
-		(struct sgdma_descrip *)priv->rx_dma_desc;
-
+	struct sgdma_csr *csr = priv->rx_dma_csr;
+	struct sgdma_descrip *descbase = priv->rx_dma_desc;
 	struct sgdma_descrip *cdesc = &descbase[0];
 	struct sgdma_descrip *ndesc = &descbase[1];
 
@@ -364,7 +361,7 @@
 static int sgdma_async_write(struct altera_tse_private *priv,
 			     struct sgdma_descrip *desc)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+	struct sgdma_csr *csr = priv->tx_dma_csr;
 
 	if (sgdma_txbusy(priv))
 		return 0;
@@ -485,7 +482,7 @@
  */
 static int sgdma_rxbusy(struct altera_tse_private *priv)
 {
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
+	struct sgdma_csr *csr = priv->rx_dma_csr;
 	return ioread32(&csr->status) & SGDMA_STSREG_BUSY;
 }
 
@@ -495,7 +492,7 @@
 static int sgdma_txbusy(struct altera_tse_private *priv)
 {
 	int delay = 0;
-	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+	struct sgdma_csr *csr = priv->tx_dma_csr;
 
 	/* if DMA is busy, wait for current transactino to finish */
 	while ((ioread32(&csr->status) & SGDMA_STSREG_BUSY) && (delay++ < 100))
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index eeecc29..9f45782 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -574,6 +574,18 @@
 	return NETDEV_TX_OK;
 }
 
+static void arc_emac_set_address_internal(struct net_device *ndev)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	unsigned int addr_low, addr_hi;
+
+	addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]);
+	addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]);
+
+	arc_reg_set(priv, R_ADDRL, addr_low);
+	arc_reg_set(priv, R_ADDRH, addr_hi);
+}
+
 /**
  * arc_emac_set_address - Set the MAC address for this device.
  * @ndev:	Pointer to net_device structure.
@@ -587,9 +599,7 @@
  */
 static int arc_emac_set_address(struct net_device *ndev, void *p)
 {
-	struct arc_emac_priv *priv = netdev_priv(ndev);
 	struct sockaddr *addr = p;
-	unsigned int addr_low, addr_hi;
 
 	if (netif_running(ndev))
 		return -EBUSY;
@@ -599,11 +609,7 @@
 
 	memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
 
-	addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]);
-	addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]);
-
-	arc_reg_set(priv, R_ADDRL, addr_low);
-	arc_reg_set(priv, R_ADDRH, addr_hi);
+	arc_emac_set_address_internal(ndev);
 
 	return 0;
 }
@@ -713,6 +719,7 @@
 	else
 		eth_hw_addr_random(ndev);
 
+	arc_emac_set_address_internal(ndev);
 	dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr);
 
 	/* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index 85dbddd..3e48809 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -150,4 +150,15 @@
 	  In case of using this driver on BCM4706 it's also requires to enable
 	  BCMA_DRIVER_GMAC_CMN to make it work.
 
+config SYSTEMPORT
+	tristate "Broadcom SYSTEMPORT internal MAC support"
+	depends on OF
+	select MII
+	select PHYLIB
+	select FIXED_PHY if SYSTEMPORT=y
+	help
+	  This driver supports the built-in Ethernet MACs found in the
+	  Broadcom BCM7xxx Set Top Box family chipset using an internal
+	  Ethernet switch.
+
 endif # NET_VENDOR_BROADCOM
diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile
index fd639a0..e2a958a 100644
--- a/drivers/net/ethernet/broadcom/Makefile
+++ b/drivers/net/ethernet/broadcom/Makefile
@@ -11,3 +11,4 @@
 obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
 obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BGMAC) += bgmac.o
+obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index a7d11f5..8db34d3 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1315,8 +1315,7 @@
 
 };
 
-#define BCM_ENET_STATS_LEN	\
-	(sizeof(bcm_enet_gstrings_stats) / sizeof(struct bcm_enet_stats))
+#define BCM_ENET_STATS_LEN	ARRAY_SIZE(bcm_enet_gstrings_stats)
 
 static const u32 unused_mib_regs[] = {
 	ETH_MIB_TX_ALL_OCTETS,
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
new file mode 100644
index 0000000..4dc8d1e
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -0,0 +1,1614 @@
+/*
+ * Broadcom BCM7xxx System Port Ethernet MAC driver
+ *
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+
+#include "bcmsysport.h"
+
+/* I/O accessors register helpers */
+#define BCM_SYSPORT_IO_MACRO(name, offset) \
+static inline u32 name##_readl(struct bcm_sysport_priv *priv, u32 off)	\
+{									\
+	u32 reg = __raw_readl(priv->base + offset + off);		\
+	return reg;							\
+}									\
+static inline void name##_writel(struct bcm_sysport_priv *priv,		\
+				  u32 val, u32 off)			\
+{									\
+	__raw_writel(val, priv->base + offset + off);			\
+}									\
+
+BCM_SYSPORT_IO_MACRO(intrl2_0, SYS_PORT_INTRL2_0_OFFSET);
+BCM_SYSPORT_IO_MACRO(intrl2_1, SYS_PORT_INTRL2_1_OFFSET);
+BCM_SYSPORT_IO_MACRO(umac, SYS_PORT_UMAC_OFFSET);
+BCM_SYSPORT_IO_MACRO(tdma, SYS_PORT_TDMA_OFFSET);
+BCM_SYSPORT_IO_MACRO(rdma, SYS_PORT_RDMA_OFFSET);
+BCM_SYSPORT_IO_MACRO(rxchk, SYS_PORT_RXCHK_OFFSET);
+BCM_SYSPORT_IO_MACRO(txchk, SYS_PORT_TXCHK_OFFSET);
+BCM_SYSPORT_IO_MACRO(rbuf, SYS_PORT_RBUF_OFFSET);
+BCM_SYSPORT_IO_MACRO(tbuf, SYS_PORT_TBUF_OFFSET);
+BCM_SYSPORT_IO_MACRO(topctrl, SYS_PORT_TOPCTRL_OFFSET);
+
+/* L2-interrupt masking/unmasking helpers, does automatic saving of the applied
+ * mask in a software copy to avoid CPU_MASK_STATUS reads in hot-paths.
+  */
+#define BCM_SYSPORT_INTR_L2(which)	\
+static inline void intrl2_##which##_mask_clear(struct bcm_sysport_priv *priv, \
+						u32 mask)		\
+{									\
+	intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR);	\
+	priv->irq##which##_mask &= ~(mask);				\
+}									\
+static inline void intrl2_##which##_mask_set(struct bcm_sysport_priv *priv, \
+						u32 mask)		\
+{									\
+	intrl2_## which##_writel(priv, mask, INTRL2_CPU_MASK_SET);	\
+	priv->irq##which##_mask |= (mask);				\
+}									\
+
+BCM_SYSPORT_INTR_L2(0)
+BCM_SYSPORT_INTR_L2(1)
+
+/* Register accesses to GISB/RBUS registers are expensive (few hundred
+ * nanoseconds), so keep the check for 64-bits explicit here to save
+ * one register write per-packet on 32-bits platforms.
+ */
+static inline void dma_desc_set_addr(struct bcm_sysport_priv *priv,
+				     void __iomem *d,
+				     dma_addr_t addr)
+{
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+	__raw_writel(upper_32_bits(addr) & DESC_ADDR_HI_MASK,
+			d + DESC_ADDR_HI_STATUS_LEN);
+#endif
+	__raw_writel(lower_32_bits(addr), d + DESC_ADDR_LO);
+}
+
+static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
+						struct dma_desc *desc,
+						unsigned int port)
+{
+	/* Ports are latched, so write upper address first */
+	tdma_writel(priv, desc->addr_status_len, TDMA_WRITE_PORT_HI(port));
+	tdma_writel(priv, desc->addr_lo, TDMA_WRITE_PORT_LO(port));
+}
+
+/* Ethtool operations */
+static int bcm_sysport_set_settings(struct net_device *dev,
+				    struct ethtool_cmd *cmd)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static int bcm_sysport_get_settings(struct net_device *dev,
+					struct ethtool_cmd *cmd)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int bcm_sysport_set_rx_csum(struct net_device *dev,
+					netdev_features_t wanted)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	u32 reg;
+
+	priv->rx_csum_en = !!(wanted & NETIF_F_RXCSUM);
+	reg = rxchk_readl(priv, RXCHK_CONTROL);
+	if (priv->rx_csum_en)
+		reg |= RXCHK_EN;
+	else
+		reg &= ~RXCHK_EN;
+
+	/* If UniMAC forwards CRC, we need to skip over it to get
+	 * a valid CHK bit to be set in the per-packet status word
+	 */
+	if (priv->rx_csum_en && priv->crc_fwd)
+		reg |= RXCHK_SKIP_FCS;
+	else
+		reg &= ~RXCHK_SKIP_FCS;
+
+	rxchk_writel(priv, reg, RXCHK_CONTROL);
+
+	return 0;
+}
+
+static int bcm_sysport_set_tx_csum(struct net_device *dev,
+					netdev_features_t wanted)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	u32 reg;
+
+	/* Hardware transmit checksum requires us to enable the Transmit status
+	 * block prepended to the packet contents
+	 */
+	priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM));
+	reg = tdma_readl(priv, TDMA_CONTROL);
+	if (priv->tsb_en)
+		reg |= TSB_EN;
+	else
+		reg &= ~TSB_EN;
+	tdma_writel(priv, reg, TDMA_CONTROL);
+
+	return 0;
+}
+
+static int bcm_sysport_set_features(struct net_device *dev,
+					netdev_features_t features)
+{
+	netdev_features_t changed = features ^ dev->features;
+	netdev_features_t wanted = dev->wanted_features;
+	int ret = 0;
+
+	if (changed & NETIF_F_RXCSUM)
+		ret = bcm_sysport_set_rx_csum(dev, wanted);
+	if (changed & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))
+		ret = bcm_sysport_set_tx_csum(dev, wanted);
+
+	return ret;
+}
+
+/* Hardware counters must be kept in sync because the order/offset
+ * is important here (order in structure declaration = order in hardware)
+ */
+static const struct bcm_sysport_stats bcm_sysport_gstrings_stats[] = {
+	/* general stats */
+	STAT_NETDEV(rx_packets),
+	STAT_NETDEV(tx_packets),
+	STAT_NETDEV(rx_bytes),
+	STAT_NETDEV(tx_bytes),
+	STAT_NETDEV(rx_errors),
+	STAT_NETDEV(tx_errors),
+	STAT_NETDEV(rx_dropped),
+	STAT_NETDEV(tx_dropped),
+	STAT_NETDEV(multicast),
+	/* UniMAC RSV counters */
+	STAT_MIB_RX("rx_64_octets", mib.rx.pkt_cnt.cnt_64),
+	STAT_MIB_RX("rx_65_127_oct", mib.rx.pkt_cnt.cnt_127),
+	STAT_MIB_RX("rx_128_255_oct", mib.rx.pkt_cnt.cnt_255),
+	STAT_MIB_RX("rx_256_511_oct", mib.rx.pkt_cnt.cnt_511),
+	STAT_MIB_RX("rx_512_1023_oct", mib.rx.pkt_cnt.cnt_1023),
+	STAT_MIB_RX("rx_1024_1518_oct", mib.rx.pkt_cnt.cnt_1518),
+	STAT_MIB_RX("rx_vlan_1519_1522_oct", mib.rx.pkt_cnt.cnt_mgv),
+	STAT_MIB_RX("rx_1522_2047_oct", mib.rx.pkt_cnt.cnt_2047),
+	STAT_MIB_RX("rx_2048_4095_oct", mib.rx.pkt_cnt.cnt_4095),
+	STAT_MIB_RX("rx_4096_9216_oct", mib.rx.pkt_cnt.cnt_9216),
+	STAT_MIB_RX("rx_pkts", mib.rx.pkt),
+	STAT_MIB_RX("rx_bytes", mib.rx.bytes),
+	STAT_MIB_RX("rx_multicast", mib.rx.mca),
+	STAT_MIB_RX("rx_broadcast", mib.rx.bca),
+	STAT_MIB_RX("rx_fcs", mib.rx.fcs),
+	STAT_MIB_RX("rx_control", mib.rx.cf),
+	STAT_MIB_RX("rx_pause", mib.rx.pf),
+	STAT_MIB_RX("rx_unknown", mib.rx.uo),
+	STAT_MIB_RX("rx_align", mib.rx.aln),
+	STAT_MIB_RX("rx_outrange", mib.rx.flr),
+	STAT_MIB_RX("rx_code", mib.rx.cde),
+	STAT_MIB_RX("rx_carrier", mib.rx.fcr),
+	STAT_MIB_RX("rx_oversize", mib.rx.ovr),
+	STAT_MIB_RX("rx_jabber", mib.rx.jbr),
+	STAT_MIB_RX("rx_mtu_err", mib.rx.mtue),
+	STAT_MIB_RX("rx_good_pkts", mib.rx.pok),
+	STAT_MIB_RX("rx_unicast", mib.rx.uc),
+	STAT_MIB_RX("rx_ppp", mib.rx.ppp),
+	STAT_MIB_RX("rx_crc", mib.rx.rcrc),
+	/* UniMAC TSV counters */
+	STAT_MIB_TX("tx_64_octets", mib.tx.pkt_cnt.cnt_64),
+	STAT_MIB_TX("tx_65_127_oct", mib.tx.pkt_cnt.cnt_127),
+	STAT_MIB_TX("tx_128_255_oct", mib.tx.pkt_cnt.cnt_255),
+	STAT_MIB_TX("tx_256_511_oct", mib.tx.pkt_cnt.cnt_511),
+	STAT_MIB_TX("tx_512_1023_oct", mib.tx.pkt_cnt.cnt_1023),
+	STAT_MIB_TX("tx_1024_1518_oct", mib.tx.pkt_cnt.cnt_1518),
+	STAT_MIB_TX("tx_vlan_1519_1522_oct", mib.tx.pkt_cnt.cnt_mgv),
+	STAT_MIB_TX("tx_1522_2047_oct", mib.tx.pkt_cnt.cnt_2047),
+	STAT_MIB_TX("tx_2048_4095_oct", mib.tx.pkt_cnt.cnt_4095),
+	STAT_MIB_TX("tx_4096_9216_oct", mib.tx.pkt_cnt.cnt_9216),
+	STAT_MIB_TX("tx_pkts", mib.tx.pkts),
+	STAT_MIB_TX("tx_multicast", mib.tx.mca),
+	STAT_MIB_TX("tx_broadcast", mib.tx.bca),
+	STAT_MIB_TX("tx_pause", mib.tx.pf),
+	STAT_MIB_TX("tx_control", mib.tx.cf),
+	STAT_MIB_TX("tx_fcs_err", mib.tx.fcs),
+	STAT_MIB_TX("tx_oversize", mib.tx.ovr),
+	STAT_MIB_TX("tx_defer", mib.tx.drf),
+	STAT_MIB_TX("tx_excess_defer", mib.tx.edf),
+	STAT_MIB_TX("tx_single_col", mib.tx.scl),
+	STAT_MIB_TX("tx_multi_col", mib.tx.mcl),
+	STAT_MIB_TX("tx_late_col", mib.tx.lcl),
+	STAT_MIB_TX("tx_excess_col", mib.tx.ecl),
+	STAT_MIB_TX("tx_frags", mib.tx.frg),
+	STAT_MIB_TX("tx_total_col", mib.tx.ncl),
+	STAT_MIB_TX("tx_jabber", mib.tx.jbr),
+	STAT_MIB_TX("tx_bytes", mib.tx.bytes),
+	STAT_MIB_TX("tx_good_pkts", mib.tx.pok),
+	STAT_MIB_TX("tx_unicast", mib.tx.uc),
+	/* UniMAC RUNT counters */
+	STAT_RUNT("rx_runt_pkts", mib.rx_runt_cnt),
+	STAT_RUNT("rx_runt_valid_fcs", mib.rx_runt_fcs),
+	STAT_RUNT("rx_runt_inval_fcs_align", mib.rx_runt_fcs_align),
+	STAT_RUNT("rx_runt_bytes", mib.rx_runt_bytes),
+	/* RXCHK misc statistics */
+	STAT_RXCHK("rxchk_bad_csum", mib.rxchk_bad_csum, RXCHK_BAD_CSUM_CNTR),
+	STAT_RXCHK("rxchk_other_pkt_disc", mib.rxchk_other_pkt_disc,
+			RXCHK_OTHER_DISC_CNTR),
+	/* RBUF misc statistics */
+	STAT_RBUF("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt, RBUF_OVFL_DISC_CNTR),
+	STAT_RBUF("rbuf_err_cnt", mib.rbuf_err_cnt, RBUF_ERR_PKT_CNTR),
+};
+
+#define BCM_SYSPORT_STATS_LEN	ARRAY_SIZE(bcm_sysport_gstrings_stats)
+
+static void bcm_sysport_get_drvinfo(struct net_device *dev,
+					struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+	strlcpy(info->version, "0.1", sizeof(info->version));
+	strlcpy(info->bus_info, "platform", sizeof(info->bus_info));
+	info->n_stats = BCM_SYSPORT_STATS_LEN;
+}
+
+static u32 bcm_sysport_get_msglvl(struct net_device *dev)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+	return priv->msg_enable;
+}
+
+static void bcm_sysport_set_msglvl(struct net_device *dev, u32 enable)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+	priv->msg_enable = enable;
+}
+
+static int bcm_sysport_get_sset_count(struct net_device *dev, int string_set)
+{
+	switch (string_set) {
+	case ETH_SS_STATS:
+		return BCM_SYSPORT_STATS_LEN;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void bcm_sysport_get_strings(struct net_device *dev,
+					u32 stringset, u8 *data)
+{
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN,
+				bcm_sysport_gstrings_stats[i].stat_string,
+				ETH_GSTRING_LEN);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv)
+{
+	int i, j = 0;
+
+	for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+		const struct bcm_sysport_stats *s;
+		u8 offset = 0;
+		u32 val = 0;
+		char *p;
+
+		s = &bcm_sysport_gstrings_stats[i];
+		switch (s->type) {
+		case BCM_SYSPORT_STAT_NETDEV:
+			continue;
+		case BCM_SYSPORT_STAT_MIB_RX:
+		case BCM_SYSPORT_STAT_MIB_TX:
+		case BCM_SYSPORT_STAT_RUNT:
+			if (s->type != BCM_SYSPORT_STAT_MIB_RX)
+				offset = UMAC_MIB_STAT_OFFSET;
+			val = umac_readl(priv, UMAC_MIB_START + j + offset);
+			break;
+		case BCM_SYSPORT_STAT_RXCHK:
+			val = rxchk_readl(priv, s->reg_offset);
+			if (val == ~0)
+				rxchk_writel(priv, 0, s->reg_offset);
+			break;
+		case BCM_SYSPORT_STAT_RBUF:
+			val = rbuf_readl(priv, s->reg_offset);
+			if (val == ~0)
+				rbuf_writel(priv, 0, s->reg_offset);
+			break;
+		}
+
+		j += s->stat_sizeof;
+		p = (char *)priv + s->stat_offset;
+		*(u32 *)p = val;
+	}
+
+	netif_dbg(priv, hw, priv->netdev, "updated MIB counters\n");
+}
+
+static void bcm_sysport_get_stats(struct net_device *dev,
+					struct ethtool_stats *stats, u64 *data)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	int i;
+
+	if (netif_running(dev))
+		bcm_sysport_update_mib_counters(priv);
+
+	for (i =  0; i < BCM_SYSPORT_STATS_LEN; i++) {
+		const struct bcm_sysport_stats *s;
+		char *p;
+
+		s = &bcm_sysport_gstrings_stats[i];
+		if (s->type == BCM_SYSPORT_STAT_NETDEV)
+			p = (char *)&dev->stats;
+		else
+			p = (char *)priv;
+		p += s->stat_offset;
+		data[i] = *(u32 *)p;
+	}
+}
+
+static void bcm_sysport_free_cb(struct bcm_sysport_cb *cb)
+{
+	dev_kfree_skb_any(cb->skb);
+	cb->skb = NULL;
+	dma_unmap_addr_set(cb, dma_addr, 0);
+}
+
+static int bcm_sysport_rx_refill(struct bcm_sysport_priv *priv,
+				 struct bcm_sysport_cb *cb)
+{
+	struct device *kdev = &priv->pdev->dev;
+	struct net_device *ndev = priv->netdev;
+	dma_addr_t mapping;
+	int ret;
+
+	cb->skb = netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH);
+	if (!cb->skb) {
+		netif_err(priv, rx_err, ndev, "SKB alloc failed\n");
+		return -ENOMEM;
+	}
+
+	mapping = dma_map_single(kdev, cb->skb->data,
+				RX_BUF_LENGTH, DMA_FROM_DEVICE);
+	ret = dma_mapping_error(kdev, mapping);
+	if (ret) {
+		bcm_sysport_free_cb(cb);
+		netif_err(priv, rx_err, ndev, "DMA mapping failure\n");
+		return ret;
+	}
+
+	dma_unmap_addr_set(cb, dma_addr, mapping);
+	dma_desc_set_addr(priv, priv->rx_bd_assign_ptr, mapping);
+
+	priv->rx_bd_assign_index++;
+	priv->rx_bd_assign_index &= (priv->num_rx_bds - 1);
+	priv->rx_bd_assign_ptr = priv->rx_bds +
+		(priv->rx_bd_assign_index * DESC_SIZE);
+
+	netif_dbg(priv, rx_status, ndev, "RX refill\n");
+
+	return 0;
+}
+
+static int bcm_sysport_alloc_rx_bufs(struct bcm_sysport_priv *priv)
+{
+	struct bcm_sysport_cb *cb;
+	int ret = 0;
+	unsigned int i;
+
+	for (i = 0; i < priv->num_rx_bds; i++) {
+		cb = &priv->rx_cbs[priv->rx_bd_assign_index];
+		if (cb->skb)
+			continue;
+
+		ret = bcm_sysport_rx_refill(priv, cb);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+/* Poll the hardware for up to budget packets to process */
+static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
+					unsigned int budget)
+{
+	struct device *kdev = &priv->pdev->dev;
+	struct net_device *ndev = priv->netdev;
+	unsigned int processed = 0, to_process;
+	struct bcm_sysport_cb *cb;
+	struct sk_buff *skb;
+	unsigned int p_index;
+	u16 len, status;
+	struct rsb *rsb;
+
+	/* Determine how much we should process since last call */
+	p_index = rdma_readl(priv, RDMA_PROD_INDEX);
+	p_index &= RDMA_PROD_INDEX_MASK;
+
+	if (p_index < priv->rx_c_index)
+		to_process = (RDMA_CONS_INDEX_MASK + 1) -
+			priv->rx_c_index + p_index;
+	else
+		to_process = p_index - priv->rx_c_index;
+
+	netif_dbg(priv, rx_status, ndev,
+			"p_index=%d rx_c_index=%d to_process=%d\n",
+			p_index, priv->rx_c_index, to_process);
+
+	while ((processed < to_process) &&
+		(processed < budget)) {
+
+		cb = &priv->rx_cbs[priv->rx_read_ptr];
+		skb = cb->skb;
+		dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
+				dma_unmap_len(cb, dma_len), DMA_FROM_DEVICE);
+
+		/* Extract the Receive Status Block prepended */
+		rsb = (struct rsb *)skb->data;
+		len = (rsb->rx_status_len >> DESC_LEN_SHIFT) & DESC_LEN_MASK;
+		status = (rsb->rx_status_len >> DESC_STATUS_SHIFT) &
+			DESC_STATUS_MASK;
+
+		processed++;
+		priv->rx_read_ptr++;
+		if (priv->rx_read_ptr == priv->num_rx_bds)
+			priv->rx_read_ptr = 0;
+
+		netif_dbg(priv, rx_status, ndev,
+				"p=%d, c=%d, rd_ptr=%d, len=%d, flag=0x%04x\n",
+				p_index, priv->rx_c_index, priv->rx_read_ptr,
+				len, status);
+
+		if (unlikely(!skb)) {
+			netif_err(priv, rx_err, ndev, "out of memory!\n");
+			ndev->stats.rx_dropped++;
+			ndev->stats.rx_errors++;
+			goto refill;
+		}
+
+		if (unlikely(!(status & DESC_EOP) || !(status & DESC_SOP))) {
+			netif_err(priv, rx_status, ndev, "fragmented packet!\n");
+			ndev->stats.rx_dropped++;
+			ndev->stats.rx_errors++;
+			bcm_sysport_free_cb(cb);
+			goto refill;
+		}
+
+		if (unlikely(status & (RX_STATUS_ERR | RX_STATUS_OVFLOW))) {
+			netif_err(priv, rx_err, ndev, "error packet\n");
+			if (RX_STATUS_OVFLOW)
+				ndev->stats.rx_over_errors++;
+			ndev->stats.rx_dropped++;
+			ndev->stats.rx_errors++;
+			bcm_sysport_free_cb(cb);
+			goto refill;
+		}
+
+		skb_put(skb, len);
+
+		/* Hardware validated our checksum */
+		if (likely(status & DESC_L4_CSUM))
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+		/* Hardware pre-pends packets with 2bytes between Ethernet
+		 * and IP header plus we have the Receive Status Block, strip
+		 * off all of this from the SKB.
+		 */
+		skb_pull(skb, sizeof(*rsb) + 2);
+		len -= (sizeof(*rsb) + 2);
+
+		/* UniMAC may forward CRC */
+		if (priv->crc_fwd) {
+			skb_trim(skb, len - ETH_FCS_LEN);
+			len -= ETH_FCS_LEN;
+		}
+
+		skb->protocol = eth_type_trans(skb, ndev);
+		ndev->stats.rx_packets++;
+		ndev->stats.rx_bytes += len;
+
+		napi_gro_receive(&priv->napi, skb);
+refill:
+		bcm_sysport_rx_refill(priv, cb);
+	}
+
+	return processed;
+}
+
+static void bcm_sysport_tx_reclaim_one(struct bcm_sysport_priv *priv,
+					struct bcm_sysport_cb *cb,
+					unsigned int *bytes_compl,
+					unsigned int *pkts_compl)
+{
+	struct device *kdev = &priv->pdev->dev;
+	struct net_device *ndev = priv->netdev;
+
+	if (cb->skb) {
+		ndev->stats.tx_bytes += cb->skb->len;
+		*bytes_compl += cb->skb->len;
+		dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
+				dma_unmap_len(cb, dma_len),
+				DMA_TO_DEVICE);
+		ndev->stats.tx_packets++;
+		(*pkts_compl)++;
+		bcm_sysport_free_cb(cb);
+	/* SKB fragment */
+	} else if (dma_unmap_addr(cb, dma_addr)) {
+		ndev->stats.tx_bytes += dma_unmap_len(cb, dma_len);
+		dma_unmap_page(kdev, dma_unmap_addr(cb, dma_addr),
+				dma_unmap_len(cb, dma_len), DMA_TO_DEVICE);
+		dma_unmap_addr_set(cb, dma_addr, 0);
+	}
+}
+
+/* Reclaim queued SKBs for transmission completion, lockless version */
+static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
+					     struct bcm_sysport_tx_ring *ring)
+{
+	struct net_device *ndev = priv->netdev;
+	unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
+	struct bcm_sysport_cb *cb;
+	struct netdev_queue *txq;
+	u32 hw_ind;
+
+	txq = netdev_get_tx_queue(ndev, ring->index);
+
+	/* Compute how many descriptors have been processed since last call */
+	hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
+	c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
+	ring->p_index = (hw_ind & RING_PROD_INDEX_MASK);
+
+	last_c_index = ring->c_index;
+	num_tx_cbs = ring->size;
+
+	c_index &= (num_tx_cbs - 1);
+
+	if (c_index >= last_c_index)
+		last_tx_cn = c_index - last_c_index;
+	else
+		last_tx_cn = num_tx_cbs - last_c_index + c_index;
+
+	netif_dbg(priv, tx_done, ndev,
+			"ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n",
+			ring->index, c_index, last_tx_cn, last_c_index);
+
+	while (last_tx_cn-- > 0) {
+		cb = ring->cbs + last_c_index;
+		bcm_sysport_tx_reclaim_one(priv, cb, &bytes_compl, &pkts_compl);
+
+		ring->desc_count++;
+		last_c_index++;
+		last_c_index &= (num_tx_cbs - 1);
+	}
+
+	ring->c_index = c_index;
+
+	if (netif_tx_queue_stopped(txq) && pkts_compl)
+		netif_tx_wake_queue(txq);
+
+	netif_dbg(priv, tx_done, ndev,
+			"ring=%d c_index=%d pkts_compl=%d, bytes_compl=%d\n",
+			ring->index, ring->c_index, pkts_compl, bytes_compl);
+
+	return pkts_compl;
+}
+
+/* Locked version of the per-ring TX reclaim routine */
+static unsigned int bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
+					   struct bcm_sysport_tx_ring *ring)
+{
+	unsigned int released;
+
+	spin_lock(&ring->lock);
+	released = __bcm_sysport_tx_reclaim(priv, ring);
+	spin_unlock(&ring->lock);
+
+	return released;
+}
+
+static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
+{
+	struct bcm_sysport_tx_ring *ring =
+		container_of(napi, struct bcm_sysport_tx_ring, napi);
+	unsigned int work_done = 0;
+
+	work_done = bcm_sysport_tx_reclaim(ring->priv, ring);
+
+	if (work_done < budget) {
+		napi_complete(napi);
+		/* re-enable TX interrupt */
+		intrl2_1_mask_clear(ring->priv, BIT(ring->index));
+	}
+
+	return work_done;
+}
+
+static void bcm_sysport_tx_reclaim_all(struct bcm_sysport_priv *priv)
+{
+	unsigned int q;
+
+	for (q = 0; q < priv->netdev->num_tx_queues; q++)
+		bcm_sysport_tx_reclaim(priv, &priv->tx_rings[q]);
+}
+
+static int bcm_sysport_poll(struct napi_struct *napi, int budget)
+{
+	struct bcm_sysport_priv *priv =
+		container_of(napi, struct bcm_sysport_priv, napi);
+	unsigned int work_done = 0;
+
+	work_done = bcm_sysport_desc_rx(priv, budget);
+
+	priv->rx_c_index += work_done;
+	priv->rx_c_index &= RDMA_CONS_INDEX_MASK;
+	rdma_writel(priv, priv->rx_c_index, RDMA_CONS_INDEX);
+
+	if (work_done < budget) {
+		napi_complete(napi);
+		/* re-enable RX interrupts */
+		intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE);
+	}
+
+	return work_done;
+}
+
+
+/* RX and misc interrupt routine */
+static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+	priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) &
+			  ~intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
+	intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR);
+
+	if (unlikely(priv->irq0_stat == 0)) {
+		netdev_warn(priv->netdev, "spurious RX interrupt\n");
+		return IRQ_NONE;
+	}
+
+	if (priv->irq0_stat & INTRL2_0_RDMA_MBDONE) {
+		if (likely(napi_schedule_prep(&priv->napi))) {
+			/* disable RX interrupts */
+			intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE);
+			__napi_schedule(&priv->napi);
+		}
+	}
+
+	/* TX ring is full, perform a full reclaim since we do not know
+	 * which one would trigger this interrupt
+	 */
+	if (priv->irq0_stat & INTRL2_0_TX_RING_FULL)
+		bcm_sysport_tx_reclaim_all(priv);
+
+	return IRQ_HANDLED;
+}
+
+/* TX interrupt service routine */
+static irqreturn_t bcm_sysport_tx_isr(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	struct bcm_sysport_tx_ring *txr;
+	unsigned int ring;
+
+	priv->irq1_stat = intrl2_1_readl(priv, INTRL2_CPU_STATUS) &
+				~intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS);
+	intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+
+	if (unlikely(priv->irq1_stat == 0)) {
+		netdev_warn(priv->netdev, "spurious TX interrupt\n");
+		return IRQ_NONE;
+	}
+
+	for (ring = 0; ring < dev->num_tx_queues; ring++) {
+		if (!(priv->irq1_stat & BIT(ring)))
+			continue;
+
+		txr = &priv->tx_rings[ring];
+
+		if (likely(napi_schedule_prep(&txr->napi))) {
+			intrl2_1_mask_set(priv, BIT(ring));
+			__napi_schedule(&txr->napi);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int bcm_sysport_insert_tsb(struct sk_buff *skb, struct net_device *dev)
+{
+	struct sk_buff *nskb;
+	struct tsb *tsb;
+	u32 csum_info;
+	u8 ip_proto;
+	u16 csum_start;
+	u16 ip_ver;
+
+	/* Re-allocate SKB if needed */
+	if (unlikely(skb_headroom(skb) < sizeof(*tsb))) {
+		nskb = skb_realloc_headroom(skb, sizeof(*tsb));
+		dev_kfree_skb(skb);
+		if (!nskb) {
+			dev->stats.tx_errors++;
+			dev->stats.tx_dropped++;
+			return -ENOMEM;
+		}
+		skb = nskb;
+	}
+
+	tsb = (struct tsb *)skb_push(skb, sizeof(*tsb));
+	/* Zero-out TSB by default */
+	memset(tsb, 0, sizeof(*tsb));
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		ip_ver = htons(skb->protocol);
+		switch (ip_ver) {
+		case ETH_P_IP:
+			ip_proto = ip_hdr(skb)->protocol;
+			break;
+		case ETH_P_IPV6:
+			ip_proto = ipv6_hdr(skb)->nexthdr;
+			break;
+		default:
+			return 0;
+		}
+
+		/* Get the checksum offset and the L4 (transport) offset */
+		csum_start = skb_checksum_start_offset(skb) - sizeof(*tsb);
+		csum_info = (csum_start + skb->csum_offset) & L4_CSUM_PTR_MASK;
+		csum_info |= (csum_start << L4_PTR_SHIFT);
+
+		if (ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP) {
+			csum_info |= L4_LENGTH_VALID;
+			if (ip_proto == IPPROTO_UDP && ip_ver == ETH_P_IP)
+				csum_info |= L4_UDP;
+		} else
+			csum_info = 0;
+
+		tsb->l4_ptr_dest_map = csum_info;
+	}
+
+	return 0;
+}
+
+static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	struct device *kdev = &priv->pdev->dev;
+	struct bcm_sysport_tx_ring *ring;
+	struct bcm_sysport_cb *cb;
+	struct netdev_queue *txq;
+	struct dma_desc *desc;
+	dma_addr_t mapping;
+	u32 len_status;
+	u16 queue;
+	int ret;
+
+	queue = skb_get_queue_mapping(skb);
+	txq = netdev_get_tx_queue(dev, queue);
+	ring = &priv->tx_rings[queue];
+
+	/* lock against tx reclaim in BH context */
+	spin_lock(&ring->lock);
+	if (unlikely(ring->desc_count == 0)) {
+		netif_tx_stop_queue(txq);
+		netdev_err(dev, "queue %d awake and ring full!\n", queue);
+		ret = NETDEV_TX_BUSY;
+		goto out;
+	}
+
+	/* Insert TSB and checksum infos */
+	if (priv->tsb_en) {
+		ret = bcm_sysport_insert_tsb(skb, dev);
+		if (ret) {
+			ret = NETDEV_TX_OK;
+			goto out;
+		}
+	}
+
+	mapping = dma_map_single(kdev, skb->data, skb->len, DMA_TO_DEVICE);
+	if (dma_mapping_error(kdev, mapping)) {
+		netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n",
+				skb->data, skb->len);
+		ret = NETDEV_TX_OK;
+		goto out;
+	}
+
+	/* Remember the SKB for future freeing */
+	cb = &ring->cbs[ring->curr_desc];
+	cb->skb = skb;
+	dma_unmap_addr_set(cb, dma_addr, mapping);
+	dma_unmap_len_set(cb, dma_len, skb->len);
+
+	/* Fetch a descriptor entry from our pool */
+	desc = ring->desc_cpu;
+
+	desc->addr_lo = lower_32_bits(mapping);
+	len_status = upper_32_bits(mapping) & DESC_ADDR_HI_MASK;
+	len_status |= (skb->len << DESC_LEN_SHIFT);
+	len_status |= (DESC_SOP | DESC_EOP | TX_STATUS_APP_CRC) <<
+			DESC_STATUS_SHIFT;
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		len_status |= (DESC_L4_CSUM << DESC_STATUS_SHIFT);
+
+	ring->curr_desc++;
+	if (ring->curr_desc == ring->size)
+		ring->curr_desc = 0;
+	ring->desc_count--;
+
+	/* Ensure write completion of the descriptor status/length
+	 * in DRAM before the System Port WRITE_PORT register latches
+	 * the value
+	 */
+	wmb();
+	desc->addr_status_len = len_status;
+	wmb();
+
+	/* Write this descriptor address to the RING write port */
+	tdma_port_write_desc_addr(priv, desc, ring->index);
+
+	/* Check ring space and update SW control flow */
+	if (ring->desc_count == 0)
+		netif_tx_stop_queue(txq);
+
+	netif_dbg(priv, tx_queued, dev, "ring=%d desc_count=%d, curr_desc=%d\n",
+			ring->index, ring->desc_count, ring->curr_desc);
+
+	ret = NETDEV_TX_OK;
+out:
+	spin_unlock(&ring->lock);
+	return ret;
+}
+
+static void bcm_sysport_tx_timeout(struct net_device *dev)
+{
+	netdev_warn(dev, "transmit timeout!\n");
+
+	dev->trans_start = jiffies;
+	dev->stats.tx_errors++;
+
+	netif_tx_wake_all_queues(dev);
+}
+
+/* phylib adjust link callback */
+static void bcm_sysport_adj_link(struct net_device *dev)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	struct phy_device *phydev = priv->phydev;
+	unsigned int changed = 0;
+	u32 cmd_bits = 0, reg;
+
+	if (priv->old_link != phydev->link) {
+		changed = 1;
+		priv->old_link = phydev->link;
+	}
+
+	if (priv->old_duplex != phydev->duplex) {
+		changed = 1;
+		priv->old_duplex = phydev->duplex;
+	}
+
+	switch (phydev->speed) {
+	case SPEED_2500:
+		cmd_bits = CMD_SPEED_2500;
+		break;
+	case SPEED_1000:
+		cmd_bits = CMD_SPEED_1000;
+		break;
+	case SPEED_100:
+		cmd_bits = CMD_SPEED_100;
+		break;
+	case SPEED_10:
+		cmd_bits = CMD_SPEED_10;
+		break;
+	default:
+		break;
+	}
+	cmd_bits <<= CMD_SPEED_SHIFT;
+
+	if (phydev->duplex == DUPLEX_HALF)
+		cmd_bits |= CMD_HD_EN;
+
+	if (priv->old_pause != phydev->pause) {
+		changed = 1;
+		priv->old_pause = phydev->pause;
+	}
+
+	if (!phydev->pause)
+		cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
+
+	reg = umac_readl(priv, UMAC_CMD);
+	reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
+			CMD_HD_EN | CMD_RX_PAUSE_IGNORE |
+			CMD_TX_PAUSE_IGNORE);
+	reg |= cmd_bits;
+	umac_writel(priv, reg, UMAC_CMD);
+
+	if (changed)
+		phy_print_status(priv->phydev);
+}
+
+static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
+				    unsigned int index)
+{
+	struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
+	struct device *kdev = &priv->pdev->dev;
+	size_t size;
+	void *p;
+	u32 reg;
+
+	/* Simple descriptors partitioning for now */
+	size = 256;
+
+	/* We just need one DMA descriptor which is DMA-able, since writing to
+	 * the port will allocate a new descriptor in its internal linked-list
+	 */
+	p = dma_zalloc_coherent(kdev, 1, &ring->desc_dma, GFP_KERNEL);
+	if (!p) {
+		netif_err(priv, hw, priv->netdev, "DMA alloc failed\n");
+		return -ENOMEM;
+	}
+
+	ring->cbs = kzalloc(sizeof(struct bcm_sysport_cb) * size, GFP_KERNEL);
+	if (!ring->cbs) {
+		netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
+		return -ENOMEM;
+	}
+
+	/* Initialize SW view of the ring */
+	spin_lock_init(&ring->lock);
+	ring->priv = priv;
+	netif_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64);
+	ring->index = index;
+	ring->size = size;
+	ring->alloc_size = ring->size;
+	ring->desc_cpu = p;
+	ring->desc_count = ring->size;
+	ring->curr_desc = 0;
+
+	/* Initialize HW ring */
+	tdma_writel(priv, RING_EN, TDMA_DESC_RING_HEAD_TAIL_PTR(index));
+	tdma_writel(priv, 0, TDMA_DESC_RING_COUNT(index));
+	tdma_writel(priv, 1, TDMA_DESC_RING_INTR_CONTROL(index));
+	tdma_writel(priv, 0, TDMA_DESC_RING_PROD_CONS_INDEX(index));
+	tdma_writel(priv, RING_IGNORE_STATUS, TDMA_DESC_RING_MAPPING(index));
+	tdma_writel(priv, 0, TDMA_DESC_RING_PCP_DEI_VID(index));
+
+	/* Program the number of descriptors as MAX_THRESHOLD and half of
+	 * its size for the hysteresis trigger
+	 */
+	tdma_writel(priv, ring->size |
+			1 << RING_HYST_THRESH_SHIFT,
+			TDMA_DESC_RING_MAX_HYST(index));
+
+	/* Enable the ring queue in the arbiter */
+	reg = tdma_readl(priv, TDMA_TIER1_ARB_0_QUEUE_EN);
+	reg |= (1 << index);
+	tdma_writel(priv, reg, TDMA_TIER1_ARB_0_QUEUE_EN);
+
+	napi_enable(&ring->napi);
+
+	netif_dbg(priv, hw, priv->netdev,
+			"TDMA cfg, size=%d, desc_cpu=%p\n",
+			ring->size, ring->desc_cpu);
+
+	return 0;
+}
+
+static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
+					unsigned int index)
+{
+	struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
+	struct device *kdev = &priv->pdev->dev;
+	u32 reg;
+
+	/* Caller should stop the TDMA engine */
+	reg = tdma_readl(priv, TDMA_STATUS);
+	if (!(reg & TDMA_DISABLED))
+		netdev_warn(priv->netdev, "TDMA not stopped!\n");
+
+	napi_disable(&ring->napi);
+	netif_napi_del(&ring->napi);
+
+	bcm_sysport_tx_reclaim(priv, ring);
+
+	kfree(ring->cbs);
+	ring->cbs = NULL;
+
+	if (ring->desc_dma) {
+		dma_free_coherent(kdev, 1, ring->desc_cpu, ring->desc_dma);
+		ring->desc_dma = 0;
+	}
+	ring->size = 0;
+	ring->alloc_size = 0;
+
+	netif_dbg(priv, hw, priv->netdev, "TDMA fini done\n");
+}
+
+/* RDMA helper */
+static inline int rdma_enable_set(struct bcm_sysport_priv *priv,
+					unsigned int enable)
+{
+	unsigned int timeout = 1000;
+	u32 reg;
+
+	reg = rdma_readl(priv, RDMA_CONTROL);
+	if (enable)
+		reg |= RDMA_EN;
+	else
+		reg &= ~RDMA_EN;
+	rdma_writel(priv, reg, RDMA_CONTROL);
+
+	/* Poll for RMDA disabling completion */
+	do {
+		reg = rdma_readl(priv, RDMA_STATUS);
+		if (!!(reg & RDMA_DISABLED) == !enable)
+			return 0;
+		usleep_range(1000, 2000);
+	} while (timeout-- > 0);
+
+	netdev_err(priv->netdev, "timeout waiting for RDMA to finish\n");
+
+	return -ETIMEDOUT;
+}
+
+/* TDMA helper */
+static inline int tdma_enable_set(struct bcm_sysport_priv *priv,
+					unsigned int enable)
+{
+	unsigned int timeout = 1000;
+	u32 reg;
+
+	reg = tdma_readl(priv, TDMA_CONTROL);
+	if (enable)
+		reg |= TDMA_EN;
+	else
+		reg &= ~TDMA_EN;
+	tdma_writel(priv, reg, TDMA_CONTROL);
+
+	/* Poll for TMDA disabling completion */
+	do {
+		reg = tdma_readl(priv, TDMA_STATUS);
+		if (!!(reg & TDMA_DISABLED) == !enable)
+			return 0;
+
+		usleep_range(1000, 2000);
+	} while (timeout-- > 0);
+
+	netdev_err(priv->netdev, "timeout waiting for TDMA to finish\n");
+
+	return -ETIMEDOUT;
+}
+
+static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
+{
+	u32 reg;
+	int ret;
+
+	/* Initialize SW view of the RX ring */
+	priv->num_rx_bds = NUM_RX_DESC;
+	priv->rx_bds = priv->base + SYS_PORT_RDMA_OFFSET;
+	priv->rx_bd_assign_ptr = priv->rx_bds;
+	priv->rx_bd_assign_index = 0;
+	priv->rx_c_index = 0;
+	priv->rx_read_ptr = 0;
+	priv->rx_cbs = kzalloc(priv->num_rx_bds *
+				sizeof(struct bcm_sysport_cb), GFP_KERNEL);
+	if (!priv->rx_cbs) {
+		netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
+		return -ENOMEM;
+	}
+
+	ret = bcm_sysport_alloc_rx_bufs(priv);
+	if (ret) {
+		netif_err(priv, hw, priv->netdev, "SKB allocation failed\n");
+		return ret;
+	}
+
+	/* Initialize HW, ensure RDMA is disabled */
+	reg = rdma_readl(priv, RDMA_STATUS);
+	if (!(reg & RDMA_DISABLED))
+		rdma_enable_set(priv, 0);
+
+	rdma_writel(priv, 0, RDMA_WRITE_PTR_LO);
+	rdma_writel(priv, 0, RDMA_WRITE_PTR_HI);
+	rdma_writel(priv, 0, RDMA_PROD_INDEX);
+	rdma_writel(priv, 0, RDMA_CONS_INDEX);
+	rdma_writel(priv, priv->num_rx_bds << RDMA_RING_SIZE_SHIFT |
+			  RX_BUF_LENGTH, RDMA_RING_BUF_SIZE);
+	/* Operate the queue in ring mode */
+	rdma_writel(priv, 0, RDMA_START_ADDR_HI);
+	rdma_writel(priv, 0, RDMA_START_ADDR_LO);
+	rdma_writel(priv, 0, RDMA_END_ADDR_HI);
+	rdma_writel(priv, NUM_HW_RX_DESC_WORDS - 1, RDMA_END_ADDR_LO);
+
+	rdma_writel(priv, 1, RDMA_MBDONE_INTR);
+
+	netif_dbg(priv, hw, priv->netdev,
+			"RDMA cfg, num_rx_bds=%d, rx_bds=%p\n",
+			priv->num_rx_bds, priv->rx_bds);
+
+	return 0;
+}
+
+static void bcm_sysport_fini_rx_ring(struct bcm_sysport_priv *priv)
+{
+	struct bcm_sysport_cb *cb;
+	unsigned int i;
+	u32 reg;
+
+	/* Caller should ensure RDMA is disabled */
+	reg = rdma_readl(priv, RDMA_STATUS);
+	if (!(reg & RDMA_DISABLED))
+		netdev_warn(priv->netdev, "RDMA not stopped!\n");
+
+	for (i = 0; i < priv->num_rx_bds; i++) {
+		cb = &priv->rx_cbs[i];
+		if (dma_unmap_addr(cb, dma_addr))
+			dma_unmap_single(&priv->pdev->dev,
+					dma_unmap_addr(cb, dma_addr),
+					RX_BUF_LENGTH, DMA_FROM_DEVICE);
+		bcm_sysport_free_cb(cb);
+	}
+
+	kfree(priv->rx_cbs);
+	priv->rx_cbs = NULL;
+
+	netif_dbg(priv, hw, priv->netdev, "RDMA fini done\n");
+}
+
+static void bcm_sysport_set_rx_mode(struct net_device *dev)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	u32 reg;
+
+	reg = umac_readl(priv, UMAC_CMD);
+	if (dev->flags & IFF_PROMISC)
+		reg |= CMD_PROMISC;
+	else
+		reg &= ~CMD_PROMISC;
+	umac_writel(priv, reg, UMAC_CMD);
+
+	/* No support for ALLMULTI */
+	if (dev->flags & IFF_ALLMULTI)
+		return;
+}
+
+static inline void umac_enable_set(struct bcm_sysport_priv *priv,
+					unsigned int enable)
+{
+	u32 reg;
+
+	reg = umac_readl(priv, UMAC_CMD);
+	if (enable)
+		reg |= CMD_RX_EN | CMD_TX_EN;
+	else
+		reg &= ~(CMD_RX_EN | CMD_TX_EN);
+	umac_writel(priv, reg, UMAC_CMD);
+}
+
+static inline int umac_reset(struct bcm_sysport_priv *priv)
+{
+	unsigned int timeout = 0;
+	u32 reg;
+	int ret = 0;
+
+	umac_writel(priv, 0, UMAC_CMD);
+	while (timeout++ < 1000) {
+		reg = umac_readl(priv, UMAC_CMD);
+		if (!(reg & CMD_SW_RESET))
+			break;
+
+		udelay(1);
+	}
+
+	if (timeout == 1000) {
+		dev_err(&priv->pdev->dev,
+			"timeout waiting for MAC to come out of reset\n");
+		ret = -ETIMEDOUT;
+	}
+
+	return ret;
+}
+
+static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
+				unsigned char *addr)
+{
+	umac_writel(priv, (addr[0] << 24) | (addr[1] << 16) |
+			(addr[2] << 8) | addr[3], UMAC_MAC0);
+	umac_writel(priv, (addr[4] << 8) | addr[5], UMAC_MAC1);
+}
+
+static void topctrl_flush(struct bcm_sysport_priv *priv)
+{
+	topctrl_writel(priv, RX_FLUSH, RX_FLUSH_CNTL);
+	topctrl_writel(priv, TX_FLUSH, TX_FLUSH_CNTL);
+	mdelay(1);
+	topctrl_writel(priv, 0, RX_FLUSH_CNTL);
+	topctrl_writel(priv, 0, TX_FLUSH_CNTL);
+}
+
+static int bcm_sysport_open(struct net_device *dev)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	unsigned int i;
+	u32 reg;
+	int ret;
+
+	/* Reset UniMAC */
+	ret = umac_reset(priv);
+	if (ret) {
+		netdev_err(dev, "UniMAC reset failed\n");
+		return ret;
+	}
+
+	/* Flush TX and RX FIFOs at TOPCTRL level */
+	topctrl_flush(priv);
+
+	/* Disable the UniMAC RX/TX */
+	umac_enable_set(priv, 0);
+
+	/* Enable RBUF 2bytes alignment and Receive Status Block */
+	reg = rbuf_readl(priv, RBUF_CONTROL);
+	reg |= RBUF_4B_ALGN | RBUF_RSB_EN;
+	rbuf_writel(priv, reg, RBUF_CONTROL);
+
+	/* Set maximum frame length */
+	umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+
+	/* Set MAC address */
+	umac_set_hw_addr(priv, dev->dev_addr);
+
+	/* Read CRC forward */
+	priv->crc_fwd = !!(umac_readl(priv, UMAC_CMD) & CMD_CRC_FWD);
+
+	priv->phydev = of_phy_connect_fixed_link(dev, bcm_sysport_adj_link,
+							priv->phy_interface);
+	if (!priv->phydev) {
+		netdev_err(dev, "could not attach to PHY\n");
+		return -ENODEV;
+	}
+
+	/* Reset house keeping link status */
+	priv->old_duplex = -1;
+	priv->old_link = -1;
+	priv->old_pause = -1;
+
+	/* mask all interrupts and request them */
+	intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
+	intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+	intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+	intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
+	intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+	intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+
+	ret = request_irq(priv->irq0, bcm_sysport_rx_isr, 0, dev->name, dev);
+	if (ret) {
+		netdev_err(dev, "failed to request RX interrupt\n");
+		goto out_phy_disconnect;
+	}
+
+	ret = request_irq(priv->irq1, bcm_sysport_tx_isr, 0, dev->name, dev);
+	if (ret) {
+		netdev_err(dev, "failed to request TX interrupt\n");
+		goto out_free_irq0;
+	}
+
+	/* Initialize both hardware and software ring */
+	for (i = 0; i < dev->num_tx_queues; i++) {
+		ret = bcm_sysport_init_tx_ring(priv, i);
+		if (ret) {
+			netdev_err(dev, "failed to initialize TX ring %d\n",
+					i);
+			goto out_free_tx_ring;
+		}
+	}
+
+	/* Initialize linked-list */
+	tdma_writel(priv, TDMA_LL_RAM_INIT_BUSY, TDMA_STATUS);
+
+	/* Initialize RX ring */
+	ret = bcm_sysport_init_rx_ring(priv);
+	if (ret) {
+		netdev_err(dev, "failed to initialize RX ring\n");
+		goto out_free_rx_ring;
+	}
+
+	/* Turn on RDMA */
+	ret = rdma_enable_set(priv, 1);
+	if (ret)
+		goto out_free_rx_ring;
+
+	/* Enable RX interrupt and TX ring full interrupt */
+	intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+
+	/* Turn on TDMA */
+	ret = tdma_enable_set(priv, 1);
+	if (ret)
+		goto out_clear_rx_int;
+
+	/* Enable NAPI */
+	napi_enable(&priv->napi);
+
+	/* Turn on UniMAC TX/RX */
+	umac_enable_set(priv, 1);
+
+	phy_start(priv->phydev);
+
+	/* Enable TX interrupts for the 32 TXQs */
+	intrl2_1_mask_clear(priv, 0xffffffff);
+
+	/* Last call before we start the real business */
+	netif_tx_start_all_queues(dev);
+
+	return 0;
+
+out_clear_rx_int:
+	intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+out_free_rx_ring:
+	bcm_sysport_fini_rx_ring(priv);
+out_free_tx_ring:
+	for (i = 0; i < dev->num_tx_queues; i++)
+		bcm_sysport_fini_tx_ring(priv, i);
+	free_irq(priv->irq1, dev);
+out_free_irq0:
+	free_irq(priv->irq0, dev);
+out_phy_disconnect:
+	phy_disconnect(priv->phydev);
+	return ret;
+}
+
+static int bcm_sysport_stop(struct net_device *dev)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	unsigned int i;
+	u32 reg;
+	int ret;
+
+	/* stop all software from updating hardware */
+	netif_tx_stop_all_queues(dev);
+	napi_disable(&priv->napi);
+	phy_stop(priv->phydev);
+
+	/* mask all interrupts */
+	intrl2_0_mask_set(priv, 0xffffffff);
+	intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+	intrl2_1_mask_set(priv, 0xffffffff);
+	intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+
+	/* Disable UniMAC RX */
+	reg = umac_readl(priv, UMAC_CMD);
+	reg &= ~CMD_RX_EN;
+	umac_writel(priv, reg, UMAC_CMD);
+
+	ret = tdma_enable_set(priv, 0);
+	if (ret) {
+		netdev_err(dev, "timeout disabling RDMA\n");
+		return ret;
+	}
+
+	/* Wait for a maximum packet size to be drained */
+	usleep_range(2000, 3000);
+
+	ret = rdma_enable_set(priv, 0);
+	if (ret) {
+		netdev_err(dev, "timeout disabling TDMA\n");
+		return ret;
+	}
+
+	/* Disable UniMAC TX */
+	reg = umac_readl(priv, UMAC_CMD);
+	reg &= ~CMD_TX_EN;
+	umac_writel(priv, reg, UMAC_CMD);
+
+	/* Free RX/TX rings SW structures */
+	for (i = 0; i < dev->num_tx_queues; i++)
+		bcm_sysport_fini_tx_ring(priv, i);
+	bcm_sysport_fini_rx_ring(priv);
+
+	free_irq(priv->irq0, dev);
+	free_irq(priv->irq1, dev);
+
+	/* Disconnect from PHY */
+	phy_disconnect(priv->phydev);
+
+	return 0;
+}
+
+static struct ethtool_ops bcm_sysport_ethtool_ops = {
+	.get_settings		= bcm_sysport_get_settings,
+	.set_settings		= bcm_sysport_set_settings,
+	.get_drvinfo		= bcm_sysport_get_drvinfo,
+	.get_msglevel		= bcm_sysport_get_msglvl,
+	.set_msglevel		= bcm_sysport_set_msglvl,
+	.get_link		= ethtool_op_get_link,
+	.get_strings		= bcm_sysport_get_strings,
+	.get_ethtool_stats	= bcm_sysport_get_stats,
+	.get_sset_count		= bcm_sysport_get_sset_count,
+};
+
+static const struct net_device_ops bcm_sysport_netdev_ops = {
+	.ndo_start_xmit		= bcm_sysport_xmit,
+	.ndo_tx_timeout		= bcm_sysport_tx_timeout,
+	.ndo_open		= bcm_sysport_open,
+	.ndo_stop		= bcm_sysport_stop,
+	.ndo_set_features	= bcm_sysport_set_features,
+	.ndo_set_rx_mode	= bcm_sysport_set_rx_mode,
+};
+
+#define REV_FMT	"v%2x.%02x"
+
+static int bcm_sysport_probe(struct platform_device *pdev)
+{
+	struct bcm_sysport_priv *priv;
+	struct device_node *dn;
+	struct net_device *dev;
+	const void *macaddr;
+	struct resource *r;
+	u32 txq, rxq;
+	int ret;
+
+	dn = pdev->dev.of_node;
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	/* Read the Transmit/Receive Queue properties */
+	if (of_property_read_u32(dn, "systemport,num-txq", &txq))
+		txq = TDMA_NUM_RINGS;
+	if (of_property_read_u32(dn, "systemport,num-rxq", &rxq))
+		rxq = 1;
+
+	dev = alloc_etherdev_mqs(sizeof(*priv), txq, rxq);
+	if (!dev)
+		return -ENOMEM;
+
+	/* Initialize private members */
+	priv = netdev_priv(dev);
+
+	priv->irq0 = platform_get_irq(pdev, 0);
+	priv->irq1 = platform_get_irq(pdev, 1);
+	if (priv->irq0 <= 0 || priv->irq1 <= 0) {
+		dev_err(&pdev->dev, "invalid interrupts\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	priv->base = devm_request_and_ioremap(&pdev->dev, r);
+	if (!priv->base) {
+		dev_err(&pdev->dev, "register remap failed\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	priv->netdev = dev;
+	priv->pdev = pdev;
+
+	priv->phy_interface = of_get_phy_mode(dn);
+	/* Default to GMII interface mode */
+	if (priv->phy_interface < 0)
+		priv->phy_interface = PHY_INTERFACE_MODE_GMII;
+
+	/* Initialize netdevice members */
+	macaddr = of_get_mac_address(dn);
+	if (!macaddr || !is_valid_ether_addr(macaddr)) {
+		dev_warn(&pdev->dev, "using random Ethernet MAC\n");
+		random_ether_addr(dev->dev_addr);
+	} else {
+		ether_addr_copy(dev->dev_addr, macaddr);
+	}
+
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	dev_set_drvdata(&pdev->dev, dev);
+	SET_ETHTOOL_OPS(dev, &bcm_sysport_ethtool_ops);
+	dev->netdev_ops = &bcm_sysport_netdev_ops;
+	netif_napi_add(dev, &priv->napi, bcm_sysport_poll, 64);
+
+	/* HW supported features, none enabled by default */
+	dev->hw_features |= NETIF_F_RXCSUM | NETIF_F_HIGHDMA |
+				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+	/* Set the needed headroom once and for all */
+	BUILD_BUG_ON(sizeof(struct tsb) != 8);
+	dev->needed_headroom += sizeof(struct tsb);
+
+	/* We are interfaced to a switch which handles the multicast
+	 * filtering for us, so we do not support programming any
+	 * multicast hash table in this Ethernet MAC.
+	 */
+	dev->flags &= ~IFF_MULTICAST;
+
+	ret = register_netdev(dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register net_device\n");
+		goto err;
+	}
+
+	priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
+	dev_info(&pdev->dev,
+		"Broadcom SYSTEMPORT" REV_FMT
+		" at 0x%p (irqs: %d, %d, TXQs: %d, RXQs: %d)\n",
+		(priv->rev >> 8) & 0xff, priv->rev & 0xff,
+		priv->base, priv->irq0, priv->irq1, txq, rxq);
+
+	return 0;
+err:
+	free_netdev(dev);
+	return ret;
+}
+
+static int bcm_sysport_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+
+	/* Not much to do, ndo_close has been called
+	 * and we use managed allocations
+	 */
+	unregister_netdev(dev);
+	free_netdev(dev);
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	return 0;
+}
+
+static const struct of_device_id bcm_sysport_of_match[] = {
+	{ .compatible = "brcm,systemport-v1.00" },
+	{ .compatible = "brcm,systemport" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver bcm_sysport_driver = {
+	.probe	= bcm_sysport_probe,
+	.remove	= bcm_sysport_remove,
+	.driver =  {
+		.name = "brcm-systemport",
+		.owner = THIS_MODULE,
+		.of_match_table = bcm_sysport_of_match,
+	},
+};
+module_platform_driver(bcm_sysport_driver);
+
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_DESCRIPTION("Broadcom System Port Ethernet MAC driver");
+MODULE_ALIAS("platform:brcm-systemport");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
new file mode 100644
index 0000000..a0441e7
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -0,0 +1,677 @@
+/*
+ * Broadcom BCM7xxx System Port Ethernet MAC driver
+ *
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __BCM_SYSPORT_H
+#define __BCM_SYSPORT_H
+
+#include <linux/if_vlan.h>
+
+/* Receive/transmit descriptor format */
+#define DESC_ADDR_HI_STATUS_LEN	0x00
+#define  DESC_ADDR_HI_SHIFT	0
+#define  DESC_ADDR_HI_MASK	0xff
+#define  DESC_STATUS_SHIFT	8
+#define  DESC_STATUS_MASK	0x3ff
+#define  DESC_LEN_SHIFT		18
+#define  DESC_LEN_MASK		0x7fff
+#define DESC_ADDR_LO		0x04
+
+/* HW supports 40-bit addressing hence the */
+#define DESC_SIZE		(WORDS_PER_DESC * sizeof(u32))
+
+/* Default RX buffer allocation size */
+#define RX_BUF_LENGTH		2048
+
+/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
+ * 1536 is multiple of 256 bytes
+ */
+#define ENET_BRCM_TAG_LEN	6
+#define ENET_PAD		8
+#define UMAC_MAX_MTU_SIZE	(ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \
+				 ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
+
+/* Transmit status block */
+struct tsb {
+	u32 pcp_dei_vid;
+#define PCP_DEI_MASK		0xf
+#define VID_SHIFT		4
+#define VID_MASK		0xfff
+	u32 l4_ptr_dest_map;
+#define L4_CSUM_PTR_MASK	0x1ff
+#define L4_PTR_SHIFT		9
+#define L4_PTR_MASK		0x1ff
+#define L4_UDP			(1 << 18)
+#define L4_LENGTH_VALID		(1 << 19)
+#define DEST_MAP_SHIFT		20
+#define DEST_MAP_MASK		0x1ff
+};
+
+/* Receive status block uses the same
+ * definitions as the DMA descriptor
+ */
+struct rsb {
+	u32 rx_status_len;
+	u32 brcm_egress_tag;
+};
+
+/* Common Receive/Transmit status bits */
+#define DESC_L4_CSUM		(1 << 7)
+#define DESC_SOP		(1 << 8)
+#define DESC_EOP		(1 << 9)
+
+/* Receive Status bits */
+#define RX_STATUS_UCAST			0
+#define RX_STATUS_BCAST			0x04
+#define RX_STATUS_MCAST			0x08
+#define RX_STATUS_L2_MCAST		0x0c
+#define RX_STATUS_ERR			(1 << 4)
+#define RX_STATUS_OVFLOW		(1 << 5)
+#define RX_STATUS_PARSE_FAIL		(1 << 6)
+
+/* Transmit Status bits */
+#define TX_STATUS_VLAN_NO_ACT		0x00
+#define TX_STATUS_VLAN_PCP_TSB		0x01
+#define TX_STATUS_VLAN_QUEUE		0x02
+#define TX_STATUS_VLAN_VID_TSB		0x03
+#define TX_STATUS_OWR_CRC		(1 << 2)
+#define TX_STATUS_APP_CRC		(1 << 3)
+#define TX_STATUS_BRCM_TAG_NO_ACT	0
+#define TX_STATUS_BRCM_TAG_ZERO		0x10
+#define TX_STATUS_BRCM_TAG_ONE_QUEUE	0x20
+#define TX_STATUS_BRCM_TAG_ONE_TSB	0x30
+#define TX_STATUS_SKIP_BYTES		(1 << 6)
+
+/* Specific register definitions */
+#define SYS_PORT_TOPCTRL_OFFSET		0
+#define REV_CNTL			0x00
+#define  REV_MASK			0xffff
+
+#define RX_FLUSH_CNTL			0x04
+#define  RX_FLUSH			(1 << 0)
+
+#define TX_FLUSH_CNTL			0x08
+#define  TX_FLUSH			(1 << 0)
+
+#define MISC_CNTL			0x0c
+#define  SYS_CLK_SEL			(1 << 0)
+#define  TDMA_EOP_SEL			(1 << 1)
+
+/* Level-2 Interrupt controller offsets and defines */
+#define SYS_PORT_INTRL2_0_OFFSET	0x200
+#define SYS_PORT_INTRL2_1_OFFSET	0x240
+#define INTRL2_CPU_STATUS		0x00
+#define INTRL2_CPU_SET			0x04
+#define INTRL2_CPU_CLEAR		0x08
+#define INTRL2_CPU_MASK_STATUS		0x0c
+#define INTRL2_CPU_MASK_SET		0x10
+#define INTRL2_CPU_MASK_CLEAR		0x14
+
+/* Level-2 instance 0 interrupt bits */
+#define INTRL2_0_GISB_ERR		(1 << 0)
+#define INTRL2_0_RBUF_OVFLOW		(1 << 1)
+#define INTRL2_0_TBUF_UNDFLOW		(1 << 2)
+#define INTRL2_0_MPD			(1 << 3)
+#define INTRL2_0_BRCM_MATCH_TAG		(1 << 4)
+#define INTRL2_0_RDMA_MBDONE		(1 << 5)
+#define INTRL2_0_OVER_MAX_THRESH	(1 << 6)
+#define INTRL2_0_BELOW_HYST_THRESH	(1 << 7)
+#define INTRL2_0_FREE_LIST_EMPTY	(1 << 8)
+#define INTRL2_0_TX_RING_FULL		(1 << 9)
+#define INTRL2_0_DESC_ALLOC_ERR		(1 << 10)
+#define INTRL2_0_UNEXP_PKTSIZE_ACK	(1 << 11)
+
+/* RXCHK offset and defines */
+#define SYS_PORT_RXCHK_OFFSET		0x300
+
+#define RXCHK_CONTROL			0x00
+#define  RXCHK_EN			(1 << 0)
+#define  RXCHK_SKIP_FCS			(1 << 1)
+#define  RXCHK_BAD_CSUM_DIS		(1 << 2)
+#define  RXCHK_BRCM_TAG_EN		(1 << 3)
+#define  RXCHK_BRCM_TAG_MATCH_SHIFT	4
+#define  RXCHK_BRCM_TAG_MATCH_MASK	0xff
+#define  RXCHK_PARSE_TNL		(1 << 12)
+#define  RXCHK_VIOL_EN			(1 << 13)
+#define  RXCHK_VIOL_DIS			(1 << 14)
+#define  RXCHK_INCOM_PKT		(1 << 15)
+#define  RXCHK_V6_DUPEXT_EN		(1 << 16)
+#define  RXCHK_V6_DUPEXT_DIS		(1 << 17)
+#define  RXCHK_ETHERTYPE_DIS		(1 << 18)
+#define  RXCHK_L2_HDR_DIS		(1 << 19)
+#define  RXCHK_L3_HDR_DIS		(1 << 20)
+#define  RXCHK_MAC_RX_ERR_DIS		(1 << 21)
+#define  RXCHK_PARSE_AUTH		(1 << 22)
+
+#define RXCHK_BRCM_TAG0			0x04
+#define RXCHK_BRCM_TAG(i)		((i) * RXCHK_BRCM_TAG0)
+#define RXCHK_BRCM_TAG0_MASK		0x24
+#define RXCHK_BRCM_TAG_MASK(i)		((i) * RXCHK_BRCM_TAG0_MASK)
+#define RXCHK_BRCM_TAG_MATCH_STATUS	0x44
+#define RXCHK_ETHERTYPE			0x48
+#define RXCHK_BAD_CSUM_CNTR		0x4C
+#define RXCHK_OTHER_DISC_CNTR		0x50
+
+/* TXCHCK offsets and defines */
+#define SYS_PORT_TXCHK_OFFSET		0x380
+#define TXCHK_PKT_RDY_THRESH		0x00
+
+/* Receive buffer offset and defines */
+#define SYS_PORT_RBUF_OFFSET		0x400
+
+#define RBUF_CONTROL			0x00
+#define  RBUF_RSB_EN			(1 << 0)
+#define  RBUF_4B_ALGN			(1 << 1)
+#define  RBUF_BRCM_TAG_STRIP		(1 << 2)
+#define  RBUF_BAD_PKT_DISC		(1 << 3)
+#define  RBUF_RESUME_THRESH_SHIFT	4
+#define  RBUF_RESUME_THRESH_MASK	0xff
+#define  RBUF_OK_TO_SEND_SHIFT		12
+#define  RBUF_OK_TO_SEND_MASK		0xff
+#define  RBUF_CRC_REPLACE		(1 << 20)
+#define  RBUF_OK_TO_SEND_MODE		(1 << 21)
+#define  RBUF_RSB_SWAP			(1 << 22)
+#define  RBUF_ACPI_EN			(1 << 23)
+
+#define RBUF_PKT_RDY_THRESH		0x04
+
+#define RBUF_STATUS			0x08
+#define  RBUF_WOL_MODE			(1 << 0)
+#define  RBUF_MPD			(1 << 1)
+#define  RBUF_ACPI			(1 << 2)
+
+#define RBUF_OVFL_DISC_CNTR		0x0c
+#define RBUF_ERR_PKT_CNTR		0x10
+
+/* Transmit buffer offset and defines */
+#define SYS_PORT_TBUF_OFFSET		0x600
+
+#define TBUF_CONTROL			0x00
+#define  TBUF_BP_EN			(1 << 0)
+#define  TBUF_MAX_PKT_THRESH_SHIFT	1
+#define  TBUF_MAX_PKT_THRESH_MASK	0x1f
+#define  TBUF_FULL_THRESH_SHIFT		8
+#define  TBUF_FULL_THRESH_MASK		0x1f
+
+/* UniMAC offset and defines */
+#define SYS_PORT_UMAC_OFFSET		0x800
+
+#define UMAC_CMD			0x008
+#define  CMD_TX_EN			(1 << 0)
+#define  CMD_RX_EN			(1 << 1)
+#define  CMD_SPEED_SHIFT		2
+#define  CMD_SPEED_10			0
+#define  CMD_SPEED_100			1
+#define  CMD_SPEED_1000			2
+#define  CMD_SPEED_2500			3
+#define  CMD_SPEED_MASK			3
+#define  CMD_PROMISC			(1 << 4)
+#define  CMD_PAD_EN			(1 << 5)
+#define  CMD_CRC_FWD			(1 << 6)
+#define  CMD_PAUSE_FWD			(1 << 7)
+#define  CMD_RX_PAUSE_IGNORE		(1 << 8)
+#define  CMD_TX_ADDR_INS		(1 << 9)
+#define  CMD_HD_EN			(1 << 10)
+#define  CMD_SW_RESET			(1 << 13)
+#define  CMD_LCL_LOOP_EN		(1 << 15)
+#define  CMD_AUTO_CONFIG		(1 << 22)
+#define  CMD_CNTL_FRM_EN		(1 << 23)
+#define  CMD_NO_LEN_CHK			(1 << 24)
+#define  CMD_RMT_LOOP_EN		(1 << 25)
+#define  CMD_PRBL_EN			(1 << 27)
+#define  CMD_TX_PAUSE_IGNORE		(1 << 28)
+#define  CMD_TX_RX_EN			(1 << 29)
+#define  CMD_RUNT_FILTER_DIS		(1 << 30)
+
+#define UMAC_MAC0			0x00c
+#define UMAC_MAC1			0x010
+#define UMAC_MAX_FRAME_LEN		0x014
+
+#define UMAC_TX_FLUSH			0x334
+
+#define UMAC_MIB_START			0x400
+
+/* There is a 0xC gap between the end of RX and beginning of TX stats and then
+ * between the end of TX stats and the beginning of the RX RUNT
+ */
+#define UMAC_MIB_STAT_OFFSET		0xc
+
+#define UMAC_MIB_CTRL			0x580
+#define  MIB_RX_CNT_RST			(1 << 0)
+#define  MIB_RUNT_CNT_RST		(1 << 1)
+#define  MIB_TX_CNT_RST			(1 << 2)
+#define UMAC_MDF_CTRL			0x650
+#define UMAC_MDF_ADDR			0x654
+
+/* Receive DMA offset and defines */
+#define SYS_PORT_RDMA_OFFSET		0x2000
+
+#define RDMA_CONTROL			0x1000
+#define  RDMA_EN			(1 << 0)
+#define  RDMA_RING_CFG			(1 << 1)
+#define  RDMA_DISC_EN			(1 << 2)
+#define  RDMA_BUF_DATA_OFFSET_SHIFT	4
+#define  RDMA_BUF_DATA_OFFSET_MASK	0x3ff
+
+#define RDMA_STATUS			0x1004
+#define  RDMA_DISABLED			(1 << 0)
+#define  RDMA_DESC_RAM_INIT_BUSY	(1 << 1)
+#define  RDMA_BP_STATUS			(1 << 2)
+
+#define RDMA_SCB_BURST_SIZE		0x1008
+
+#define RDMA_RING_BUF_SIZE		0x100c
+#define  RDMA_RING_SIZE_SHIFT		16
+
+#define RDMA_WRITE_PTR_HI		0x1010
+#define RDMA_WRITE_PTR_LO		0x1014
+#define RDMA_PROD_INDEX			0x1018
+#define  RDMA_PROD_INDEX_MASK		0xffff
+
+#define RDMA_CONS_INDEX			0x101c
+#define  RDMA_CONS_INDEX_MASK		0xffff
+
+#define RDMA_START_ADDR_HI		0x1020
+#define RDMA_START_ADDR_LO		0x1024
+#define RDMA_END_ADDR_HI		0x1028
+#define RDMA_END_ADDR_LO		0x102c
+
+#define RDMA_MBDONE_INTR		0x1030
+#define  RDMA_INTR_THRESH_MASK		0xff
+#define  RDMA_TIMEOUT_SHIFT		16
+#define  RDMA_TIMEOUT_MASK		0xffff
+
+#define RDMA_XON_XOFF_THRESH		0x1034
+#define  RDMA_XON_XOFF_THRESH_MASK	0xffff
+#define  RDMA_XOFF_THRESH_SHIFT		16
+
+#define RDMA_READ_PTR_HI		0x1038
+#define RDMA_READ_PTR_LO		0x103c
+
+#define RDMA_OVERRIDE			0x1040
+#define  RDMA_LE_MODE			(1 << 0)
+#define  RDMA_REG_MODE			(1 << 1)
+
+#define RDMA_TEST			0x1044
+#define  RDMA_TP_OUT_SEL		(1 << 0)
+#define  RDMA_MEM_SEL			(1 << 1)
+
+#define RDMA_DEBUG			0x1048
+
+/* Transmit DMA offset and defines */
+#define TDMA_NUM_RINGS			32	/* rings = queues */
+#define TDMA_PORT_SIZE			DESC_SIZE /* two 32-bits words */
+
+#define SYS_PORT_TDMA_OFFSET		0x4000
+#define TDMA_WRITE_PORT_OFFSET		0x0000
+#define TDMA_WRITE_PORT_HI(i)		(TDMA_WRITE_PORT_OFFSET + \
+					(i) * TDMA_PORT_SIZE)
+#define TDMA_WRITE_PORT_LO(i)		(TDMA_WRITE_PORT_OFFSET + \
+					sizeof(u32) + (i) * TDMA_PORT_SIZE)
+
+#define TDMA_READ_PORT_OFFSET		(TDMA_WRITE_PORT_OFFSET + \
+					(TDMA_NUM_RINGS * TDMA_PORT_SIZE))
+#define TDMA_READ_PORT_HI(i)		(TDMA_READ_PORT_OFFSET + \
+					(i) * TDMA_PORT_SIZE)
+#define TDMA_READ_PORT_LO(i)		(TDMA_READ_PORT_OFFSET + \
+					sizeof(u32) + (i) * TDMA_PORT_SIZE)
+
+#define TDMA_READ_PORT_CMD_OFFSET	(TDMA_READ_PORT_OFFSET + \
+					(TDMA_NUM_RINGS * TDMA_PORT_SIZE))
+#define TDMA_READ_PORT_CMD(i)		(TDMA_READ_PORT_CMD_OFFSET + \
+					(i) * sizeof(u32))
+
+#define TDMA_DESC_RING_00_BASE		(TDMA_READ_PORT_CMD_OFFSET + \
+					(TDMA_NUM_RINGS * sizeof(u32)))
+
+/* Register offsets and defines relatives to a specific ring number */
+#define RING_HEAD_TAIL_PTR		0x00
+#define  RING_HEAD_MASK			0x7ff
+#define  RING_TAIL_SHIFT		11
+#define  RING_TAIL_MASK			0x7ff
+#define  RING_FLUSH			(1 << 24)
+#define  RING_EN			(1 << 25)
+
+#define RING_COUNT			0x04
+#define  RING_COUNT_MASK		0x7ff
+#define  RING_BUFF_DONE_SHIFT		11
+#define  RING_BUFF_DONE_MASK		0x7ff
+
+#define RING_MAX_HYST			0x08
+#define  RING_MAX_THRESH_MASK		0x7ff
+#define  RING_HYST_THRESH_SHIFT		11
+#define  RING_HYST_THRESH_MASK		0x7ff
+
+#define RING_INTR_CONTROL		0x0c
+#define  RING_INTR_THRESH_MASK		0x7ff
+#define  RING_EMPTY_INTR_EN		(1 << 15)
+#define  RING_TIMEOUT_SHIFT		16
+#define  RING_TIMEOUT_MASK		0xffff
+
+#define RING_PROD_CONS_INDEX		0x10
+#define  RING_PROD_INDEX_MASK		0xffff
+#define  RING_CONS_INDEX_SHIFT		16
+#define  RING_CONS_INDEX_MASK		0xffff
+
+#define RING_MAPPING			0x14
+#define  RING_QID_MASK			0x3
+#define  RING_PORT_ID_SHIFT		3
+#define  RING_PORT_ID_MASK		0x7
+#define  RING_IGNORE_STATUS		(1 << 6)
+#define  RING_FAILOVER_EN		(1 << 7)
+#define  RING_CREDIT_SHIFT		8
+#define  RING_CREDIT_MASK		0xffff
+
+#define RING_PCP_DEI_VID		0x18
+#define  RING_VID_MASK			0x7ff
+#define  RING_DEI			(1 << 12)
+#define  RING_PCP_SHIFT			13
+#define  RING_PCP_MASK			0x7
+#define  RING_PKT_SIZE_ADJ_SHIFT	16
+#define  RING_PKT_SIZE_ADJ_MASK		0xf
+
+#define TDMA_DESC_RING_SIZE		28
+
+/* Defininition for a given TX ring base address */
+#define TDMA_DESC_RING_BASE(i)		(TDMA_DESC_RING_00_BASE + \
+					((i) * TDMA_DESC_RING_SIZE))
+
+/* Ring indexed register addreses */
+#define TDMA_DESC_RING_HEAD_TAIL_PTR(i)	(TDMA_DESC_RING_BASE(i) + \
+					RING_HEAD_TAIL_PTR)
+#define TDMA_DESC_RING_COUNT(i)		(TDMA_DESC_RING_BASE(i) + \
+					RING_COUNT)
+#define TDMA_DESC_RING_MAX_HYST(i)	(TDMA_DESC_RING_BASE(i) + \
+					RING_MAX_HYST)
+#define TDMA_DESC_RING_INTR_CONTROL(i)	(TDMA_DESC_RING_BASE(i) + \
+					RING_INTR_CONTROL)
+#define TDMA_DESC_RING_PROD_CONS_INDEX(i) \
+					(TDMA_DESC_RING_BASE(i) + \
+					RING_PROD_CONS_INDEX)
+#define TDMA_DESC_RING_MAPPING(i)	(TDMA_DESC_RING_BASE(i) + \
+					RING_MAPPING)
+#define TDMA_DESC_RING_PCP_DEI_VID(i)	(TDMA_DESC_RING_BASE(i) + \
+					RING_PCP_DEI_VID)
+
+#define TDMA_CONTROL			0x600
+#define  TDMA_EN			(1 << 0)
+#define  TSB_EN				(1 << 1)
+#define  TSB_SWAP			(1 << 2)
+#define  ACB_ALGO			(1 << 3)
+#define  BUF_DATA_OFFSET_SHIFT		4
+#define  BUF_DATA_OFFSET_MASK		0x3ff
+#define  VLAN_EN			(1 << 14)
+#define  SW_BRCM_TAG			(1 << 15)
+#define  WNC_KPT_SIZE_UPDATE		(1 << 16)
+#define  SYNC_PKT_SIZE			(1 << 17)
+#define  ACH_TXDONE_DELAY_SHIFT		18
+#define  ACH_TXDONE_DELAY_MASK		0xff
+
+#define TDMA_STATUS			0x604
+#define  TDMA_DISABLED			(1 << 0)
+#define  TDMA_LL_RAM_INIT_BUSY		(1 << 1)
+
+#define TDMA_SCB_BURST_SIZE		0x608
+#define TDMA_OVER_MAX_THRESH_STATUS	0x60c
+#define TDMA_OVER_HYST_THRESH_STATUS	0x610
+#define TDMA_TPID			0x614
+
+#define TDMA_FREE_LIST_HEAD_TAIL_PTR	0x618
+#define  TDMA_FREE_HEAD_MASK		0x7ff
+#define  TDMA_FREE_TAIL_SHIFT		11
+#define  TDMA_FREE_TAIL_MASK		0x7ff
+
+#define TDMA_FREE_LIST_COUNT		0x61c
+#define  TDMA_FREE_LIST_COUNT_MASK	0x7ff
+
+#define TDMA_TIER2_ARB_CTRL		0x620
+#define  TDMA_ARB_MODE_RR		0
+#define  TDMA_ARB_MODE_WEIGHT_RR	0x1
+#define  TDMA_ARB_MODE_STRICT		0x2
+#define  TDMA_ARB_MODE_DEFICIT_RR	0x3
+#define  TDMA_CREDIT_SHIFT		4
+#define  TDMA_CREDIT_MASK		0xffff
+
+#define TDMA_TIER1_ARB_0_CTRL		0x624
+#define  TDMA_ARB_EN			(1 << 0)
+
+#define TDMA_TIER1_ARB_0_QUEUE_EN	0x628
+#define TDMA_TIER1_ARB_1_CTRL		0x62c
+#define TDMA_TIER1_ARB_1_QUEUE_EN	0x630
+#define TDMA_TIER1_ARB_2_CTRL		0x634
+#define TDMA_TIER1_ARB_2_QUEUE_EN	0x638
+#define TDMA_TIER1_ARB_3_CTRL		0x63c
+#define TDMA_TIER1_ARB_3_QUEUE_EN	0x640
+
+#define TDMA_SCB_ENDIAN_OVERRIDE	0x644
+#define  TDMA_LE_MODE			(1 << 0)
+#define  TDMA_REG_MODE			(1 << 1)
+
+#define TDMA_TEST			0x648
+#define  TDMA_TP_OUT_SEL		(1 << 0)
+#define  TDMA_MEM_TM			(1 << 1)
+
+#define TDMA_DEBUG			0x64c
+
+/* Transmit/Receive descriptor */
+struct dma_desc {
+	u32	addr_status_len;
+	u32	addr_lo;
+};
+
+/* Number of Receive hardware descriptor words */
+#define NUM_HW_RX_DESC_WORDS		1024
+/* Real number of usable descriptors */
+#define NUM_RX_DESC			(NUM_HW_RX_DESC_WORDS / WORDS_PER_DESC)
+
+/* Internal linked-list RAM has up to 1536 entries */
+#define NUM_TX_DESC			1536
+
+#define WORDS_PER_DESC			(sizeof(struct dma_desc) / sizeof(u32))
+
+/* Rx/Tx common counter group.*/
+struct bcm_sysport_pkt_counters {
+	u32	cnt_64;		/* RO Received/Transmited 64 bytes packet */
+	u32	cnt_127;	/* RO Rx/Tx 127 bytes packet */
+	u32	cnt_255;	/* RO Rx/Tx 65-255 bytes packet */
+	u32	cnt_511;	/* RO Rx/Tx 256-511 bytes packet */
+	u32	cnt_1023;	/* RO Rx/Tx 512-1023 bytes packet */
+	u32	cnt_1518;	/* RO Rx/Tx 1024-1518 bytes packet */
+	u32	cnt_mgv;	/* RO Rx/Tx 1519-1522 good VLAN packet */
+	u32	cnt_2047;	/* RO Rx/Tx 1522-2047 bytes packet*/
+	u32	cnt_4095;	/* RO Rx/Tx 2048-4095 bytes packet*/
+	u32	cnt_9216;	/* RO Rx/Tx 4096-9216 bytes packet*/
+};
+
+/* RSV, Receive Status Vector */
+struct bcm_sysport_rx_counters {
+	struct  bcm_sysport_pkt_counters pkt_cnt;
+	u32	pkt;		/* RO (0x428) Received pkt count*/
+	u32	bytes;		/* RO Received byte count */
+	u32	mca;		/* RO # of Received multicast pkt */
+	u32	bca;		/* RO # of Receive broadcast pkt */
+	u32	fcs;		/* RO # of Received FCS error  */
+	u32	cf;		/* RO # of Received control frame pkt*/
+	u32	pf;		/* RO # of Received pause frame pkt */
+	u32	uo;		/* RO # of unknown op code pkt */
+	u32	aln;		/* RO # of alignment error count */
+	u32	flr;		/* RO # of frame length out of range count */
+	u32	cde;		/* RO # of code error pkt */
+	u32	fcr;		/* RO # of carrier sense error pkt */
+	u32	ovr;		/* RO # of oversize pkt*/
+	u32	jbr;		/* RO # of jabber count */
+	u32	mtue;		/* RO # of MTU error pkt*/
+	u32	pok;		/* RO # of Received good pkt */
+	u32	uc;		/* RO # of unicast pkt */
+	u32	ppp;		/* RO # of PPP pkt */
+	u32	rcrc;		/* RO (0x470),# of CRC match pkt */
+};
+
+/* TSV, Transmit Status Vector */
+struct bcm_sysport_tx_counters {
+	struct bcm_sysport_pkt_counters pkt_cnt;
+	u32	pkts;		/* RO (0x4a8) Transmited pkt */
+	u32	mca;		/* RO # of xmited multicast pkt */
+	u32	bca;		/* RO # of xmited broadcast pkt */
+	u32	pf;		/* RO # of xmited pause frame count */
+	u32	cf;		/* RO # of xmited control frame count */
+	u32	fcs;		/* RO # of xmited FCS error count */
+	u32	ovr;		/* RO # of xmited oversize pkt */
+	u32	drf;		/* RO # of xmited deferral pkt */
+	u32	edf;		/* RO # of xmited Excessive deferral pkt*/
+	u32	scl;		/* RO # of xmited single collision pkt */
+	u32	mcl;		/* RO # of xmited multiple collision pkt*/
+	u32	lcl;		/* RO # of xmited late collision pkt */
+	u32	ecl;		/* RO # of xmited excessive collision pkt*/
+	u32	frg;		/* RO # of xmited fragments pkt*/
+	u32	ncl;		/* RO # of xmited total collision count */
+	u32	jbr;		/* RO # of xmited jabber count*/
+	u32	bytes;		/* RO # of xmited byte count */
+	u32	pok;		/* RO # of xmited good pkt */
+	u32	uc;		/* RO (0x0x4f0)# of xmited unitcast pkt */
+};
+
+struct bcm_sysport_mib {
+	struct bcm_sysport_rx_counters rx;
+	struct bcm_sysport_tx_counters tx;
+	u32 rx_runt_cnt;
+	u32 rx_runt_fcs;
+	u32 rx_runt_fcs_align;
+	u32 rx_runt_bytes;
+	u32 rxchk_bad_csum;
+	u32 rxchk_other_pkt_disc;
+	u32 rbuf_ovflow_cnt;
+	u32 rbuf_err_cnt;
+};
+
+/* HW maintains a large list of counters */
+enum bcm_sysport_stat_type {
+	BCM_SYSPORT_STAT_NETDEV = -1,
+	BCM_SYSPORT_STAT_MIB_RX,
+	BCM_SYSPORT_STAT_MIB_TX,
+	BCM_SYSPORT_STAT_RUNT,
+	BCM_SYSPORT_STAT_RXCHK,
+	BCM_SYSPORT_STAT_RBUF,
+};
+
+/* Macros to help define ethtool statistics */
+#define STAT_NETDEV(m) { \
+	.stat_string = __stringify(m), \
+	.stat_sizeof = sizeof(((struct net_device_stats *)0)->m), \
+	.stat_offset = offsetof(struct net_device_stats, m), \
+	.type = BCM_SYSPORT_STAT_NETDEV, \
+}
+
+#define STAT_MIB(str, m, _type) { \
+	.stat_string = str, \
+	.stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+	.stat_offset = offsetof(struct bcm_sysport_priv, m), \
+	.type = _type, \
+}
+
+#define STAT_MIB_RX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_RX)
+#define STAT_MIB_TX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_TX)
+#define STAT_RUNT(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_RUNT)
+
+#define STAT_RXCHK(str, m, ofs) { \
+	.stat_string = str, \
+	.stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+	.stat_offset = offsetof(struct bcm_sysport_priv, m), \
+	.type = BCM_SYSPORT_STAT_RXCHK, \
+	.reg_offset = ofs, \
+}
+
+#define STAT_RBUF(str, m, ofs) { \
+	.stat_string = str, \
+	.stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+	.stat_offset = offsetof(struct bcm_sysport_priv, m), \
+	.type = BCM_SYSPORT_STAT_RBUF, \
+	.reg_offset = ofs, \
+}
+
+struct bcm_sysport_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int stat_sizeof;
+	int stat_offset;
+	enum bcm_sysport_stat_type type;
+	/* reg offset from UMAC base for misc counters */
+	u16 reg_offset;
+};
+
+/* Software house keeping helper structure */
+struct bcm_sysport_cb {
+	struct sk_buff	*skb;		/* SKB for RX packets */
+	void __iomem	*bd_addr;	/* Buffer descriptor PHYS addr */
+
+	DEFINE_DMA_UNMAP_ADDR(dma_addr);
+	DEFINE_DMA_UNMAP_LEN(dma_len);
+};
+
+/* Software view of the TX ring */
+struct bcm_sysport_tx_ring {
+	spinlock_t	lock;		/* Ring lock for tx reclaim/xmit */
+	struct napi_struct napi;	/* NAPI per tx queue */
+	dma_addr_t	desc_dma;	/* DMA cookie */
+	unsigned int	index;		/* Ring index */
+	unsigned int	size;		/* Ring current size */
+	unsigned int	alloc_size;	/* Ring one-time allocated size */
+	unsigned int	desc_count;	/* Number of descriptors */
+	unsigned int	curr_desc;	/* Current descriptor */
+	unsigned int	c_index;	/* Last consumer index */
+	unsigned int	p_index;	/* Current producer index */
+	struct bcm_sysport_cb *cbs;	/* Transmit control blocks */
+	struct dma_desc	*desc_cpu;	/* CPU view of the descriptor */
+	struct bcm_sysport_priv *priv;	/* private context backpointer */
+};
+
+/* Driver private structure */
+struct bcm_sysport_priv {
+	void __iomem		*base;
+	u32			irq0_stat;
+	u32			irq0_mask;
+	u32			irq1_stat;
+	u32			irq1_mask;
+	struct napi_struct	napi ____cacheline_aligned;
+	struct net_device	*netdev;
+	struct platform_device	*pdev;
+	int			irq0;
+	int			irq1;
+
+	/* Transmit rings */
+	struct bcm_sysport_tx_ring tx_rings[TDMA_NUM_RINGS];
+
+	/* Receive queue */
+	void __iomem		*rx_bds;
+	void __iomem		*rx_bd_assign_ptr;
+	unsigned int		rx_bd_assign_index;
+	struct bcm_sysport_cb	*rx_cbs;
+	unsigned int		num_rx_bds;
+	unsigned int		rx_read_ptr;
+	unsigned int		rx_c_index;
+
+	/* PHY device */
+	struct phy_device	*phydev;
+	phy_interface_t		phy_interface;
+	int			old_pause;
+	int			old_link;
+	int			old_duplex;
+
+	/* Misc fields */
+	unsigned int		rx_csum_en:1;
+	unsigned int		tsb_en:1;
+	unsigned int		crc_fwd:1;
+	u16			rev;
+
+	/* MIB related fields */
+	struct bcm_sysport_mib	mib;
+
+	/* Ethtool */
+	u32			msg_enable;
+};
+#endif /* __BCM_SYSPORT_H */
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index b9f7022..e5d95c5 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -12286,7 +12286,9 @@
 	if (tg3_flag(tp, MAX_RXPEND_64) &&
 	    tp->rx_pending > 63)
 		tp->rx_pending = 63;
-	tp->rx_jumbo_pending = ering->rx_jumbo_pending;
+
+	if (tg3_flag(tp, JUMBO_RING_ENABLE))
+		tp->rx_jumbo_pending = ering->rx_jumbo_pending;
 
 	for (i = 0; i < tp->irq_max; i++)
 		tp->napi[i].tx_pending = ering->tx_pending;
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 97db5a7..2f67c7c 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -120,6 +120,9 @@
 #define MAX_VFS			30 /* Max VFs supported by BE3 FW */
 #define FW_VER_LEN		32
 
+#define	RSS_INDIR_TABLE_LEN	128
+#define RSS_HASH_KEY_LEN	40
+
 struct be_dma_mem {
 	void *va;
 	dma_addr_t dma;
@@ -409,6 +412,13 @@
 	u32 if_cap_flags;
 };
 
+struct rss_info {
+	u64 rss_flags;
+	u8 rsstable[RSS_INDIR_TABLE_LEN];
+	u8 rss_queue[RSS_INDIR_TABLE_LEN];
+	u8 rss_hkey[RSS_HASH_KEY_LEN];
+};
+
 struct be_adapter {
 	struct pci_dev *pdev;
 	struct net_device *netdev;
@@ -507,7 +517,7 @@
 	u32 msg_enable;
 	int be_get_temp_freq;
 	u8 pf_number;
-	u64 rss_flags;
+	struct rss_info rss_info;
 };
 
 #define be_physfn(adapter)		(!adapter->virtfn)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index d1ec15a..07e78e8 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2020,13 +2020,10 @@
 }
 
 int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
-			u32 rss_hash_opts, u16 table_size)
+			u32 rss_hash_opts, u16 table_size, u8 *rss_hkey)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_rss_config *req;
-	u32 myhash[10] = {0x15d43fa5, 0x2534685a, 0x5f87693a, 0x5668494e,
-			0x33cf6a53, 0x383334c6, 0x76ac4257, 0x59b242b2,
-			0x3ea83c02, 0x4a110304};
 	int status;
 
 	if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
@@ -2049,7 +2046,7 @@
 		req->hdr.version = 1;
 
 	memcpy(req->cpu_table, rsstable, table_size);
-	memcpy(req->hash, myhash, sizeof(myhash));
+	memcpy(req->hash, rss_hkey, RSS_HASH_KEY_LEN);
 	be_dws_cpu_to_le(req->hash, sizeof(req->hash));
 
 	status = be_mbox_notify_wait(adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index b60e4d5..4ea79b9 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -2068,7 +2068,7 @@
 			u32 *function_mode, u32 *function_caps, u16 *asic_rev);
 int be_cmd_reset_function(struct be_adapter *adapter);
 int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
-		      u32 rss_hash_opts, u16 table_size);
+		      u32 rss_hash_opts, u16 table_size, u8 *rss_hkey);
 int be_process_mcc(struct be_adapter *adapter);
 int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon,
 			    u8 status, u8 state);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 15ba96c..6f3494e 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -933,27 +933,27 @@
 
 	switch (flow_type) {
 	case TCP_V4_FLOW:
-		if (adapter->rss_flags & RSS_ENABLE_IPV4)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
 			data |= RXH_IP_DST | RXH_IP_SRC;
-		if (adapter->rss_flags & RSS_ENABLE_TCP_IPV4)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV4)
 			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 		break;
 	case UDP_V4_FLOW:
-		if (adapter->rss_flags & RSS_ENABLE_IPV4)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
 			data |= RXH_IP_DST | RXH_IP_SRC;
-		if (adapter->rss_flags & RSS_ENABLE_UDP_IPV4)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV4)
 			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 		break;
 	case TCP_V6_FLOW:
-		if (adapter->rss_flags & RSS_ENABLE_IPV6)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
 			data |= RXH_IP_DST | RXH_IP_SRC;
-		if (adapter->rss_flags & RSS_ENABLE_TCP_IPV6)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV6)
 			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 		break;
 	case UDP_V6_FLOW:
-		if (adapter->rss_flags & RSS_ENABLE_IPV6)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
 			data |= RXH_IP_DST | RXH_IP_SRC;
-		if (adapter->rss_flags & RSS_ENABLE_UDP_IPV6)
+		if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV6)
 			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 		break;
 	}
@@ -992,7 +992,7 @@
 	struct be_rx_obj *rxo;
 	int status = 0, i, j;
 	u8 rsstable[128];
-	u32 rss_flags = adapter->rss_flags;
+	u32 rss_flags = adapter->rss_info.rss_flags;
 
 	if (cmd->data != L3_RSS_FLAGS &&
 	    cmd->data != (L3_RSS_FLAGS | L4_RSS_FLAGS))
@@ -1039,7 +1039,7 @@
 		return -EINVAL;
 	}
 
-	if (rss_flags == adapter->rss_flags)
+	if (rss_flags == adapter->rss_info.rss_flags)
 		return status;
 
 	if (be_multi_rxq(adapter)) {
@@ -1051,9 +1051,11 @@
 			}
 		}
 	}
-	status = be_cmd_rss_config(adapter, rsstable, rss_flags, 128);
+
+	status = be_cmd_rss_config(adapter, adapter->rss_info.rsstable,
+				   rss_flags, 128, adapter->rss_info.rss_hkey);
 	if (!status)
-		adapter->rss_flags = rss_flags;
+		adapter->rss_info.rss_flags = rss_flags;
 
 	return status;
 }
@@ -1103,6 +1105,68 @@
 	return be_update_queues(adapter);
 }
 
+static u32 be_get_rxfh_indir_size(struct net_device *netdev)
+{
+	return RSS_INDIR_TABLE_LEN;
+}
+
+static u32 be_get_rxfh_key_size(struct net_device *netdev)
+{
+	return RSS_HASH_KEY_LEN;
+}
+
+static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	int i;
+	struct rss_info *rss = &adapter->rss_info;
+
+	if (indir) {
+		for (i = 0; i < RSS_INDIR_TABLE_LEN; i++)
+			indir[i] = rss->rss_queue[i];
+	}
+
+	if (hkey)
+		memcpy(hkey, rss->rss_hkey, RSS_HASH_KEY_LEN);
+
+	return 0;
+}
+
+static int be_set_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey)
+{
+	int rc = 0, i, j;
+	struct be_adapter *adapter = netdev_priv(netdev);
+	u8 rsstable[RSS_INDIR_TABLE_LEN];
+
+	if (indir) {
+		struct be_rx_obj *rxo;
+		for (i = 0; i < RSS_INDIR_TABLE_LEN; i++) {
+			j = indir[i];
+			rxo = &adapter->rx_obj[j];
+			rsstable[i] = rxo->rss_id;
+			adapter->rss_info.rss_queue[i] = j;
+		}
+	} else {
+		memcpy(rsstable, adapter->rss_info.rsstable,
+		       RSS_INDIR_TABLE_LEN);
+	}
+
+	if (!hkey)
+		hkey =  adapter->rss_info.rss_hkey;
+
+	rc = be_cmd_rss_config(adapter, rsstable,
+			adapter->rss_info.rss_flags,
+			RSS_INDIR_TABLE_LEN, hkey);
+	if (rc) {
+		adapter->rss_info.rss_flags = RSS_ENABLE_NONE;
+		return -EIO;
+	}
+	memcpy(adapter->rss_info.rss_hkey, hkey, RSS_HASH_KEY_LEN);
+	memcpy(adapter->rss_info.rsstable, rsstable,
+	       RSS_INDIR_TABLE_LEN);
+	return 0;
+}
+
 const struct ethtool_ops be_ethtool_ops = {
 	.get_settings = be_get_settings,
 	.get_drvinfo = be_get_drvinfo,
@@ -1129,6 +1193,10 @@
 	.self_test = be_self_test,
 	.get_rxnfc = be_get_rxnfc,
 	.set_rxnfc = be_set_rxnfc,
+	.get_rxfh_indir_size = be_get_rxfh_indir_size,
+	.get_rxfh_key_size = be_get_rxfh_key_size,
+	.get_rxfh = be_get_rxfh,
+	.set_rxfh = be_set_rxfh,
 	.get_channels = be_get_channels,
 	.set_channels = be_set_channels
 };
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a186454..a3c6a27 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2774,7 +2774,8 @@
 {
 	struct be_rx_obj *rxo;
 	int rc, i, j;
-	u8 rsstable[128];
+	u8 rss_hkey[RSS_HASH_KEY_LEN];
+	struct rss_info *rss = &adapter->rss_info;
 
 	for_all_rx_queues(adapter, rxo, i) {
 		rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN,
@@ -2799,31 +2800,37 @@
 	}
 
 	if (be_multi_rxq(adapter)) {
-		for (j = 0; j < 128; j += adapter->num_rx_qs - 1) {
+		for (j = 0; j < RSS_INDIR_TABLE_LEN;
+			j += adapter->num_rx_qs - 1) {
 			for_all_rss_queues(adapter, rxo, i) {
-				if ((j + i) >= 128)
+				if ((j + i) >= RSS_INDIR_TABLE_LEN)
 					break;
-				rsstable[j + i] = rxo->rss_id;
+				rss->rsstable[j + i] = rxo->rss_id;
+				rss->rss_queue[j + i] = i;
 			}
 		}
-		adapter->rss_flags = RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 |
-					RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6;
+		rss->rss_flags = RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 |
+			RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6;
 
 		if (!BEx_chip(adapter))
-			adapter->rss_flags |= RSS_ENABLE_UDP_IPV4 |
-						RSS_ENABLE_UDP_IPV6;
+			rss->rss_flags |= RSS_ENABLE_UDP_IPV4 |
+				RSS_ENABLE_UDP_IPV6;
 	} else {
 		/* Disable RSS, if only default RX Q is created */
-		adapter->rss_flags = RSS_ENABLE_NONE;
+		rss->rss_flags = RSS_ENABLE_NONE;
 	}
 
-	rc = be_cmd_rss_config(adapter, rsstable, adapter->rss_flags,
-			       128);
+	get_random_bytes(rss_hkey, RSS_HASH_KEY_LEN);
+	rc = be_cmd_rss_config(adapter, rss->rsstable,
+			       rss->rss_flags,
+			       128, rss_hkey);
 	if (rc) {
-		adapter->rss_flags = RSS_ENABLE_NONE;
+		rss->rss_flags = RSS_ENABLE_NONE;
 		return rc;
 	}
 
+	memcpy(rss->rss_hkey, rss_hkey, RSS_HASH_KEY_LEN);
+
 	/* First time posting */
 	for_all_rx_queues(adapter, rxo, i)
 		be_post_rx_frags(rxo, GFP_KERNEL);
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index 8b70ca7..f3658bd 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -769,11 +769,6 @@
 	return phy_mii_ioctl(phy, ifr, cmd);
 }
 
-static int ethoc_config(struct net_device *dev, struct ifmap *map)
-{
-	return -ENOSYS;
-}
-
 static void ethoc_do_set_mac_address(struct net_device *dev)
 {
 	struct ethoc *priv = netdev_priv(dev);
@@ -995,7 +990,6 @@
 	.ndo_open = ethoc_open,
 	.ndo_stop = ethoc_stop,
 	.ndo_do_ioctl = ethoc_ioctl,
-	.ndo_set_config = ethoc_config,
 	.ndo_set_mac_address = ethoc_set_mac_address,
 	.ndo_set_rx_mode = ethoc_set_multicast_list,
 	.ndo_change_mtu = ethoc_change_mtu,
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 1471c54..e27e609 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -265,10 +265,10 @@
 	u32 tx_hwtstamp_timeouts;
 
 	/* Rx */
-	bool (*clean_rx) (struct e1000_ring *ring, int *work_done,
-			  int work_to_do) ____cacheline_aligned_in_smp;
-	void (*alloc_rx_buf) (struct e1000_ring *ring, int cleaned_count,
-			      gfp_t gfp);
+	bool (*clean_rx)(struct e1000_ring *ring, int *work_done,
+			 int work_to_do) ____cacheline_aligned_in_smp;
+	void (*alloc_rx_buf)(struct e1000_ring *ring, int cleaned_count,
+			     gfp_t gfp);
 	struct e1000_ring *rx_ring;
 
 	u32 rx_int_delay;
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index cad250b..4e5ad7e 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -169,6 +169,7 @@
 		}
 	} else if (!pm_runtime_suspended(netdev->dev.parent)) {
 		u32 status = er32(STATUS);
+
 		if (status & E1000_STATUS_LU) {
 			if (status & E1000_STATUS_SPEED_1000)
 				speed = SPEED_1000;
@@ -783,25 +784,26 @@
 			      reg + (offset << 2), val,
 			      (test[pat] & write & mask));
 			*data = reg;
-			return 1;
+			return true;
 		}
 	}
-	return 0;
+	return false;
 }
 
 static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
 			      int reg, u32 mask, u32 write)
 {
 	u32 val;
+
 	__ew32(&adapter->hw, reg, write & mask);
 	val = __er32(&adapter->hw, reg);
 	if ((write & mask) != (val & mask)) {
 		e_err("set/check test failed (reg 0x%05X): got 0x%08X expected 0x%08X\n",
 		      reg, (val & mask), (write & mask));
 		*data = reg;
-		return 1;
+		return true;
 	}
-	return 0;
+	return false;
 }
 
 #define REG_PATTERN_TEST_ARRAY(reg, offset, mask, write)                       \
@@ -1717,6 +1719,7 @@
 	*data = 0;
 	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
 		int i = 0;
+
 		hw->mac.serdes_has_link = false;
 
 		/* On some blade server designs, link establishment
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 9866f26..a290113 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1320,6 +1320,7 @@
 	 */
 	if ((hw->mac.type == e1000_pch2lan) && link) {
 		u32 reg;
+
 		reg = er32(STATUS);
 		if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
 			reg = er32(TIPG);
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index d50c91e..e4207ef 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -599,6 +599,7 @@
 
 	if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) {
 		u32 rctl = er32(RCTL);
+
 		ew32(RCTL, rctl & ~E1000_RCTL_EN);
 		e_err("ME firmware caused invalid RDT - resetting\n");
 		schedule_work(&adapter->reset_task);
@@ -615,6 +616,7 @@
 
 	if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) {
 		u32 tctl = er32(TCTL);
+
 		ew32(TCTL, tctl & ~E1000_TCTL_EN);
 		e_err("ME firmware caused invalid TDT - resetting\n");
 		schedule_work(&adapter->reset_task);
@@ -1165,7 +1167,7 @@
 		dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
 		adapter->tx_hwtstamp_skb = NULL;
 		adapter->tx_hwtstamp_timeouts++;
-		e_warn("clearing Tx timestamp hang");
+		e_warn("clearing Tx timestamp hang\n");
 	} else {
 		/* reschedule to check later */
 		schedule_work(&adapter->tx_hwtstamp_work);
@@ -1198,6 +1200,7 @@
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
 		bool cleaned = false;
+
 		rmb();		/* read buffer_info after eop_desc */
 		for (; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
@@ -1753,6 +1756,7 @@
 		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
 			/* disable receives */
 			u32 rctl = er32(RCTL);
+
 			ew32(RCTL, rctl & ~E1000_RCTL_EN);
 			adapter->flags |= FLAG_RESTART_NOW;
 		}
@@ -1960,6 +1964,7 @@
 	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
 	if (hw->mac.type == e1000_82574) {
 		u32 rfctl = er32(RFCTL);
+
 		rfctl |= E1000_RFCTL_ACK_DIS;
 		ew32(RFCTL, rfctl);
 	}
@@ -2204,6 +2209,7 @@
 
 	if (adapter->msix_entries) {
 		int i;
+
 		for (i = 0; i < adapter->num_vectors; i++)
 			synchronize_irq(adapter->msix_entries[i].vector);
 	} else {
@@ -2921,6 +2927,7 @@
 
 	if (adapter->flags2 & FLAG2_DMA_BURST) {
 		u32 txdctl = er32(TXDCTL(0));
+
 		txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
 			    E1000_TXDCTL_WTHRESH);
 		/* set up some performance related parameters to encourage the
@@ -3239,6 +3246,7 @@
 
 		if (adapter->flags & FLAG_IS_ICH) {
 			u32 rxdctl = er32(RXDCTL(0));
+
 			ew32(RXDCTL(0), rxdctl | 0x3);
 		}
 
@@ -4695,6 +4703,7 @@
 	/* Correctable ECC Errors */
 	if (hw->mac.type == e1000_pch_lpt) {
 		u32 pbeccsts = er32(PBECCSTS);
+
 		adapter->corr_errors +=
 		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
 		adapter->uncorr_errors +=
@@ -4808,6 +4817,7 @@
 	    (adapter->flags & FLAG_RESTART_NOW)) {
 		struct e1000_hw *hw = &adapter->hw;
 		u32 rctl = er32(RCTL);
+
 		ew32(RCTL, rctl | E1000_RCTL_EN);
 		adapter->flags &= ~FLAG_RESTART_NOW;
 	}
@@ -4930,6 +4940,7 @@
 			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
 			    !txb2b) {
 				u32 tarc0;
+
 				tarc0 = er32(TARC(0));
 				tarc0 &= ~SPEED_MODE_BIT;
 				ew32(TARC(0), tarc0);
@@ -5170,7 +5181,7 @@
 	__be16 protocol;
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL)
-		return 0;
+		return false;
 
 	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
 		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
@@ -5215,7 +5226,7 @@
 		i = 0;
 	tx_ring->next_to_use = i;
 
-	return 1;
+	return true;
 }
 
 static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,
@@ -5687,7 +5698,7 @@
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+	int max_frame = new_mtu + VLAN_HLEN + ETH_HLEN + ETH_FCS_LEN;
 
 	/* Jumbo frame support */
 	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
@@ -6209,6 +6220,7 @@
 		e1e_wphy(&adapter->hw, BM_WUS, ~0);
 	} else {
 		u32 wus = er32(WUS);
+
 		if (wus) {
 			e_info("MAC Wakeup cause - %s\n",
 			       wus & E1000_WUS_EX ? "Unicast Packet" :
@@ -6235,6 +6247,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int e1000e_pm_thaw(struct device *dev)
 {
 	struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
@@ -6255,7 +6268,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
 static int e1000e_pm_suspend(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -7027,7 +7039,7 @@
 	.resume = e1000_io_resume,
 };
 
-static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
+static const struct pci_device_id e1000_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
@@ -7144,6 +7156,7 @@
 static int __init e1000_init_module(void)
 {
 	int ret;
+
 	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
 		e1000e_driver_version);
 	pr_info("Copyright(c) 1999 - 2014 Intel Corporation.\n");
diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c
index a9a976f..b1f212b 100644
--- a/drivers/net/ethernet/intel/e1000e/nvm.c
+++ b/drivers/net/ethernet/intel/e1000e/nvm.c
@@ -398,6 +398,7 @@
 		/* Loop to allow for up to whole page write of eeprom */
 		while (widx < words) {
 			u16 word_out = data[widx];
+
 			word_out = (word_out >> 8) | (word_out << 8);
 			e1000_shift_out_eec_bits(hw, word_out, 16);
 			widx++;
diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c
index d0ac0f3..aa1923f 100644
--- a/drivers/net/ethernet/intel/e1000e/param.c
+++ b/drivers/net/ethernet/intel/e1000e/param.c
@@ -436,6 +436,7 @@
 
 		if (num_IntMode > bd) {
 			unsigned int int_mode = IntMode[bd];
+
 			e1000_validate_option(&int_mode, &opt, adapter);
 			adapter->int_mode = int_mode;
 		} else {
@@ -457,6 +458,7 @@
 
 		if (num_SmartPowerDownEnable > bd) {
 			unsigned int spd = SmartPowerDownEnable[bd];
+
 			e1000_validate_option(&spd, &opt, adapter);
 			if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && spd)
 				adapter->flags |= FLAG_SMART_POWER_DOWN;
@@ -473,6 +475,7 @@
 
 		if (num_CrcStripping > bd) {
 			unsigned int crc_stripping = CrcStripping[bd];
+
 			e1000_validate_option(&crc_stripping, &opt, adapter);
 			if (crc_stripping == OPTION_ENABLED) {
 				adapter->flags2 |= FLAG2_CRC_STRIPPING;
@@ -495,6 +498,7 @@
 
 		if (num_KumeranLockLoss > bd) {
 			unsigned int kmrn_lock_loss = KumeranLockLoss[bd];
+
 			e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
 			enabled = kmrn_lock_loss;
 		}
diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c
index 00b3fc9..b2005e1 100644
--- a/drivers/net/ethernet/intel/e1000e/phy.c
+++ b/drivers/net/ethernet/intel/e1000e/phy.c
@@ -2896,6 +2896,7 @@
 		    (hw->phy.addr == 2) &&
 		    !(MAX_PHY_REG_ADDRESS & reg) && (data & (1 << 11))) {
 			u16 data2 = 0x7EFF;
+
 			ret_val = e1000_access_phy_debug_regs_hv(hw,
 								 (1 << 6) | 0x3,
 								 &data2, false);
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index beb7b43..a46571c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -329,9 +329,7 @@
 	struct ptp_clock *ptp_clock;
 	struct ptp_clock_info ptp_caps;
 	struct sk_buff *ptp_tx_skb;
-	struct work_struct ptp_tx_work;
 	struct hwtstamp_config tstamp_config;
-	unsigned long ptp_tx_start;
 	unsigned long last_rx_ptp_check;
 	spinlock_t tmreg_lock; /* Used to protect the device time registers. */
 	u64 ptp_base_adj;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index ed3902b..34415d3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -33,6 +33,16 @@
 static void i40e_resume_aq(struct i40e_hw *hw);
 
 /**
+ * i40e_is_nvm_update_op - return true if this is an NVM update operation
+ * @desc: API request descriptor
+ **/
+static inline bool i40e_is_nvm_update_op(struct i40e_aq_desc *desc)
+{
+	return (desc->opcode == i40e_aqc_opc_nvm_erase) ||
+	       (desc->opcode == i40e_aqc_opc_nvm_update);
+}
+
+/**
  *  i40e_adminq_init_regs - Initialize AdminQ registers
  *  @hw: pointer to the hardware structure
  *
@@ -585,6 +595,7 @@
 
 	/* pre-emptive resource lock release */
 	i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
+	hw->aq.nvm_busy = false;
 
 	ret_code = i40e_aq_set_hmc_resource_profile(hw,
 						    I40E_HMC_PROFILE_DEFAULT,
@@ -708,6 +719,12 @@
 		goto asq_send_command_exit;
 	}
 
+	if (i40e_is_nvm_update_op(desc) && hw->aq.nvm_busy) {
+		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: NVM busy.\n");
+		status = I40E_ERR_NVM;
+		goto asq_send_command_exit;
+	}
+
 	details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
 	if (cmd_details) {
 		*details = *cmd_details;
@@ -835,6 +852,9 @@
 		hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
 	}
 
+	if (i40e_is_nvm_update_op(desc))
+		hw->aq.nvm_busy = true;
+
 	/* update the error if time out occurred */
 	if ((!cmd_completed) &&
 	    (!details->async && !details->postpone)) {
@@ -929,6 +949,9 @@
 			       e->msg_size);
 	}
 
+	if (i40e_is_nvm_update_op(&e->desc))
+		hw->aq.nvm_busy = false;
+
 	/* Restore the original datalen and buffer address in the desc,
 	 * FW updates datalen to indicate the event message
 	 * size
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
index 993f768..b1552fb 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -90,6 +90,7 @@
 	u16 fw_min_ver;                 /* firmware minor version */
 	u16 api_maj_ver;                /* api major version */
 	u16 api_min_ver;                /* api minor version */
+	bool nvm_busy;
 
 	struct mutex asq_mutex; /* Send queue lock */
 	struct mutex arq_mutex; /* Receive queue lock */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index 7b6374a..f2ba4b7 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -182,9 +182,6 @@
 	i40e_aqc_opc_add_mirror_rule    = 0x0260,
 	i40e_aqc_opc_delete_mirror_rule = 0x0261,
 
-	i40e_aqc_opc_set_storm_control_config = 0x0280,
-	i40e_aqc_opc_get_storm_control_config = 0x0281,
-
 	/* DCB commands */
 	i40e_aqc_opc_dcb_ignore_pfc = 0x0301,
 	i40e_aqc_opc_dcb_updated    = 0x0302,
@@ -207,6 +204,7 @@
 	i40e_aqc_opc_query_switching_comp_bw_config        = 0x041A,
 	i40e_aqc_opc_suspend_port_tx                       = 0x041B,
 	i40e_aqc_opc_resume_port_tx                        = 0x041C,
+	i40e_aqc_opc_configure_partition_bw                = 0x041D,
 
 	/* hmc */
 	i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
@@ -1289,27 +1287,6 @@
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
-/* Set Storm Control Configuration (direct 0x0280)
- * Get Storm Control Configuration (direct 0x0281)
- *    the command and response use the same descriptor structure
- */
-struct i40e_aqc_set_get_storm_control_config {
-	__le32 broadcast_threshold;
-	__le32 multicast_threshold;
-	__le32 control_flags;
-#define I40E_AQC_STORM_CONTROL_MDIPW            0x01
-#define I40E_AQC_STORM_CONTROL_MDICW            0x02
-#define I40E_AQC_STORM_CONTROL_BDIPW            0x04
-#define I40E_AQC_STORM_CONTROL_BDICW            0x08
-#define I40E_AQC_STORM_CONTROL_BIDU             0x10
-#define I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT   8
-#define I40E_AQC_STORM_CONTROL_INTERVAL_MASK    (0x3FF << \
-					I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT)
-	u8     reserved[4];
-};
-
-I40E_CHECK_CMD_LENGTH(i40e_aqc_set_get_storm_control_config);
-
 /* DCB 0x03xx*/
 
 /* PFC Ignore (direct 0x0301)
@@ -1499,6 +1476,15 @@
  * (direct 0x041B and 0x041C) uses the generic SEID struct
  */
 
+/* Configure partition BW
+ * (indirect 0x041D)
+ */
+struct i40e_aqc_configure_partition_bw_data {
+	__le16 pf_valid_bits;
+	u8     min_bw[16];      /* guaranteed bandwidth */
+	u8     max_bw[16];      /* bandwidth limit */
+};
+
 /* Get and set the active HMC resource profile and status.
  * (direct 0x0500) and (direct 0x0501)
  */
@@ -1583,11 +1569,8 @@
 #define I40E_AQ_PHY_FLAG_PAUSE_TX         0x01
 #define I40E_AQ_PHY_FLAG_PAUSE_RX         0x02
 #define I40E_AQ_PHY_FLAG_LOW_POWER        0x04
-#define I40E_AQ_PHY_FLAG_AN_SHIFT         3
-#define I40E_AQ_PHY_FLAG_AN_MASK          (0x3 << I40E_AQ_PHY_FLAG_AN_SHIFT)
-#define I40E_AQ_PHY_FLAG_AN_OFF           0x00 /* link forced on */
-#define I40E_AQ_PHY_FLAG_AN_OFF_LINK_DOWN 0x01
-#define I40E_AQ_PHY_FLAG_AN_ON            0x02
+#define I40E_AQ_PHY_LINK_ENABLED		  0x08
+#define I40E_AQ_PHY_AN_ENABLED			  0x10
 #define I40E_AQ_PHY_FLAG_MODULE_QUAL      0x20
 	__le16 eee_capability;
 #define I40E_AQ_EEE_100BASE_TX       0x0002
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 922cdcc..22eefda 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -975,6 +975,13 @@
 	hw_link_info->an_info = resp->an_info;
 	hw_link_info->ext_info = resp->ext_info;
 	hw_link_info->loopback = resp->loopback;
+	hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size);
+	hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
+
+	if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
+		hw_link_info->crc_enable = true;
+	else
+		hw_link_info->crc_enable = false;
 
 	if (resp->command_flags & cpu_to_le16(I40E_AQ_LSE_ENABLE))
 		hw_link_info->lse_enable = true;
@@ -1300,6 +1307,7 @@
 	struct i40e_aqc_driver_version *cmd =
 		(struct i40e_aqc_driver_version *)&desc.params.raw;
 	i40e_status status;
+	u16 len;
 
 	if (dv == NULL)
 		return I40E_ERR_PARAM;
@@ -1311,7 +1319,14 @@
 	cmd->driver_minor_ver = dv->minor_version;
 	cmd->driver_build_ver = dv->build_version;
 	cmd->driver_subbuild_ver = dv->subbuild_version;
-	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	len = 0;
+	while (len < sizeof(dv->driver_string) &&
+	       (dv->driver_string[len] < 0x80) &&
+	       dv->driver_string[len])
+		len++;
+	status = i40e_asq_send_command(hw, &desc, dv->driver_string,
+				       len, cmd_details);
 
 	return status;
 }
@@ -2094,8 +2109,8 @@
  * @cmd_details: pointer to command details structure or NULL
  **/
 i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
-				u16 udp_port, u8 header_len,
-				u8 protocol_index, u8 *filter_index,
+				u16 udp_port, u8 protocol_index,
+				u8 *filter_index,
 				struct i40e_asq_cmd_details *cmd_details)
 {
 	struct i40e_aq_desc desc;
@@ -2253,6 +2268,35 @@
 }
 
 /**
+ * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
+ * @hw: pointer to the hw struct
+ * @seid: VSI seid
+ * @credit: BW limit credits (0 = disabled)
+ * @max_credit: Max BW limit credits
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
+				u16 seid, u16 credit, u8 max_credit,
+				struct i40e_asq_cmd_details *cmd_details)
+{
+	struct i40e_aq_desc desc;
+	struct i40e_aqc_configure_vsi_bw_limit *cmd =
+		(struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
+	i40e_status status;
+
+	i40e_fill_default_direct_cmd_desc(&desc,
+					  i40e_aqc_opc_configure_vsi_bw_limit);
+
+	cmd->vsi_seid = cpu_to_le16(seid);
+	cmd->credit = cpu_to_le16(credit);
+	cmd->max_credit = max_credit;
+
+	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+	return status;
+}
+
+/**
  * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
  * @hw: pointer to the hw struct
  * @seid: VSI seid
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index 3c37386..1aaec40 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -1744,10 +1744,6 @@
 		i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_ATR_ENABLED, false);
 	} else if (strncmp(cmd_buf, "fd-atr on", 9) == 0) {
 		i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_ATR_ENABLED, true);
-	} else if (strncmp(cmd_buf, "fd-sb off", 9) == 0) {
-		i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_SB_ENABLED, false);
-	} else if (strncmp(cmd_buf, "fd-sb on", 8) == 0) {
-		i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_SB_ENABLED, true);
 	} else if (strncmp(cmd_buf, "lldp", 4) == 0) {
 		if (strncmp(&cmd_buf[5], "stop", 4) == 0) {
 			int ret;
@@ -1967,8 +1963,6 @@
 		dev_info(&pf->pdev->dev, "  rem fd_filter <dest q_index> <flex_off> <pctype> <dest_vsi> <dest_ctl> <fd_status> <cnt_index> <fd_id> <packet_len> <packet>\n");
 		dev_info(&pf->pdev->dev, "  fd-atr off\n");
 		dev_info(&pf->pdev->dev, "  fd-atr on\n");
-		dev_info(&pf->pdev->dev, "  fd-sb off\n");
-		dev_info(&pf->pdev->dev, "  fd-sb on\n");
 		dev_info(&pf->pdev->dev, "  lldp start\n");
 		dev_info(&pf->pdev->dev, "  lldp stop\n");
 		dev_info(&pf->pdev->dev, "  lldp get local\n");
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 03d99cb..0cf47c9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -649,7 +649,7 @@
 			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 	}
 	rcu_read_lock();
-	for (j = 0; j < vsi->num_queue_pairs; j++, i += 4) {
+	for (j = 0; j < vsi->num_queue_pairs; j++) {
 		struct i40e_ring *tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
 		struct i40e_ring *rx_ring;
 
@@ -662,14 +662,16 @@
 			data[i] = tx_ring->stats.packets;
 			data[i + 1] = tx_ring->stats.bytes;
 		} while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
+		i += 2;
 
 		/* Rx ring is the 2nd half of the queue pair */
 		rx_ring = &tx_ring[1];
 		do {
 			start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
-			data[i + 2] = rx_ring->stats.packets;
-			data[i + 3] = rx_ring->stats.bytes;
+			data[i] = rx_ring->stats.packets;
+			data[i + 1] = rx_ring->stats.bytes;
 		} while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
+		i += 2;
 	}
 	rcu_read_unlock();
 	if (vsi == pf->vsi[pf->lan_vsi]) {
@@ -1189,6 +1191,12 @@
 		return -EINVAL;
 
 	fsp->flow_type = rule->flow_type;
+	if (fsp->flow_type == IP_USER_FLOW) {
+		fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
+		fsp->h_u.usr_ip4_spec.proto = 0;
+		fsp->m_u.usr_ip4_spec.proto = 0;
+	}
+
 	fsp->h_u.tcp_ip4_spec.psrc = rule->src_port;
 	fsp->h_u.tcp_ip4_spec.pdst = rule->dst_port;
 	fsp->h_u.tcp_ip4_spec.ip4src = rule->src_ip[0];
diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
index d5d98fe..5c341ae 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
@@ -747,6 +747,7 @@
 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena),  1,	195 },
 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena),  1,	196 },
 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh),   3,	198 },
+	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena),      1,	201 },
 	{ 0 }
 };
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
index 341de92..eb65fe2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
@@ -56,6 +56,7 @@
 	u8  tphdata_ena;
 	u8  tphhead_ena;
 	u8  lrxqthresh;
+	u8  prefena;	/* NOTE: normally must be set to 1 at init */
 };
 
 /* Tx queue context data */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 861b722..109052a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -39,7 +39,7 @@
 
 #define DRV_VERSION_MAJOR 0
 #define DRV_VERSION_MINOR 3
-#define DRV_VERSION_BUILD 36
+#define DRV_VERSION_BUILD 46
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
 	     __stringify(DRV_VERSION_MINOR) "." \
 	     __stringify(DRV_VERSION_BUILD)    DRV_KERN
@@ -2312,6 +2312,8 @@
 	rx_ctx.crcstrip = 1;
 	rx_ctx.l2tsel = 1;
 	rx_ctx.showiv = 1;
+	/* set the prefena field to 1 because the manual says to */
+	rx_ctx.prefena = 1;
 
 	/* clear the context in the HMC */
 	err = i40e_clear_lan_rx_queue_context(hw, pf_q);
@@ -3163,9 +3165,7 @@
 			usleep_range(1000, 2000);
 		}
 		/* Skip if the queue is already in the requested state */
-		if (enable && (tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
-			continue;
-		if (!enable && !(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
+		if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
 			continue;
 
 		/* turn on/off the queue */
@@ -3181,13 +3181,8 @@
 		/* wait for the change to finish */
 		for (j = 0; j < 10; j++) {
 			tx_reg = rd32(hw, I40E_QTX_ENA(pf_q));
-			if (enable) {
-				if ((tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
-					break;
-			} else {
-				if (!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
-					break;
-			}
+			if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
+				break;
 
 			udelay(10);
 		}
@@ -3226,15 +3221,9 @@
 			usleep_range(1000, 2000);
 		}
 
-		if (enable) {
-			/* is STAT set ? */
-			if ((rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
-				continue;
-		} else {
-			/* is !STAT set ? */
-			if (!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
-				continue;
-		}
+		/* Skip if the queue is already in the requested state */
+		if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
+			continue;
 
 		/* turn on/off the queue */
 		if (enable)
@@ -3247,13 +3236,8 @@
 		for (j = 0; j < 10; j++) {
 			rx_reg = rd32(hw, I40E_QRX_ENA(pf_q));
 
-			if (enable) {
-				if ((rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
-					break;
-			} else {
-				if (!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
-					break;
-			}
+			if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
+				break;
 
 			udelay(10);
 		}
@@ -3516,6 +3500,19 @@
 }
 
 /**
+ * i40e_vsi_close - Shut down a VSI
+ * @vsi: the vsi to be quelled
+ **/
+static void i40e_vsi_close(struct i40e_vsi *vsi)
+{
+	if (!test_and_set_bit(__I40E_DOWN, &vsi->state))
+		i40e_down(vsi);
+	i40e_vsi_free_irq(vsi);
+	i40e_vsi_free_tx_resources(vsi);
+	i40e_vsi_free_rx_resources(vsi);
+}
+
+/**
  * i40e_quiesce_vsi - Pause a given VSI
  * @vsi: the VSI being paused
  **/
@@ -3528,8 +3525,7 @@
 	if (vsi->netdev && netif_running(vsi->netdev)) {
 		vsi->netdev->netdev_ops->ndo_stop(vsi->netdev);
 	} else {
-		set_bit(__I40E_DOWN, &vsi->state);
-		i40e_down(vsi);
+		i40e_vsi_close(vsi);
 	}
 }
 
@@ -3546,7 +3542,7 @@
 	if (vsi->netdev && netif_running(vsi->netdev))
 		vsi->netdev->netdev_ops->ndo_open(vsi->netdev);
 	else
-		i40e_up(vsi);   /* this clears the DOWN bit */
+		i40e_vsi_open(vsi);   /* this clears the DOWN bit */
 }
 
 /**
@@ -4031,6 +4027,8 @@
 				 pf->vsi[v]->seid);
 			/* Will try to configure as many components */
 		} else {
+			/* Re-configure VSI vectors based on updated TC map */
+			i40e_vsi_map_rings_to_vectors(pf->vsi[v]);
 			if (pf->vsi[v]->netdev)
 				i40e_dcbnl_set_all(pf->vsi[v]);
 		}
@@ -4070,6 +4068,9 @@
 				       DCB_CAP_DCBX_VER_IEEE;
 			pf->flags |= I40E_FLAG_DCB_ENABLED;
 		}
+	} else {
+		dev_info(&pf->pdev->dev, "AQ Querying DCB configuration failed: %d\n",
+			 pf->hw.aq.asq_last_status);
 	}
 
 out:
@@ -4271,6 +4272,14 @@
 	if (err)
 		return err;
 
+	/* configure global TSO hardware offload settings */
+	wr32(&pf->hw, I40E_GLLAN_TSOMSK_F, be32_to_cpu(TCP_FLAG_PSH |
+						       TCP_FLAG_FIN) >> 16);
+	wr32(&pf->hw, I40E_GLLAN_TSOMSK_M, be32_to_cpu(TCP_FLAG_PSH |
+						       TCP_FLAG_FIN |
+						       TCP_FLAG_CWR) >> 16);
+	wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16);
+
 #ifdef CONFIG_I40E_VXLAN
 	vxlan_get_rx_port(netdev);
 #endif
@@ -4304,24 +4313,32 @@
 	if (err)
 		goto err_setup_rx;
 
-	if (!vsi->netdev) {
+	if (vsi->netdev) {
+		snprintf(int_name, sizeof(int_name) - 1, "%s-%s",
+			 dev_driver_string(&pf->pdev->dev), vsi->netdev->name);
+		err = i40e_vsi_request_irq(vsi, int_name);
+		if (err)
+			goto err_setup_rx;
+
+		/* Notify the stack of the actual queue counts. */
+		err = netif_set_real_num_tx_queues(vsi->netdev,
+						   vsi->num_queue_pairs);
+		if (err)
+			goto err_set_queues;
+
+		err = netif_set_real_num_rx_queues(vsi->netdev,
+						   vsi->num_queue_pairs);
+		if (err)
+			goto err_set_queues;
+
+	} else if (vsi->type == I40E_VSI_FDIR) {
+		snprintf(int_name, sizeof(int_name) - 1, "%s-fdir",
+			 dev_driver_string(&pf->pdev->dev));
+		err = i40e_vsi_request_irq(vsi, int_name);
+	} else {
 		err = EINVAL;
 		goto err_setup_rx;
 	}
-	snprintf(int_name, sizeof(int_name) - 1, "%s-%s",
-		 dev_driver_string(&pf->pdev->dev), vsi->netdev->name);
-	err = i40e_vsi_request_irq(vsi, int_name);
-	if (err)
-		goto err_setup_rx;
-
-	/* Notify the stack of the actual queue counts. */
-	err = netif_set_real_num_tx_queues(vsi->netdev, vsi->num_queue_pairs);
-	if (err)
-		goto err_set_queues;
-
-	err = netif_set_real_num_rx_queues(vsi->netdev, vsi->num_queue_pairs);
-	if (err)
-		goto err_set_queues;
 
 	err = i40e_up_complete(vsi);
 	if (err)
@@ -4378,14 +4395,7 @@
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_vsi *vsi = np->vsi;
 
-	if (test_and_set_bit(__I40E_DOWN, &vsi->state))
-		return 0;
-
-	i40e_down(vsi);
-	i40e_vsi_free_irq(vsi);
-
-	i40e_vsi_free_tx_resources(vsi);
-	i40e_vsi_free_rx_resources(vsi);
+	i40e_vsi_close(vsi);
 
 	return 0;
 }
@@ -5221,9 +5231,6 @@
 		}
 	} while (err);
 
-	/* increment MSI-X count because current FW skips one */
-	pf->hw.func_caps.num_msix_vectors++;
-
 	if (((pf->hw.aq.fw_maj_ver == 2) && (pf->hw.aq.fw_min_ver < 22)) ||
 	    (pf->hw.aq.fw_maj_ver < 2)) {
 		pf->hw.func_caps.num_msix_vectors++;
@@ -5262,8 +5269,7 @@
 static void i40e_fdir_sb_setup(struct i40e_pf *pf)
 {
 	struct i40e_vsi *vsi;
-	bool new_vsi = false;
-	int err, i;
+	int i;
 
 	if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
 		return;
@@ -5283,47 +5289,12 @@
 				     pf->vsi[pf->lan_vsi]->seid, 0);
 		if (!vsi) {
 			dev_info(&pf->pdev->dev, "Couldn't create FDir VSI\n");
-			goto err_vsi;
+			pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
+			return;
 		}
-		new_vsi = true;
 	}
+
 	i40e_vsi_setup_irqhandler(vsi, i40e_fdir_clean_ring);
-
-	err = i40e_vsi_setup_tx_resources(vsi);
-	if (err)
-		goto err_setup_tx;
-	err = i40e_vsi_setup_rx_resources(vsi);
-	if (err)
-		goto err_setup_rx;
-
-	if (new_vsi) {
-		char int_name[IFNAMSIZ + 9];
-		err = i40e_vsi_configure(vsi);
-		if (err)
-			goto err_setup_rx;
-		snprintf(int_name, sizeof(int_name) - 1, "%s-fdir",
-			 dev_driver_string(&pf->pdev->dev));
-		err = i40e_vsi_request_irq(vsi, int_name);
-		if (err)
-			goto err_setup_rx;
-		err = i40e_up_complete(vsi);
-		if (err)
-			goto err_up_complete;
-		clear_bit(__I40E_NEEDS_RESTART, &vsi->state);
-	}
-
-	return;
-
-err_up_complete:
-	i40e_down(vsi);
-	i40e_vsi_free_irq(vsi);
-err_setup_rx:
-	i40e_vsi_free_rx_resources(vsi);
-err_setup_tx:
-	i40e_vsi_free_tx_resources(vsi);
-err_vsi:
-	pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
-	i40e_vsi_clear(vsi);
 }
 
 /**
@@ -5637,7 +5608,6 @@
  **/
 static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf)
 {
-	const int vxlan_hdr_qwords = 4;
 	struct i40e_hw *hw = &pf->hw;
 	i40e_status ret;
 	u8 filter_index;
@@ -5655,7 +5625,6 @@
 			port = pf->vxlan_ports[i];
 			ret = port ?
 			      i40e_aq_add_udp_tunnel(hw, ntohs(port),
-						     vxlan_hdr_qwords,
 						     I40E_AQC_TUNNEL_TYPE_VXLAN,
 						     &filter_index, NULL)
 			      : i40e_aq_del_udp_tunnel(hw, i, NULL);
@@ -6644,6 +6613,96 @@
 }
 
 #endif
+#ifdef HAVE_FDB_OPS
+#ifdef USE_CONST_DEV_UC_CHAR
+static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+			    struct net_device *dev,
+			    const unsigned char *addr,
+			    u16 flags)
+#else
+static int i40e_ndo_fdb_add(struct ndmsg *ndm,
+			    struct net_device *dev,
+			    unsigned char *addr,
+			    u16 flags)
+#endif
+{
+	struct i40e_netdev_priv *np = netdev_priv(dev);
+	struct i40e_pf *pf = np->vsi->back;
+	int err = 0;
+
+	if (!(pf->flags & I40E_FLAG_SRIOV_ENABLED))
+		return -EOPNOTSUPP;
+
+	/* Hardware does not support aging addresses so if a
+	 * ndm_state is given only allow permanent addresses
+	 */
+	if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
+		netdev_info(dev, "FDB only supports static addresses\n");
+		return -EINVAL;
+	}
+
+	if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
+		err = dev_uc_add_excl(dev, addr);
+	else if (is_multicast_ether_addr(addr))
+		err = dev_mc_add_excl(dev, addr);
+	else
+		err = -EINVAL;
+
+	/* Only return duplicate errors if NLM_F_EXCL is set */
+	if (err == -EEXIST && !(flags & NLM_F_EXCL))
+		err = 0;
+
+	return err;
+}
+
+#ifndef USE_DEFAULT_FDB_DEL_DUMP
+#ifdef USE_CONST_DEV_UC_CHAR
+static int i40e_ndo_fdb_del(struct ndmsg *ndm,
+			    struct net_device *dev,
+			    const unsigned char *addr)
+#else
+static int i40e_ndo_fdb_del(struct ndmsg *ndm,
+			    struct net_device *dev,
+			    unsigned char *addr)
+#endif
+{
+	struct i40e_netdev_priv *np = netdev_priv(dev);
+	struct i40e_pf *pf = np->vsi->back;
+	int err = -EOPNOTSUPP;
+
+	if (ndm->ndm_state & NUD_PERMANENT) {
+		netdev_info(dev, "FDB only supports static addresses\n");
+		return -EINVAL;
+	}
+
+	if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
+		if (is_unicast_ether_addr(addr))
+			err = dev_uc_del(dev, addr);
+		else if (is_multicast_ether_addr(addr))
+			err = dev_mc_del(dev, addr);
+		else
+			err = -EINVAL;
+	}
+
+	return err;
+}
+
+static int i40e_ndo_fdb_dump(struct sk_buff *skb,
+			     struct netlink_callback *cb,
+			     struct net_device *dev,
+			     int idx)
+{
+	struct i40e_netdev_priv *np = netdev_priv(dev);
+	struct i40e_pf *pf = np->vsi->back;
+
+	if (pf->flags & I40E_FLAG_SRIOV_ENABLED)
+		idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
+
+	return idx;
+}
+
+#endif /* USE_DEFAULT_FDB_DEL_DUMP */
+#endif /* HAVE_FDB_OPS */
 static const struct net_device_ops i40e_netdev_ops = {
 	.ndo_open		= i40e_open,
 	.ndo_stop		= i40e_close,
@@ -6671,6 +6730,13 @@
 	.ndo_add_vxlan_port	= i40e_add_vxlan_port,
 	.ndo_del_vxlan_port	= i40e_del_vxlan_port,
 #endif
+#ifdef HAVE_FDB_OPS
+	.ndo_fdb_add		= i40e_ndo_fdb_add,
+#ifndef USE_DEFAULT_FDB_DEL_DUMP
+	.ndo_fdb_del		= i40e_ndo_fdb_del,
+	.ndo_fdb_dump		= i40e_ndo_fdb_dump,
+#endif
+#endif
 };
 
 /**
@@ -6712,12 +6778,15 @@
 			   NETIF_F_HW_VLAN_CTAG_FILTER |
 			   NETIF_F_IPV6_CSUM	       |
 			   NETIF_F_TSO		       |
+			   NETIF_F_TSO_ECN	       |
 			   NETIF_F_TSO6		       |
 			   NETIF_F_RXCSUM	       |
-			   NETIF_F_NTUPLE	       |
 			   NETIF_F_RXHASH	       |
 			   0;
 
+	if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
+		netdev->features |= NETIF_F_NTUPLE;
+
 	/* copy netdev features into list of user selectable features */
 	netdev->hw_features |= netdev->features;
 
@@ -6976,11 +7045,7 @@
 				unregister_netdev(vsi->netdev);
 			}
 		} else {
-			if (!test_and_set_bit(__I40E_DOWN, &vsi->state))
-				i40e_down(vsi);
-			i40e_vsi_free_irq(vsi);
-			i40e_vsi_free_tx_resources(vsi);
-			i40e_vsi_free_rx_resources(vsi);
+			i40e_vsi_close(vsi);
 		}
 		i40e_vsi_disable_irq(vsi);
 	}
@@ -8084,6 +8149,7 @@
 	u16 link_status;
 	int err = 0;
 	u32 len;
+	u32 i;
 
 	err = pci_enable_device_mem(pdev);
 	if (err)
@@ -8237,7 +8303,7 @@
 	if (err) {
 		dev_info(&pdev->dev, "init_pf_dcb failed: %d\n", err);
 		pf->flags &= ~I40E_FLAG_DCB_ENABLED;
-		goto err_init_dcb;
+		/* Continue without DCB enabled */
 	}
 #endif /* CONFIG_I40E_DCB */
 
@@ -8273,6 +8339,13 @@
 		dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err);
 		goto err_vsis;
 	}
+	/* if FDIR VSI was set up, start it now */
+	for (i = 0; i < pf->hw.func_caps.num_vsis; i++) {
+		if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) {
+			i40e_vsi_open(pf->vsi[i]);
+			break;
+		}
+	}
 
 	/* The main driver is (mostly) up and happy. We need to set this state
 	 * before setting up the misc vector or we get a race and the vector
@@ -8326,6 +8399,7 @@
 	dv.minor_version = DRV_VERSION_MINOR;
 	dv.build_version = DRV_VERSION_BUILD;
 	dv.subbuild_version = 0;
+	strncpy(dv.driver_string, DRV_VERSION, sizeof(dv.driver_string));
 	i40e_aq_send_driver_version(&pf->hw, &dv, NULL);
 
 	/* since everything's happy, start the service_task timer */
@@ -8367,9 +8441,6 @@
 err_switch_setup:
 	i40e_reset_interrupt_capability(pf);
 	del_timer_sync(&pf->service_timer);
-#ifdef CONFIG_I40E_DCB
-err_init_dcb:
-#endif /* CONFIG_I40E_DCB */
 err_mac_addr:
 err_configure_lan_hmc:
 	(void)i40e_shutdown_lan_hmc(hw);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 262bdf1..8129918 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -160,7 +160,7 @@
 		udelay(5);
 	}
 	if (ret_code == I40E_ERR_TIMEOUT)
-		hw_dbg(hw, "Done bit in GLNVM_SRCTL not set");
+		hw_dbg(hw, "Done bit in GLNVM_SRCTL not set\n");
 	return ret_code;
 }
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index 9cd57e6..d351832 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -157,8 +157,8 @@
 i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
 				struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
-				u16 udp_port, u8 header_len,
-				u8 protocol_index, u8 *filter_index,
+				u16 udp_port, u8 protocol_index,
+				u8 *filter_index,
 				struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
 				struct i40e_asq_cmd_details *cmd_details);
@@ -167,6 +167,9 @@
 i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
 				    u16 flags, u8 *mac_addr,
 				    struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
+				u16 seid, u16 credit, u8 max_credit,
+				struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
 				struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_set_hmc_resource_profile(struct i40e_hw *hw,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
index e33ec6c..1fedc7a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
@@ -217,40 +217,6 @@
 }
 
 /**
- * i40e_ptp_tx_work
- * @work: pointer to work struct
- *
- * This work function polls the PRTTSYN_STAT_0.TXTIME bit to determine when a
- * Tx timestamp event has occurred, in order to pass the Tx timestamp value up
- * the stack in the skb.
- */
-static void i40e_ptp_tx_work(struct work_struct *work)
-{
-	struct i40e_pf *pf = container_of(work, struct i40e_pf,
-					  ptp_tx_work);
-	struct i40e_hw *hw = &pf->hw;
-	u32 prttsyn_stat_0;
-
-	if (!pf->ptp_tx_skb)
-		return;
-
-	if (time_is_before_jiffies(pf->ptp_tx_start +
-				   I40E_PTP_TX_TIMEOUT)) {
-		dev_kfree_skb_any(pf->ptp_tx_skb);
-		pf->ptp_tx_skb = NULL;
-		pf->tx_hwtstamp_timeouts++;
-		dev_warn(&pf->pdev->dev, "clearing Tx timestamp hang");
-		return;
-	}
-
-	prttsyn_stat_0 = rd32(hw, I40E_PRTTSYN_STAT_0);
-	if (prttsyn_stat_0 & I40E_PRTTSYN_STAT_0_TXTIME_MASK)
-		i40e_ptp_tx_hwtstamp(pf);
-	else
-		schedule_work(&pf->ptp_tx_work);
-}
-
-/**
  * i40e_ptp_enable - Enable/disable ancillary features of the PHC subsystem
  * @ptp: The PTP clock structure
  * @rq: The requested feature to change
@@ -321,7 +287,7 @@
 		pf->last_rx_ptp_check = jiffies;
 		pf->rx_hwtstamp_cleared++;
 		dev_warn(&vsi->back->pdev->dev,
-			 "%s: clearing Rx timestamp hang",
+			 "%s: clearing Rx timestamp hang\n",
 			 __func__);
 	}
 }
@@ -608,7 +574,6 @@
 		u32 regval;
 
 		spin_lock_init(&pf->tmreg_lock);
-		INIT_WORK(&pf->ptp_tx_work, i40e_ptp_tx_work);
 
 		dev_info(&pf->pdev->dev, "%s: added PHC on %s\n", __func__,
 			 netdev->name);
@@ -647,7 +612,6 @@
 	pf->ptp_tx = false;
 	pf->ptp_rx = false;
 
-	cancel_work_sync(&pf->ptp_tx_work);
 	if (pf->ptp_tx_skb) {
 		dev_kfree_skb_any(pf->ptp_tx_skb);
 		pf->ptp_tx_skb = NULL;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 0f5d96a..ece7ae9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -418,7 +418,7 @@
 		}
 		break;
 	default:
-		dev_info(&pf->pdev->dev, "Could not specify spec type %d",
+		dev_info(&pf->pdev->dev, "Could not specify spec type %d\n",
 			 input->flow_type);
 		ret = -EINVAL;
 	}
@@ -478,7 +478,7 @@
 				pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT;
 			}
 		} else {
-			dev_info(&pdev->dev, "FD filter programming error");
+			dev_info(&pdev->dev, "FD filter programming error\n");
 		}
 	} else if (error ==
 			  (0x1 << I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
@@ -1713,9 +1713,11 @@
 				I40E_TX_FLAGS_VLAN_PRIO_SHIFT;
 		if (tx_flags & I40E_TX_FLAGS_SW_VLAN) {
 			struct vlan_ethhdr *vhdr;
-			if (skb_header_cloned(skb) &&
-			    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-				return -ENOMEM;
+			int rc;
+
+			rc = skb_cow_head(skb, 0);
+			if (rc < 0)
+				return rc;
 			vhdr = (struct vlan_ethhdr *)skb->data;
 			vhdr->h_vlan_TCI = htons(tx_flags >>
 						 I40E_TX_FLAGS_VLAN_SHIFT);
@@ -1743,20 +1745,18 @@
 		    u64 *cd_type_cmd_tso_mss, u32 *cd_tunneling)
 {
 	u32 cd_cmd, cd_tso_len, cd_mss;
+	struct ipv6hdr *ipv6h;
 	struct tcphdr *tcph;
 	struct iphdr *iph;
 	u32 l4len;
 	int err;
-	struct ipv6hdr *ipv6h;
 
 	if (!skb_is_gso(skb))
 		return 0;
 
-	if (skb_header_cloned(skb)) {
-		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-		if (err)
-			return err;
-	}
+	err = skb_cow_head(skb, 0);
+	if (err < 0)
+		return err;
 
 	if (protocol == htons(ETH_P_IP)) {
 		iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
@@ -1825,9 +1825,6 @@
 	*cd_type_cmd_tso_mss |= (u64)I40E_TX_CTX_DESC_TSYN <<
 				I40E_TXD_CTX_QW1_CMD_SHIFT;
 
-	pf->ptp_tx_start = jiffies;
-	schedule_work(&pf->ptp_tx_work);
-
 	return 1;
 }
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 71a968f..c4df8ba 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -167,6 +167,9 @@
 	u8 loopback;
 	/* is Link Status Event notification to SW enabled */
 	bool lse_enable;
+	u16 max_frame_size;
+	bool crc_enable;
+	u8 pacing;
 };
 
 struct i40e_phy_info {
@@ -409,6 +412,7 @@
 	u8 minor_version;
 	u8 build_version;
 	u8 subbuild_version;
+	u8 driver_string[32];
 };
 
 /* RX Descriptors */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 02c11a7..82e7abf 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -29,6 +29,24 @@
 /***********************misc routines*****************************/
 
 /**
+ * i40e_vc_disable_vf
+ * @pf: pointer to the pf info
+ * @vf: pointer to the vf info
+ *
+ * Disable the VF through a SW reset
+ **/
+static inline void i40e_vc_disable_vf(struct i40e_pf *pf, struct i40e_vf *vf)
+{
+	struct i40e_hw *hw = &pf->hw;
+	u32 reg;
+
+	reg = rd32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id));
+	reg |= I40E_VPGEN_VFRTRIG_VFSWR_MASK;
+	wr32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id), reg);
+	i40e_flush(hw);
+}
+
+/**
  * i40e_vc_isvalid_vsi_id
  * @vf: pointer to the vf info
  * @vsi_id: vf relative vsi id
@@ -416,6 +434,15 @@
 	if (ret)
 		dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
 
+	/* Set VF bandwidth if specified */
+	if (vf->tx_rate) {
+		ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid,
+						  vf->tx_rate / 50, 0, NULL);
+		if (ret)
+			dev_err(&pf->pdev->dev, "Unable to set tx rate, VF %d, error code %d.\n",
+				vf->vf_id, ret);
+	}
+
 error_alloc_vsi_res:
 	return ret;
 }
@@ -2022,10 +2049,11 @@
 	}
 
 	/* delete the temporary mac address */
-	i40e_del_filter(vsi, vf->default_lan_addr.addr, 0, true, false);
+	i40e_del_filter(vsi, vf->default_lan_addr.addr, vf->port_vlan_id,
+			true, false);
 
 	/* add the new mac address */
-	f = i40e_add_filter(vsi, mac, 0, true, false);
+	f = i40e_add_filter(vsi, mac, vf->port_vlan_id, true, false);
 	if (!f) {
 		dev_err(&pf->pdev->dev,
 			"Unable to add VF ucast filter\n");
@@ -2088,18 +2116,28 @@
 		goto error_pvid;
 	}
 
-	if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi))
+	if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi)) {
 		dev_err(&pf->pdev->dev,
 			"VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n",
 			vf_id);
+		/* Administrator Error - knock the VF offline until he does
+		 * the right thing by reconfiguring his network correctly
+		 * and then reloading the VF driver.
+		 */
+		i40e_vc_disable_vf(pf, vf);
+	}
 
 	/* Check for condition where there was already a port VLAN ID
 	 * filter set and now it is being deleted by setting it to zero.
+	 * Additionally check for the condition where there was a port
+	 * VLAN but now there is a new and different port VLAN being set.
 	 * Before deleting all the old VLAN filters we must add new ones
 	 * with -1 (I40E_VLAN_ANY) or otherwise we're left with all our
 	 * MAC addresses deleted.
 	 */
-	if (!(vlan_id || qos) && vsi->info.pvid)
+	if ((!(vlan_id || qos) ||
+	    (vlan_id | qos) != le16_to_cpu(vsi->info.pvid)) &&
+	    vsi->info.pvid)
 		ret = i40e_vsi_add_vlan(vsi, I40E_VLAN_ANY);
 
 	if (vsi->info.pvid) {
@@ -2160,7 +2198,61 @@
  **/
 int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate)
 {
-	return -EOPNOTSUPP;
+	struct i40e_netdev_priv *np = netdev_priv(netdev);
+	struct i40e_pf *pf = np->vsi->back;
+	struct i40e_vsi *vsi;
+	struct i40e_vf *vf;
+	int speed = 0;
+	int ret = 0;
+
+	/* validate the request */
+	if (vf_id >= pf->num_alloc_vfs) {
+		dev_err(&pf->pdev->dev, "Invalid VF Identifier %d.\n", vf_id);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	vf = &(pf->vf[vf_id]);
+	vsi = pf->vsi[vf->lan_vsi_index];
+	if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
+		dev_err(&pf->pdev->dev, "Uninitialized VF %d.\n", vf_id);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	switch (pf->hw.phy.link_info.link_speed) {
+	case I40E_LINK_SPEED_40GB:
+		speed = 40000;
+		break;
+	case I40E_LINK_SPEED_10GB:
+		speed = 10000;
+		break;
+	case I40E_LINK_SPEED_1GB:
+		speed = 1000;
+		break;
+	default:
+		break;
+	}
+
+	if (tx_rate > speed) {
+		dev_err(&pf->pdev->dev, "Invalid tx rate %d specified for vf %d.",
+			tx_rate, vf->vf_id);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	/* Tx rate credits are in values of 50Mbps, 0 is disabled*/
+	ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, tx_rate / 50, 0,
+					  NULL);
+	if (ret) {
+		dev_err(&pf->pdev->dev, "Unable to set tx rate, error code %d.\n",
+			ret);
+		ret = -EIO;
+		goto error;
+	}
+	vf->tx_rate = tx_rate;
+error:
+	return ret;
 }
 
 /**
@@ -2200,10 +2292,17 @@
 
 	memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN);
 
-	ivi->tx_rate = 0;
+	ivi->tx_rate = vf->tx_rate;
 	ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK;
 	ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >>
 		   I40E_VLAN_PRIORITY_SHIFT;
+	if (vf->link_forced == false)
+		ivi->linkstate = IFLA_VF_LINK_STATE_AUTO;
+	else if (vf->link_up == true)
+		ivi->linkstate = IFLA_VF_LINK_STATE_ENABLE;
+	else
+		ivi->linkstate = IFLA_VF_LINK_STATE_DISABLE;
+
 	ret = 0;
 
 error_param:
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
index 389c47f..ba3d1f8 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -98,6 +98,7 @@
 
 	unsigned long vf_caps;	/* vf's adv. capabilities */
 	unsigned long vf_states;	/* vf's runtime states */
+	unsigned int tx_rate;	/* Tx bandwidth limit in Mbps */
 	bool link_forced;
 	bool link_up;		/* only valid if vf link is forced */
 };
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
index 5470ce9..c79df25 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
@@ -28,6 +28,16 @@
 #include "i40e_prototype.h"
 
 /**
+ * i40e_is_nvm_update_op - return true if this is an NVM update operation
+ * @desc: API request descriptor
+ **/
+static inline bool i40e_is_nvm_update_op(struct i40e_aq_desc *desc)
+{
+	return (desc->opcode == i40e_aqc_opc_nvm_erase) ||
+	       (desc->opcode == i40e_aqc_opc_nvm_update);
+}
+
+/**
  *  i40e_adminq_init_regs - Initialize AdminQ registers
  *  @hw: pointer to the hardware structure
  *
@@ -659,6 +669,12 @@
 		goto asq_send_command_exit;
 	}
 
+	if (i40e_is_nvm_update_op(desc) && hw->aq.nvm_busy) {
+		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: NVM busy.\n");
+		status = I40E_ERR_NVM;
+		goto asq_send_command_exit;
+	}
+
 	details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
 	if (cmd_details) {
 		*details = *cmd_details;
@@ -786,6 +802,9 @@
 		hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
 	}
 
+	if (i40e_is_nvm_update_op(desc))
+		hw->aq.nvm_busy = true;
+
 	/* update the error if time out occurred */
 	if ((!cmd_completed) &&
 	    (!details->async && !details->postpone)) {
@@ -880,6 +899,9 @@
 			       e->msg_size);
 	}
 
+	if (i40e_is_nvm_update_op(&e->desc))
+		hw->aq.nvm_busy = false;
+
 	/* Restore the original datalen and buffer address in the desc,
 	 * FW updates datalen to indicate the event message
 	 * size
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
index 8f72c31d..7d24be5 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
@@ -87,6 +87,7 @@
 	u16 fw_min_ver;                 /* firmware minor version */
 	u16 api_maj_ver;                /* api major version */
 	u16 api_min_ver;                /* api minor version */
+	bool nvm_busy;
 
 	struct mutex asq_mutex; /* Send queue lock */
 	struct mutex arq_mutex; /* Receive queue lock */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
index 97662b6..6e61766 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
@@ -180,9 +180,6 @@
 	i40e_aqc_opc_add_mirror_rule    = 0x0260,
 	i40e_aqc_opc_delete_mirror_rule = 0x0261,
 
-	i40e_aqc_opc_set_storm_control_config = 0x0280,
-	i40e_aqc_opc_get_storm_control_config = 0x0281,
-
 	/* DCB commands */
 	i40e_aqc_opc_dcb_ignore_pfc = 0x0301,
 	i40e_aqc_opc_dcb_updated    = 0x0302,
@@ -205,6 +202,7 @@
 	i40e_aqc_opc_query_switching_comp_bw_config        = 0x041A,
 	i40e_aqc_opc_suspend_port_tx                       = 0x041B,
 	i40e_aqc_opc_resume_port_tx                        = 0x041C,
+	i40e_aqc_opc_configure_partition_bw                = 0x041D,
 
 	/* hmc */
 	i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
@@ -1289,27 +1287,6 @@
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
 
-/* Set Storm Control Configuration (direct 0x0280)
- * Get Storm Control Configuration (direct 0x0281)
- *    the command and response use the same descriptor structure
- */
-struct i40e_aqc_set_get_storm_control_config {
-	__le32 broadcast_threshold;
-	__le32 multicast_threshold;
-	__le32 control_flags;
-#define I40E_AQC_STORM_CONTROL_MDIPW            0x01
-#define I40E_AQC_STORM_CONTROL_MDICW            0x02
-#define I40E_AQC_STORM_CONTROL_BDIPW            0x04
-#define I40E_AQC_STORM_CONTROL_BDICW            0x08
-#define I40E_AQC_STORM_CONTROL_BIDU             0x10
-#define I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT   8
-#define I40E_AQC_STORM_CONTROL_INTERVAL_MASK    (0x3FF << \
-					I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT)
-	u8     reserved[4];
-};
-
-I40E_CHECK_CMD_LENGTH(i40e_aqc_set_get_storm_control_config);
-
 /* DCB 0x03xx*/
 
 /* PFC Ignore (direct 0x0301)
@@ -1499,6 +1476,15 @@
  * (direct 0x041B and 0x041C) uses the generic SEID struct
  */
 
+/* Configure partition BW
+ * (indirect 0x041D)
+ */
+struct i40e_aqc_configure_partition_bw_data {
+	__le16 pf_valid_bits;
+	u8     min_bw[16];      /* guaranteed bandwidth */
+	u8     max_bw[16];      /* bandwidth limit */
+};
+
 /* Get and set the active HMC resource profile and status.
  * (direct 0x0500) and (direct 0x0501)
  */
@@ -1583,11 +1569,8 @@
 #define I40E_AQ_PHY_FLAG_PAUSE_TX         0x01
 #define I40E_AQ_PHY_FLAG_PAUSE_RX         0x02
 #define I40E_AQ_PHY_FLAG_LOW_POWER        0x04
-#define I40E_AQ_PHY_FLAG_AN_SHIFT         3
-#define I40E_AQ_PHY_FLAG_AN_MASK          (0x3 << I40E_AQ_PHY_FLAG_AN_SHIFT)
-#define I40E_AQ_PHY_FLAG_AN_OFF           0x00 /* link forced on */
-#define I40E_AQ_PHY_FLAG_AN_OFF_LINK_DOWN 0x01
-#define I40E_AQ_PHY_FLAG_AN_ON            0x02
+#define I40E_AQ_PHY_LINK_ENABLED		  0x08
+#define I40E_AQ_PHY_AN_ENABLED			  0x10
 #define I40E_AQ_PHY_FLAG_MODULE_QUAL      0x20
 	__le16 eee_capability;
 #define I40E_AQ_EEE_100BASE_TX       0x0002
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h b/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
index 17e42ca..775fcb2 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
@@ -53,6 +53,7 @@
 	u8  tphdata_ena;
 	u8  tphhead_ena;
 	u8  lrxqthresh;
+	u8  prefena;	/* NOTE: normally must be set to 1 at init */
 };
 
 /* Tx queue context data */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index 4673b338..51a6dee 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -173,6 +173,9 @@
 	u8 loopback;
 	/* is Link Status Event notification to SW enabled */
 	bool lse_enable;
+	u16 max_frame_size;
+	bool crc_enable;
+	u8 pacing;
 };
 
 struct i40e_phy_info {
@@ -415,6 +418,7 @@
 	u8 minor_version;
 	u8 build_version;
 	u8 subbuild_version;
+	u8 driver_string[32];
 };
 
 /* RX Descriptors */
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index 8b0db1c..a46be01 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -365,6 +365,316 @@
 	return 0;
 }
 
+/**
+ * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
+ * @adapter: board private structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the flow is supported, else Invalid Input.
+ **/
+static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,
+				    struct ethtool_rxnfc *cmd)
+{
+	struct i40e_hw *hw = &adapter->hw;
+	u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
+		   ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
+
+	/* We always hash on IP src and dest addresses */
+	cmd->data = RXH_IP_SRC | RXH_IP_DST;
+
+	switch (cmd->flow_type) {
+	case TCP_V4_FLOW:
+		if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
+			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		break;
+	case UDP_V4_FLOW:
+		if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
+			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		break;
+
+	case SCTP_V4_FLOW:
+	case AH_ESP_V4_FLOW:
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+	case IPV4_FLOW:
+		break;
+
+	case TCP_V6_FLOW:
+		if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
+			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		break;
+	case UDP_V6_FLOW:
+		if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
+			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		break;
+
+	case SCTP_V6_FLOW:
+	case AH_ESP_V6_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+	case IPV6_FLOW:
+		break;
+	default:
+		cmd->data = 0;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * i40evf_get_rxnfc - command to get RX flow classification rules
+ * @netdev: network interface device structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the command is supported.
+ **/
+static int i40evf_get_rxnfc(struct net_device *netdev,
+			    struct ethtool_rxnfc *cmd,
+			    u32 *rule_locs)
+{
+	struct i40evf_adapter *adapter = netdev_priv(netdev);
+	int ret = -EOPNOTSUPP;
+
+	switch (cmd->cmd) {
+	case ETHTOOL_GRXRINGS:
+		cmd->data = adapter->vsi_res->num_queue_pairs;
+		ret = 0;
+		break;
+	case ETHTOOL_GRXFH:
+		ret = i40evf_get_rss_hash_opts(adapter, cmd);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * i40evf_set_rss_hash_opt - Enable/Disable flow types for RSS hash
+ * @adapter: board private structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the flow input set is supported.
+ **/
+static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
+				   struct ethtool_rxnfc *nfc)
+{
+	struct i40e_hw *hw = &adapter->hw;
+
+	u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
+		   ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
+
+	/* RSS does not support anything other than hashing
+	 * to queues on src and dst IPs and ports
+	 */
+	if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
+			  RXH_L4_B_0_1 | RXH_L4_B_2_3))
+		return -EINVAL;
+
+	/* We need at least the IP SRC and DEST fields for hashing */
+	if (!(nfc->data & RXH_IP_SRC) ||
+	    !(nfc->data & RXH_IP_DST))
+		return -EINVAL;
+
+	switch (nfc->flow_type) {
+	case TCP_V4_FLOW:
+		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+		case 0:
+			hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+			break;
+		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case TCP_V6_FLOW:
+		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+		case 0:
+			hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+			break;
+		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case UDP_V4_FLOW:
+		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+		case 0:
+			hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
+				  ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
+			break;
+		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
+				 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case UDP_V6_FLOW:
+		switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+		case 0:
+			hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
+				  ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
+			break;
+		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+			hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
+				 ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case AH_ESP_V4_FLOW:
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+	case SCTP_V4_FLOW:
+		if ((nfc->data & RXH_L4_B_0_1) ||
+		    (nfc->data & RXH_L4_B_2_3))
+			return -EINVAL;
+		hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
+		break;
+	case AH_ESP_V6_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+	case SCTP_V6_FLOW:
+		if ((nfc->data & RXH_L4_B_0_1) ||
+		    (nfc->data & RXH_L4_B_2_3))
+			return -EINVAL;
+		hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
+		break;
+	case IPV4_FLOW:
+		hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
+			((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4);
+		break;
+	case IPV6_FLOW:
+		hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
+			((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	wr32(hw, I40E_VFQF_HENA(0), (u32)hena);
+	wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));
+	i40e_flush(hw);
+
+	return 0;
+}
+
+/**
+ * i40evf_set_rxnfc - command to set RX flow classification rules
+ * @netdev: network interface device structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the command is supported.
+ **/
+static int i40evf_set_rxnfc(struct net_device *netdev,
+			    struct ethtool_rxnfc *cmd)
+{
+	struct i40evf_adapter *adapter = netdev_priv(netdev);
+	int ret = -EOPNOTSUPP;
+
+	switch (cmd->cmd) {
+	case ETHTOOL_SRXFH:
+		ret = i40evf_set_rss_hash_opt(adapter, cmd);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * i40evf_get_channels: get the number of channels supported by the device
+ * @netdev: network interface device structure
+ * @ch: channel information structure
+ *
+ * For the purposes of our device, we only use combined channels, i.e. a tx/rx
+ * queue pair. Report one extra channel to match our "other" MSI-X vector.
+ **/
+static void i40evf_get_channels(struct net_device *netdev,
+				struct ethtool_channels *ch)
+{
+	struct i40evf_adapter *adapter = netdev_priv(netdev);
+
+	/* Report maximum channels */
+	ch->max_combined = adapter->vsi_res->num_queue_pairs;
+
+	ch->max_other = NONQ_VECS;
+	ch->other_count = NONQ_VECS;
+
+	ch->combined_count = adapter->vsi_res->num_queue_pairs;
+}
+
+/**
+ * i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size
+ * @netdev: network interface device structure
+ *
+ * Returns the table size.
+ **/
+static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
+{
+	return (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;
+}
+
+/**
+ * i40evf_get_rxfh_indir - get the rx flow hash indirection table
+ * @netdev: network interface device structure
+ * @indir: indirection table
+ *
+ * Reads the indirection table directly from the hardware. Always returns 0.
+ **/
+static int i40evf_get_rxfh_indir(struct net_device *netdev, u32 *indir)
+{
+	struct i40evf_adapter *adapter = netdev_priv(netdev);
+	struct i40e_hw *hw = &adapter->hw;
+	u32 hlut_val;
+	int i, j;
+
+	for (i = 0, j = 0; i < I40E_VFQF_HLUT_MAX_INDEX; i++) {
+		hlut_val = rd32(hw, I40E_VFQF_HLUT(i));
+		indir[j++] = hlut_val & 0xff;
+		indir[j++] = (hlut_val >> 8) & 0xff;
+		indir[j++] = (hlut_val >> 16) & 0xff;
+		indir[j++] = (hlut_val >> 24) & 0xff;
+	}
+	return 0;
+}
+
+/**
+ * i40evf_set_rxfh_indir - set the rx flow hash indirection table
+ * @netdev: network interface device structure
+ * @indir: indirection table
+ *
+ * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
+ * returns 0 after programming the table.
+ **/
+static int i40evf_set_rxfh_indir(struct net_device *netdev, const u32 *indir)
+{
+	struct i40evf_adapter *adapter = netdev_priv(netdev);
+	struct i40e_hw *hw = &adapter->hw;
+	u32 hlut_val;
+	int i, j;
+
+	for (i = 0, j = 0; i < I40E_VFQF_HLUT_MAX_INDEX + 1; i++) {
+		hlut_val = indir[j++];
+		hlut_val |= indir[j++] << 8;
+		hlut_val |= indir[j++] << 16;
+		hlut_val |= indir[j++] << 24;
+		wr32(hw, I40E_VFQF_HLUT(i), hlut_val);
+	}
+
+	return 0;
+}
+
 static struct ethtool_ops i40evf_ethtool_ops = {
 	.get_settings		= i40evf_get_settings,
 	.get_drvinfo		= i40evf_get_drvinfo,
@@ -378,6 +688,12 @@
 	.set_msglevel		= i40evf_set_msglevel,
 	.get_coalesce		= i40evf_get_coalesce,
 	.set_coalesce		= i40evf_set_coalesce,
+	.get_rxnfc		= i40evf_get_rxnfc,
+	.set_rxnfc		= i40evf_set_rxnfc,
+	.get_rxfh_indir_size	= i40evf_get_rxfh_indir_size,
+	.get_rxfh_indir		= i40evf_get_rxfh_indir,
+	.set_rxfh_indir		= i40evf_set_rxfh_indir,
+	.get_channels		= i40evf_get_channels,
 };
 
 /**
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 2797548..6edd581 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -25,13 +25,15 @@
 #include "i40e_prototype.h"
 static int i40evf_setup_all_tx_resources(struct i40evf_adapter *adapter);
 static int i40evf_setup_all_rx_resources(struct i40evf_adapter *adapter);
+static void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter);
+static void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter);
 static int i40evf_close(struct net_device *netdev);
 
 char i40evf_driver_name[] = "i40evf";
 static const char i40evf_driver_string[] =
 	"Intel(R) XL710 X710 Virtual Function Network Driver";
 
-#define DRV_VERSION "0.9.16"
+#define DRV_VERSION "0.9.23"
 const char i40evf_driver_version[] = DRV_VERSION;
 static const char i40evf_copyright[] =
 	"Copyright (c) 2013 - 2014 Intel Corporation.";
@@ -1309,7 +1311,6 @@
 		goto restart_watchdog;
 
 	if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) {
-		dev_info(&adapter->pdev->dev, "Checking for redemption\n");
 		if ((rd32(hw, I40E_VFGEN_RSTAT) & 0x3) == I40E_VFR_VFACTIVE) {
 			/* A chance for redemption! */
 			dev_err(&adapter->pdev->dev, "Hardware came out of reset. Attempting reinit.\n");
@@ -1534,9 +1535,13 @@
 			rstat_val);
 		adapter->flags |= I40EVF_FLAG_PF_COMMS_FAILED;
 
-		if (netif_running(adapter->netdev))
-			i40evf_close(adapter->netdev);
-
+		if (netif_running(adapter->netdev)) {
+			set_bit(__I40E_DOWN, &adapter->vsi.state);
+			i40evf_down(adapter);
+			i40evf_free_traffic_irqs(adapter);
+			i40evf_free_all_tx_resources(adapter);
+			i40evf_free_all_rx_resources(adapter);
+		}
 		i40evf_free_misc_irq(adapter);
 		i40evf_reset_interrupt_capability(adapter);
 		i40evf_free_queues(adapter);
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index fa36fe12..2e36c67 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 /* e1000_82575
  * e1000_82576
@@ -73,9 +70,8 @@
 static s32  igb_update_nvm_checksum_82580(struct e1000_hw *hw);
 static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw);
 static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw);
-static const u16 e1000_82580_rxpbs_table[] =
-	{ 36, 72, 144, 1, 2, 4, 8, 16,
-	  35, 70, 140 };
+static const u16 e1000_82580_rxpbs_table[] = {
+	36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
 
 /**
  *  igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
@@ -526,7 +522,7 @@
 static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-	struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575;
+	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
 	s32 ret_val;
 	u32 ctrl_ext = 0;
 	u32 link_mode = 0;
@@ -1180,8 +1176,8 @@
 {
 	u32 swfw_sync;
 
-	while (igb_get_hw_semaphore(hw) != 0);
-	/* Empty */
+	while (igb_get_hw_semaphore(hw) != 0)
+		; /* Empty */
 
 	swfw_sync = rd32(E1000_SW_FW_SYNC);
 	swfw_sync &= ~mask;
@@ -1216,7 +1212,7 @@
 	while (timeout) {
 		if (rd32(E1000_EEMNGCTL) & mask)
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 		timeout--;
 	}
 	if (!timeout)
@@ -1269,7 +1265,7 @@
 
 	if (hw->phy.media_type != e1000_media_type_copper) {
 		ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
-		                                             &duplex);
+							     &duplex);
 		/* Use this flag to determine if link needs to be checked or
 		 * not.  If  we have link clear the flag so that we do not
 		 * continue to check for link.
@@ -1316,7 +1312,7 @@
 
 	/* flush the write to verify completion */
 	wrfl();
-	msleep(1);
+	usleep_range(1000, 2000);
 }
 
 /**
@@ -1411,7 +1407,7 @@
 
 		/* flush the write to verify completion */
 		wrfl();
-		msleep(1);
+		usleep_range(1000, 2000);
 	}
 }
 
@@ -1436,9 +1432,8 @@
 
 	/* set the completion timeout for interface */
 	ret_val = igb_set_pcie_completion_timeout(hw);
-	if (ret_val) {
+	if (ret_val)
 		hw_dbg("PCI-E Set completion timeout has failed.\n");
-	}
 
 	hw_dbg("Masking off all interrupts\n");
 	wr32(E1000_IMC, 0xffffffff);
@@ -1447,7 +1442,7 @@
 	wr32(E1000_TCTL, E1000_TCTL_PSP);
 	wrfl();
 
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	ctrl = rd32(E1000_CTRL);
 
@@ -1676,7 +1671,7 @@
 		    hw->mac.type == e1000_82576) {
 			ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data);
 			if (ret_val) {
-				printk(KERN_DEBUG "NVM Read Error\n\n");
+				hw_dbg(KERN_DEBUG "NVM Read Error\n\n");
 				return ret_val;
 			}
 
@@ -1689,7 +1684,7 @@
 		 * link either autoneg or be forced to 1000/Full
 		 */
 		ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
-		            E1000_CTRL_FD | E1000_CTRL_FRCDPX;
+				E1000_CTRL_FD | E1000_CTRL_FRCDPX;
 
 		/* set speed of 1000/Full if speed/duplex is forced */
 		reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
@@ -1925,7 +1920,7 @@
 	}
 	/* Poll all queues to verify they have shut down */
 	for (ms_wait = 0; ms_wait < 10; ms_wait++) {
-		msleep(1);
+		usleep_range(1000, 2000);
 		rx_enabled = 0;
 		for (i = 0; i < 4; i++)
 			rx_enabled |= rd32(E1000_RXDCTL(i));
@@ -1953,7 +1948,7 @@
 	wr32(E1000_RCTL, temp_rctl);
 	wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN);
 	wrfl();
-	msleep(2);
+	usleep_range(2000, 3000);
 
 	/* Enable RX queues that were previously enabled and restore our
 	 * previous state
@@ -2005,14 +2000,14 @@
 	 * 16ms to 55ms
 	 */
 	ret_val = igb_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
-	                                &pcie_devctl2);
+					&pcie_devctl2);
 	if (ret_val)
 		goto out;
 
 	pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
 
 	ret_val = igb_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
-	                                 &pcie_devctl2);
+					 &pcie_devctl2);
 out:
 	/* disable completion timeout resend */
 	gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
@@ -2241,7 +2236,7 @@
 	wr32(E1000_TCTL, E1000_TCTL_PSP);
 	wrfl();
 
-	msleep(10);
+	usleep_range(10000, 11000);
 
 	/* Determine whether or not a global dev reset is requested */
 	if (global_device_reset &&
@@ -2259,7 +2254,7 @@
 
 	/* Add delay to insure DEV_RST has time to complete */
 	if (global_device_reset)
-		msleep(5);
+		usleep_range(5000, 6000);
 
 	ret_val = igb_get_auto_rd_done(hw);
 	if (ret_val) {
@@ -2436,8 +2431,7 @@
 
 	ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
 	if (ret_val) {
-		hw_dbg("NVM Read Error while updating checksum"
-			" compatibility bit.\n");
+		hw_dbg("NVM Read Error while updating checksum compatibility bit.\n");
 		goto out;
 	}
 
@@ -2447,8 +2441,7 @@
 		ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
 					&nvm_data);
 		if (ret_val) {
-			hw_dbg("NVM Write Error while updating checksum"
-				" compatibility bit.\n");
+			hw_dbg("NVM Write Error while updating checksum compatibility bit.\n");
 			goto out;
 		}
 	}
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h
index 09d78be..b407c55 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.h
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_82575_H_
 #define _E1000_82575_H_
@@ -37,9 +34,9 @@
 		       u8 data);
 
 #define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
-                                     (ID_LED_DEF1_DEF2 <<  8) | \
-                                     (ID_LED_DEF1_DEF2 <<  4) | \
-                                     (ID_LED_OFF1_ON2))
+				     (ID_LED_DEF1_DEF2 <<  8) | \
+				     (ID_LED_DEF1_DEF2 <<  4) | \
+				     (ID_LED_OFF1_ON2))
 
 #define E1000_RAR_ENTRIES_82575        16
 #define E1000_RAR_ENTRIES_82576        24
@@ -67,16 +64,16 @@
 #define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX    0x01000000
 
 #define E1000_EICR_TX_QUEUE ( \
-    E1000_EICR_TX_QUEUE0 |    \
-    E1000_EICR_TX_QUEUE1 |    \
-    E1000_EICR_TX_QUEUE2 |    \
-    E1000_EICR_TX_QUEUE3)
+	E1000_EICR_TX_QUEUE0 |    \
+	E1000_EICR_TX_QUEUE1 |    \
+	E1000_EICR_TX_QUEUE2 |    \
+	E1000_EICR_TX_QUEUE3)
 
 #define E1000_EICR_RX_QUEUE ( \
-    E1000_EICR_RX_QUEUE0 |    \
-    E1000_EICR_RX_QUEUE1 |    \
-    E1000_EICR_RX_QUEUE2 |    \
-    E1000_EICR_RX_QUEUE3)
+	E1000_EICR_RX_QUEUE0 |    \
+	E1000_EICR_RX_QUEUE1 |    \
+	E1000_EICR_RX_QUEUE2 |    \
+	E1000_EICR_RX_QUEUE3)
 
 /* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
 #define E1000_IMIREXT_SIZE_BP     0x00001000  /* Packet size bypass */
@@ -92,8 +89,7 @@
 		struct {
 			struct {
 				__le16 pkt_info;   /* RSS type, Packet type */
-				__le16 hdr_info;   /* Split Header,
-						    * header buffer length */
+				__le16 hdr_info;   /* Split Head, buf len */
 			} lo_dword;
 			union {
 				__le32 rss;          /* RSS Hash */
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index b05bf92..f85be66 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_DEFINES_H_
 #define _E1000_DEFINES_H_
@@ -101,11 +98,11 @@
 
 /* Same mask, but for extended and packet split descriptors */
 #define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
-    E1000_RXDEXT_STATERR_CE  |            \
-    E1000_RXDEXT_STATERR_SE  |            \
-    E1000_RXDEXT_STATERR_SEQ |            \
-    E1000_RXDEXT_STATERR_CXE |            \
-    E1000_RXDEXT_STATERR_RXE)
+	E1000_RXDEXT_STATERR_CE  |            \
+	E1000_RXDEXT_STATERR_SE  |            \
+	E1000_RXDEXT_STATERR_SEQ |            \
+	E1000_RXDEXT_STATERR_CXE |            \
+	E1000_RXDEXT_STATERR_RXE)
 
 #define E1000_MRQC_RSS_FIELD_IPV4_TCP          0x00010000
 #define E1000_MRQC_RSS_FIELD_IPV4              0x00020000
@@ -307,33 +304,25 @@
 #define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
 
 /* DMA Coalescing register fields */
-#define E1000_DMACR_DMACWT_MASK         0x00003FFF /* DMA Coalescing
-							* Watchdog Timer */
-#define E1000_DMACR_DMACTHR_MASK        0x00FF0000 /* DMA Coalescing Receive
-							* Threshold */
+#define E1000_DMACR_DMACWT_MASK         0x00003FFF /* DMA Coal Watchdog Timer */
+#define E1000_DMACR_DMACTHR_MASK        0x00FF0000 /* DMA Coal Rx Threshold */
 #define E1000_DMACR_DMACTHR_SHIFT       16
-#define E1000_DMACR_DMAC_LX_MASK        0x30000000 /* Lx when no PCIe
-							* transactions */
+#define E1000_DMACR_DMAC_LX_MASK        0x30000000 /* Lx when no PCIe trans */
 #define E1000_DMACR_DMAC_LX_SHIFT       28
 #define E1000_DMACR_DMAC_EN             0x80000000 /* Enable DMA Coalescing */
 /* DMA Coalescing BMC-to-OS Watchdog Enable */
 #define E1000_DMACR_DC_BMC2OSW_EN	0x00008000
 
-#define E1000_DMCTXTH_DMCTTHR_MASK      0x00000FFF /* DMA Coalescing Transmit
-							* Threshold */
+#define E1000_DMCTXTH_DMCTTHR_MASK      0x00000FFF /* DMA Coal Tx Threshold */
 
 #define E1000_DMCTLX_TTLX_MASK          0x00000FFF /* Time to LX request */
 
-#define E1000_DMCRTRH_UTRESH_MASK       0x0007FFFF /* Receive Traffic Rate
-							* Threshold */
-#define E1000_DMCRTRH_LRPRCW            0x80000000 /* Rcv packet rate in
-							* current window */
+#define E1000_DMCRTRH_UTRESH_MASK       0x0007FFFF /* Rx Traffic Rate Thresh */
+#define E1000_DMCRTRH_LRPRCW            0x80000000 /* Rx pkt rate curr window */
 
-#define E1000_DMCCNT_CCOUNT_MASK        0x01FFFFFF /* DMA Coal Rcv Traffic
-							* Current Cnt */
+#define E1000_DMCCNT_CCOUNT_MASK        0x01FFFFFF /* DMA Coal Rx Current Cnt */
 
-#define E1000_FCRTC_RTH_COAL_MASK       0x0003FFF0 /* Flow ctrl Rcv Threshold
-							* High val */
+#define E1000_FCRTC_RTH_COAL_MASK       0x0003FFF0 /* FC Rx Thresh High val */
 #define E1000_FCRTC_RTH_COAL_SHIFT      4
 #define E1000_PCIEMISC_LX_DECISION      0x00000080 /* Lx power decision */
 
@@ -406,12 +395,12 @@
  *   o LSC    = Link Status Change
  */
 #define IMS_ENABLE_MASK ( \
-    E1000_IMS_RXT0   |    \
-    E1000_IMS_TXDW   |    \
-    E1000_IMS_RXDMT0 |    \
-    E1000_IMS_RXSEQ  |    \
-    E1000_IMS_LSC    |    \
-    E1000_IMS_DOUTSYNC)
+	E1000_IMS_RXT0   |    \
+	E1000_IMS_TXDW   |    \
+	E1000_IMS_RXDMT0 |    \
+	E1000_IMS_RXSEQ  |    \
+	E1000_IMS_LSC    |    \
+	E1000_IMS_DOUTSYNC)
 
 /* Interrupt Mask Set */
 #define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
@@ -1011,8 +1000,7 @@
 #define E1000_VFTA_ENTRY_BIT_SHIFT_MASK      0x1F
 
 /* DMA Coalescing register fields */
-#define E1000_PCIEMISC_LX_DECISION      0x00000080 /* Lx power decision based
-                                                      on DMA coal */
+#define E1000_PCIEMISC_LX_DECISION      0x00000080 /* Lx power on DMA coal */
 
 /* Tx Rate-Scheduler Config fields */
 #define E1000_RTTBCNRC_RS_ENA		0x80000000
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 10741d1..89925e4 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -1,28 +1,24 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_HW_H_
 #define _E1000_HW_H_
@@ -320,15 +316,15 @@
 #include "e1000_mbx.h"
 
 struct e1000_mac_operations {
-	s32  (*check_for_link)(struct e1000_hw *);
-	s32  (*reset_hw)(struct e1000_hw *);
-	s32  (*init_hw)(struct e1000_hw *);
+	s32 (*check_for_link)(struct e1000_hw *);
+	s32 (*reset_hw)(struct e1000_hw *);
+	s32 (*init_hw)(struct e1000_hw *);
 	bool (*check_mng_mode)(struct e1000_hw *);
-	s32  (*setup_physical_interface)(struct e1000_hw *);
+	s32 (*setup_physical_interface)(struct e1000_hw *);
 	void (*rar_set)(struct e1000_hw *, u8 *, u32);
-	s32  (*read_mac_addr)(struct e1000_hw *);
-	s32  (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
-	s32  (*acquire_swfw_sync)(struct e1000_hw *, u16);
+	s32 (*read_mac_addr)(struct e1000_hw *);
+	s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
+	s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
 	void (*release_swfw_sync)(struct e1000_hw *, u16);
 #ifdef CONFIG_IGB_HWMON
 	s32 (*get_thermal_sensor_data)(struct e1000_hw *);
@@ -338,31 +334,31 @@
 };
 
 struct e1000_phy_operations {
-	s32  (*acquire)(struct e1000_hw *);
-	s32  (*check_polarity)(struct e1000_hw *);
-	s32  (*check_reset_block)(struct e1000_hw *);
-	s32  (*force_speed_duplex)(struct e1000_hw *);
-	s32  (*get_cfg_done)(struct e1000_hw *hw);
-	s32  (*get_cable_length)(struct e1000_hw *);
-	s32  (*get_phy_info)(struct e1000_hw *);
-	s32  (*read_reg)(struct e1000_hw *, u32, u16 *);
+	s32 (*acquire)(struct e1000_hw *);
+	s32 (*check_polarity)(struct e1000_hw *);
+	s32 (*check_reset_block)(struct e1000_hw *);
+	s32 (*force_speed_duplex)(struct e1000_hw *);
+	s32 (*get_cfg_done)(struct e1000_hw *hw);
+	s32 (*get_cable_length)(struct e1000_hw *);
+	s32 (*get_phy_info)(struct e1000_hw *);
+	s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
 	void (*release)(struct e1000_hw *);
-	s32  (*reset)(struct e1000_hw *);
-	s32  (*set_d0_lplu_state)(struct e1000_hw *, bool);
-	s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
-	s32  (*write_reg)(struct e1000_hw *, u32, u16);
+	s32 (*reset)(struct e1000_hw *);
+	s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
+	s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
+	s32 (*write_reg)(struct e1000_hw *, u32, u16);
 	s32 (*read_i2c_byte)(struct e1000_hw *, u8, u8, u8 *);
 	s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
 };
 
 struct e1000_nvm_operations {
-	s32  (*acquire)(struct e1000_hw *);
-	s32  (*read)(struct e1000_hw *, u16, u16, u16 *);
+	s32 (*acquire)(struct e1000_hw *);
+	s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
 	void (*release)(struct e1000_hw *);
-	s32  (*write)(struct e1000_hw *, u16, u16, u16 *);
-	s32  (*update)(struct e1000_hw *);
-	s32  (*validate)(struct e1000_hw *);
-	s32  (*valid_led_default)(struct e1000_hw *, u16 *);
+	s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
+	s32 (*update)(struct e1000_hw *);
+	s32 (*validate)(struct e1000_hw *);
+	s32 (*valid_led_default)(struct e1000_hw *, u16 *);
 };
 
 #define E1000_MAX_SENSORS		3
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index db96339..2231598 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 /* e1000_i210
  * e1000_i211
@@ -365,7 +362,7 @@
 			word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
 			if (word_address == address) {
 				*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
-				hw_dbg("Read INVM Word 0x%02x = %x",
+				hw_dbg("Read INVM Word 0x%02x = %x\n",
 					  address, *data);
 				status = E1000_SUCCESS;
 				break;
@@ -435,6 +432,7 @@
 			*data = ID_LED_RESERVED_FFFF;
 			ret_val = E1000_SUCCESS;
 		}
+		break;
 	case NVM_SUB_DEV_ID:
 		*data = hw->subsystem_device_id;
 		break;
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
index 907fe99..9f34976 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_I210_H_
 #define _E1000_I210_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c
index 5910a93..2a88595 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #include <linux/if_ether.h>
 #include <linux/delay.h>
@@ -442,7 +439,7 @@
  *  The caller must have a packed mc_addr_list of multicast addresses.
  **/
 void igb_update_mc_addr_list(struct e1000_hw *hw,
-                             u8 *mc_addr_list, u32 mc_addr_count)
+			     u8 *mc_addr_list, u32 mc_addr_count)
 {
 	u32 hash_value, hash_bit, hash_reg;
 	int i;
@@ -866,8 +863,7 @@
 			goto out;
 
 		if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
-			hw_dbg("Copper PHY and Auto Neg "
-				 "has not completed.\n");
+			hw_dbg("Copper PHY and Auto Neg has not completed.\n");
 			goto out;
 		}
 
@@ -929,11 +925,10 @@
 			 */
 			if (hw->fc.requested_mode == e1000_fc_full) {
 				hw->fc.current_mode = e1000_fc_full;
-				hw_dbg("Flow Control = FULL.\r\n");
+				hw_dbg("Flow Control = FULL.\n");
 			} else {
 				hw->fc.current_mode = e1000_fc_rx_pause;
-				hw_dbg("Flow Control = "
-				       "RX PAUSE frames only.\r\n");
+				hw_dbg("Flow Control = RX PAUSE frames only.\n");
 			}
 		}
 		/* For receiving PAUSE frames ONLY.
@@ -948,7 +943,7 @@
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
 			hw->fc.current_mode = e1000_fc_tx_pause;
-			hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
+			hw_dbg("Flow Control = TX PAUSE frames only.\n");
 		}
 		/* For transmitting PAUSE frames ONLY.
 		 *
@@ -962,7 +957,7 @@
 			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
 			hw->fc.current_mode = e1000_fc_rx_pause;
-			hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
+			hw_dbg("Flow Control = RX PAUSE frames only.\n");
 		}
 		/* Per the IEEE spec, at this point flow control should be
 		 * disabled.  However, we want to consider that we could
@@ -988,10 +983,10 @@
 			 (hw->fc.requested_mode == e1000_fc_tx_pause) ||
 			 (hw->fc.strict_ieee)) {
 			hw->fc.current_mode = e1000_fc_none;
-			hw_dbg("Flow Control = NONE.\r\n");
+			hw_dbg("Flow Control = NONE.\n");
 		} else {
 			hw->fc.current_mode = e1000_fc_rx_pause;
-			hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
+			hw_dbg("Flow Control = RX PAUSE frames only.\n");
 		}
 
 		/* Now we need to do one last check...  If we auto-
@@ -1266,7 +1261,7 @@
 	while (i < AUTO_READ_DONE_TIMEOUT) {
 		if (rd32(E1000_EECD) & E1000_EECD_AUTO_RD)
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 		i++;
 	}
 
@@ -1299,7 +1294,7 @@
 	}
 
 	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
-		switch(hw->phy.media_type) {
+		switch (hw->phy.media_type) {
 		case e1000_media_type_internal_serdes:
 			*data = ID_LED_DEFAULT_82575_SERDES;
 			break;
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h
index 99299ba..ea24961b 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_MAC_H_
 #define _E1000_MAC_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_mbx.c b/drivers/net/ethernet/intel/igb/e1000_mbx.c
index d5b1217..162cc49 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mbx.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mbx.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #include "e1000_mbx.h"
 
diff --git a/drivers/net/ethernet/intel/igb/e1000_mbx.h b/drivers/net/ethernet/intel/igb/e1000_mbx.h
index f52f551..d20af6b 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mbx.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mbx.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_MBX_H_
 #define _E1000_MBX_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c
index 9abf829..92bcdbe 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -1,28 +1,24 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #include <linux/if_ether.h>
 #include <linux/delay.h>
@@ -480,6 +476,7 @@
 		/* Loop to allow for up to whole page write of eeprom */
 		while (widx < words) {
 			u16 word_out = data[widx];
+
 			word_out = (word_out >> 8) | (word_out << 8);
 			igb_shift_out_eec_bits(hw, word_out, 16);
 			widx++;
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.h b/drivers/net/ethernet/intel/igb/e1000_nvm.h
index 5b10117..febc9cd 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.h
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_NVM_H_
 #define _E1000_NVM_H_
@@ -32,7 +29,7 @@
 s32  igb_read_mac_addr(struct e1000_hw *hw);
 s32  igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
 s32  igb_read_part_string(struct e1000_hw *hw, u8 *part_num,
-                          u32 part_num_size);
+			  u32 part_num_size);
 s32  igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
 s32  igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
 s32  igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
index 4009bba..424f16c 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #include <linux/if_ether.h>
 #include <linux/delay.h>
@@ -924,8 +921,7 @@
 	if (phy->autoneg_wait_to_complete) {
 		ret_val = igb_wait_autoneg(hw);
 		if (ret_val) {
-			hw_dbg("Error while waiting for "
-			       "autoneg to complete\n");
+			hw_dbg("Error while waiting for autoneg to complete\n");
 			goto out;
 		}
 	}
@@ -2244,7 +2240,7 @@
 		hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
 	}
 	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
-	msleep(1);
+	usleep_range(1000, 2000);
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h
index 4c2c36c..fe921e2 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.h
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_PHY_H_
 #define _E1000_PHY_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index bdb246e..833bbb9 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #ifndef _E1000_REGS_H_
 #define _E1000_REGS_H_
@@ -301,9 +298,9 @@
 #define E1000_RA2      0x054E0  /* 2nd half of Rx address array - RW Array */
 #define E1000_PSRTYPE(_i)       (0x05480 + ((_i) * 4))
 #define E1000_RAL(_i)  (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
-                                       (0x054E0 + ((_i - 16) * 8)))
+					(0x054E0 + ((_i - 16) * 8)))
 #define E1000_RAH(_i)  (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
-                                       (0x054E4 + ((_i - 16) * 8)))
+					(0x054E4 + ((_i - 16) * 8)))
 #define E1000_IP4AT_REG(_i)     (0x05840 + ((_i) * 8))
 #define E1000_IP6AT_REG(_i)     (0x05880 + ((_i) * 4))
 #define E1000_WUPM_REG(_i)      (0x05A00 + ((_i) * 4))
@@ -358,8 +355,7 @@
 #define E1000_VMBMEM(_n)       (0x00800 + (64 * (_n)))
 #define E1000_VMOLR(_n)        (0x05AD0 + (4 * (_n)))
 #define E1000_DVMOLR(_n)       (0x0C038 + (64 * (_n)))
-#define E1000_VLVF(_n)         (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
-                                                       * Filter - RW */
+#define E1000_VLVF(_n)         (0x05D00 + (4 * (_n))) /* VLAN VM Filter */
 #define E1000_VMVIR(_n)        (0x03700 + (4 * (_n)))
 
 struct e1000_hw;
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 2713006..06102d1 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -1,29 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 /* Linux PRO/1000 Ethernet Driver main header file */
 
@@ -198,6 +194,7 @@
 	unsigned int bytecount;
 	u16 gso_segs;
 	__be16 protocol;
+
 	DEFINE_DMA_UNMAP_ADDR(dma);
 	DEFINE_DMA_UNMAP_LEN(len);
 	u32 tx_flags;
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index e5570ac..333a2b0 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 /* ethtool support for igb */
 
@@ -286,7 +283,7 @@
 	}
 
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		hw->mac.autoneg = 1;
@@ -399,7 +396,7 @@
 	adapter->fc_autoneg = pause->autoneg;
 
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
 		hw->fc.requested_mode = e1000_fc_default;
@@ -886,7 +883,7 @@
 	}
 
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	if (!netif_running(adapter->netdev)) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
@@ -1060,8 +1057,8 @@
 	{ E1000_TDT(0),	   0x100, 4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
 	{ E1000_TDT(4),	   0x40,  4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
 	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
-	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
-	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
 	{ E1000_TCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
 	{ E1000_RA,	   0, 16, TABLE64_TEST_LO,
 						0xFFFFFFFF, 0xFFFFFFFF },
@@ -1103,8 +1100,8 @@
 	{ E1000_TDT(0),	   0x100, 4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
 	{ E1000_TDT(4),	   0x40,  4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
 	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
-	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
-	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
 	{ E1000_TCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
 	{ E1000_RA,	   0, 16, TABLE64_TEST_LO,
 						0xFFFFFFFF, 0xFFFFFFFF },
@@ -1132,8 +1129,10 @@
 	{ E1000_RDBAH(4),  0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
 	{ E1000_RDLEN(4),  0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
 	/* Enable all RX queues before testing. */
-	{ E1000_RXDCTL(0), 0x100, 4,  WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
-	{ E1000_RXDCTL(4), 0x40, 12,  WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+	{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0,
+	  E1000_RXDCTL_QUEUE_ENABLE },
+	{ E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0,
+	  E1000_RXDCTL_QUEUE_ENABLE },
 	/* RDH is read-only for 82576, only test RDT. */
 	{ E1000_RDT(0),	   0x100, 4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
 	{ E1000_RDT(4),	   0x40, 12,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
@@ -1149,14 +1148,14 @@
 	{ E1000_TDBAH(4),  0x40, 12,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
 	{ E1000_TDLEN(4),  0x40, 12,  PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
 	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
-	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
-	{ E1000_RCTL, 	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+	{ E1000_RCTL,	   0x100, 1,  SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
 	{ E1000_TCTL,	   0x100, 1,  SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
 	{ E1000_RA,	   0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
 	{ E1000_RA,	   0, 16, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
 	{ E1000_RA2,	   0, 8, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
 	{ E1000_RA2,	   0, 8, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
-	{ E1000_MTA,	   0, 128,TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_MTA,	   0, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
 	{ 0, 0, 0, 0 }
 };
 
@@ -1170,7 +1169,8 @@
 	{ E1000_RDBAH(0),  0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
 	{ E1000_RDLEN(0),  0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
 	/* Enable all four RX queues before testing. */
-	{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+	{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0,
+	  E1000_RXDCTL_QUEUE_ENABLE },
 	/* RDH is read-only for 82575, only test RDT. */
 	{ E1000_RDT(0),    0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
 	{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
@@ -1196,8 +1196,8 @@
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 pat, val;
-	static const u32 _test[] =
-		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+	static const u32 _test[] = {
+		0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
 	for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
 		wr32(reg, (_test[pat] & write));
 		val = rd32(reg) & mask;
@@ -1206,11 +1206,11 @@
 				"pattern test reg %04X failed: got 0x%08X expected 0x%08X\n",
 				reg, val, (_test[pat] & write & mask));
 			*data = reg;
-			return 1;
+			return true;
 		}
 	}
 
-	return 0;
+	return false;
 }
 
 static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
@@ -1218,17 +1218,18 @@
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 val;
+
 	wr32(reg, write & mask);
 	val = rd32(reg);
 	if ((write & mask) != (val & mask)) {
 		dev_err(&adapter->pdev->dev,
-			"set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg,
-			(val & mask), (write & mask));
+			"set/check reg %04X test failed: got 0x%08X expected 0x%08X\n",
+			reg, (val & mask), (write & mask));
 		*data = reg;
-		return 1;
+		return true;
 	}
 
-	return 0;
+	return false;
 }
 
 #define REG_PATTERN_TEST(reg, mask, write) \
@@ -1387,14 +1388,14 @@
 	/* Hook up test interrupt handler just for this test */
 	if (adapter->flags & IGB_FLAG_HAS_MSIX) {
 		if (request_irq(adapter->msix_entries[0].vector,
-		                igb_test_intr, 0, netdev->name, adapter)) {
+				igb_test_intr, 0, netdev->name, adapter)) {
 			*data = 1;
 			return -1;
 		}
 	} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
 		shared_int = false;
 		if (request_irq(irq,
-		                igb_test_intr, 0, netdev->name, adapter)) {
+				igb_test_intr, 0, netdev->name, adapter)) {
 			*data = 1;
 			return -1;
 		}
@@ -1412,7 +1413,7 @@
 	/* Disable all the interrupts */
 	wr32(E1000_IMC, ~0);
 	wrfl();
-	msleep(10);
+	usleep_range(10000, 11000);
 
 	/* Define all writable bits for ICS */
 	switch (hw->mac.type) {
@@ -1459,7 +1460,7 @@
 			wr32(E1000_IMC, mask);
 			wr32(E1000_ICS, mask);
 			wrfl();
-			msleep(10);
+			usleep_range(10000, 11000);
 
 			if (adapter->test_icr & mask) {
 				*data = 3;
@@ -1481,7 +1482,7 @@
 		wr32(E1000_IMS, mask);
 		wr32(E1000_ICS, mask);
 		wrfl();
-		msleep(10);
+		usleep_range(10000, 11000);
 
 		if (!(adapter->test_icr & mask)) {
 			*data = 4;
@@ -1503,7 +1504,7 @@
 			wr32(E1000_IMC, ~mask);
 			wr32(E1000_ICS, ~mask);
 			wrfl();
-			msleep(10);
+			usleep_range(10000, 11000);
 
 			if (adapter->test_icr & mask) {
 				*data = 5;
@@ -1515,7 +1516,7 @@
 	/* Disable all the interrupts */
 	wr32(E1000_IMC, ~0);
 	wrfl();
-	msleep(10);
+	usleep_range(10000, 11000);
 
 	/* Unhook test interrupt handler */
 	if (adapter->flags & IGB_FLAG_HAS_MSIX)
@@ -1949,6 +1950,7 @@
 	*data = 0;
 	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
 		int i = 0;
+
 		hw->mac.serdes_has_link = false;
 
 		/* On some blade server designs, link establishment
@@ -2413,9 +2415,11 @@
 	switch (cmd->flow_type) {
 	case TCP_V4_FLOW:
 		cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		/* Fall through */
 	case UDP_V4_FLOW:
 		if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP)
 			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		/* Fall through */
 	case SCTP_V4_FLOW:
 	case AH_ESP_V4_FLOW:
 	case AH_V4_FLOW:
@@ -2425,9 +2429,11 @@
 		break;
 	case TCP_V6_FLOW:
 		cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		/* Fall through */
 	case UDP_V6_FLOW:
 		if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP)
 			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+		/* Fall through */
 	case SCTP_V6_FLOW:
 	case AH_ESP_V6_FLOW:
 	case AH_V6_FLOW:
diff --git a/drivers/net/ethernet/intel/igb/igb_hwmon.c b/drivers/net/ethernet/intel/igb/igb_hwmon.c
index 8333f67..44b6a68 100644
--- a/drivers/net/ethernet/intel/igb/igb_hwmon.c
+++ b/drivers/net/ethernet/intel/igb/igb_hwmon.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #include "igb.h"
 #include "e1000_82575.h"
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index fb98d46..bfcda8a 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
-  Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007-2014 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, see <http://www.gnu.org/licenses/>.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-2014 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -75,7 +72,7 @@
 	[board_82575] = &e1000_82575_info,
 };
 
-static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
+static const struct pci_device_id igb_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_BACKPLANE_1GBPS) },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_SGMII) },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_BACKPLANE_2_5GBPS) },
@@ -117,7 +114,6 @@
 
 MODULE_DEVICE_TABLE(pci, igb_pci_tbl);
 
-void igb_reset(struct igb_adapter *);
 static int igb_setup_all_tx_resources(struct igb_adapter *);
 static int igb_setup_all_rx_resources(struct igb_adapter *);
 static void igb_free_all_tx_resources(struct igb_adapter *);
@@ -141,7 +137,7 @@
 static void igb_watchdog_task(struct work_struct *);
 static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *);
 static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev,
-						 struct rtnl_link_stats64 *stats);
+					  struct rtnl_link_stats64 *stats);
 static int igb_change_mtu(struct net_device *, int);
 static int igb_set_mac(struct net_device *, void *);
 static void igb_set_uta(struct igb_adapter *adapter);
@@ -159,7 +155,8 @@
 static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
 static void igb_tx_timeout(struct net_device *);
 static void igb_reset_task(struct work_struct *);
-static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features);
+static void igb_vlan_mode(struct net_device *netdev,
+			  netdev_features_t features);
 static int igb_vlan_rx_add_vid(struct net_device *, __be16, u16);
 static int igb_vlan_rx_kill_vid(struct net_device *, __be16, u16);
 static void igb_restore_vlan(struct igb_adapter *);
@@ -215,10 +212,9 @@
 static void igb_netpoll(struct net_device *);
 #endif
 #ifdef CONFIG_PCI_IOV
-static unsigned int max_vfs = 0;
+static unsigned int max_vfs;
 module_param(max_vfs, uint, 0);
-MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
-                 "per physical function");
+MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate per physical function");
 #endif /* CONFIG_PCI_IOV */
 
 static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
@@ -384,8 +380,7 @@
 	/* Print netdevice Info */
 	if (netdev) {
 		dev_info(&adapter->pdev->dev, "Net device Info\n");
-		pr_info("Device Name     state            trans_start      "
-			"last_rx\n");
+		pr_info("Device Name     state            trans_start      last_rx\n");
 		pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
 			netdev->state, netdev->trans_start, netdev->last_rx);
 	}
@@ -438,9 +433,7 @@
 		pr_info("------------------------------------\n");
 		pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index);
 		pr_info("------------------------------------\n");
-		pr_info("T [desc]     [address 63:0  ] [PlPOCIStDDM Ln] "
-			"[bi->dma       ] leng  ntw timestamp        "
-			"bi->skb\n");
+		pr_info("T [desc]     [address 63:0  ] [PlPOCIStDDM Ln] [bi->dma       ] leng  ntw timestamp        bi->skb\n");
 
 		for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
 			const char *next_desc;
@@ -458,9 +451,8 @@
 			else
 				next_desc = "";
 
-			pr_info("T [0x%03X]    %016llX %016llX %016llX"
-				" %04X  %p %016llX %p%s\n", i,
-				le64_to_cpu(u0->a),
+			pr_info("T [0x%03X]    %016llX %016llX %016llX %04X  %p %016llX %p%s\n",
+				i, le64_to_cpu(u0->a),
 				le64_to_cpu(u0->b),
 				(u64)dma_unmap_addr(buffer_info, dma),
 				dma_unmap_len(buffer_info, len),
@@ -519,10 +511,8 @@
 		pr_info("------------------------------------\n");
 		pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index);
 		pr_info("------------------------------------\n");
-		pr_info("R  [desc]      [ PktBuf     A0] [  HeadBuf   DD] "
-			"[bi->dma       ] [bi->skb] <-- Adv Rx Read format\n");
-		pr_info("RWB[desc]      [PcsmIpSHl PtRs] [vl er S cks ln] -----"
-			"----------- [bi->skb] <-- Adv Rx Write-Back format\n");
+		pr_info("R  [desc]      [ PktBuf     A0] [  HeadBuf   DD] [bi->dma       ] [bi->skb] <-- Adv Rx Read format\n");
+		pr_info("RWB[desc]      [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format\n");
 
 		for (i = 0; i < rx_ring->count; i++) {
 			const char *next_desc;
@@ -584,7 +574,7 @@
 	struct e1000_hw *hw = &adapter->hw;
 	s32 i2cctl = rd32(E1000_I2CPARAMS);
 
-	return ((i2cctl & E1000_I2C_DATA_IN) != 0);
+	return !!(i2cctl & E1000_I2C_DATA_IN);
 }
 
 /**
@@ -648,7 +638,7 @@
 	struct e1000_hw *hw = &adapter->hw;
 	s32 i2cctl = rd32(E1000_I2CPARAMS);
 
-	return ((i2cctl & E1000_I2C_CLK_IN) != 0);
+	return !!(i2cctl & E1000_I2C_CLK_IN);
 }
 
 static const struct i2c_algo_bit_data igb_i2c_algo = {
@@ -681,9 +671,9 @@
 static int __init igb_init_module(void)
 {
 	int ret;
+
 	pr_info("%s - version %s\n",
 	       igb_driver_string, igb_driver_version);
-
 	pr_info("%s\n", igb_copyright);
 
 #ifdef CONFIG_IGB_DCA
@@ -736,12 +726,14 @@
 				adapter->rx_ring[i]->reg_idx = rbase_offset +
 							       Q_IDX_82576(i);
 		}
+		/* Fall through */
 	case e1000_82575:
 	case e1000_82580:
 	case e1000_i350:
 	case e1000_i354:
 	case e1000_i210:
 	case e1000_i211:
+		/* Fall through */
 	default:
 		for (; i < adapter->num_rx_queues; i++)
 			adapter->rx_ring[i]->reg_idx = rbase_offset + i;
@@ -1292,8 +1284,7 @@
 		if (adapter->hw.mac.type >= e1000_82576)
 			set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags);
 
-		/*
-		 * On i350, i354, i210, and i211, loopback VLAN packets
+		/* On i350, i354, i210, and i211, loopback VLAN packets
 		 * have the tag byte-swapped.
 		 */
 		if (adapter->hw.mac.type >= e1000_i350)
@@ -1345,6 +1336,7 @@
 	for (; v_idx < q_vectors; v_idx++) {
 		int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - v_idx);
 		int tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - v_idx);
+
 		err = igb_alloc_q_vector(adapter, q_vectors, v_idx,
 					 tqpv, txr_idx, rqpv, rxr_idx);
 
@@ -1484,6 +1476,7 @@
 	 */
 	if (adapter->flags & IGB_FLAG_HAS_MSIX) {
 		u32 regval = rd32(E1000_EIAM);
+
 		wr32(E1000_EIAM, regval & ~adapter->eims_enable_mask);
 		wr32(E1000_EIMC, adapter->eims_enable_mask);
 		regval = rd32(E1000_EIAC);
@@ -1495,6 +1488,7 @@
 	wrfl();
 	if (adapter->flags & IGB_FLAG_HAS_MSIX) {
 		int i;
+
 		for (i = 0; i < adapter->num_q_vectors; i++)
 			synchronize_irq(adapter->msix_entries[i].vector);
 	} else {
@@ -1513,6 +1507,7 @@
 	if (adapter->flags & IGB_FLAG_HAS_MSIX) {
 		u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_DRSTA;
 		u32 regval = rd32(E1000_EIAC);
+
 		wr32(E1000_EIAC, regval | adapter->eims_enable_mask);
 		regval = rd32(E1000_EIAM);
 		wr32(E1000_EIAM, regval | adapter->eims_enable_mask);
@@ -1745,6 +1740,7 @@
 	/* notify VFs that reset has been completed */
 	if (adapter->vfs_allocated_count) {
 		u32 reg_data = rd32(E1000_CTRL_EXT);
+
 		reg_data |= E1000_CTRL_EXT_PFRSTD;
 		wr32(E1000_CTRL_EXT, reg_data);
 	}
@@ -1787,7 +1783,7 @@
 	wr32(E1000_TCTL, tctl);
 	/* flush both disables and wait for them to finish */
 	wrfl();
-	msleep(10);
+	usleep_range(10000, 11000);
 
 	igb_irq_disable(adapter);
 
@@ -1827,7 +1823,7 @@
 {
 	WARN_ON(in_interrupt());
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 	igb_down(adapter);
 	igb_up(adapter);
 	clear_bit(__IGB_RESETTING, &adapter->state);
@@ -1960,6 +1956,7 @@
 	/* disable receive for all VFs and wait one second */
 	if (adapter->vfs_allocated_count) {
 		int i;
+
 		for (i = 0 ; i < adapter->vfs_allocated_count; i++)
 			adapter->vf_data[i].flags &= IGB_VF_FLAG_PF_SET_MAC;
 
@@ -2529,7 +2526,8 @@
 	}
 
 	/* let the f/w know that the h/w is now under the control of the
-	 * driver. */
+	 * driver.
+	 */
 	igb_get_hw_control(adapter);
 
 	strcpy(netdev->name, "eth%d");
@@ -3077,6 +3075,7 @@
 	/* notify VFs that reset has been completed */
 	if (adapter->vfs_allocated_count) {
 		u32 reg_data = rd32(E1000_CTRL_EXT);
+
 		reg_data |= E1000_CTRL_EXT_PFRSTD;
 		wr32(E1000_CTRL_EXT, reg_data);
 	}
@@ -3248,7 +3247,7 @@
  *  Configure a transmit ring after a reset.
  **/
 void igb_configure_tx_ring(struct igb_adapter *adapter,
-                           struct igb_ring *ring)
+			   struct igb_ring *ring)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 txdctl = 0;
@@ -3389,7 +3388,8 @@
 
 	if (adapter->rss_indir_tbl_init != num_rx_queues) {
 		for (j = 0; j < IGB_RETA_SIZE; j++)
-			adapter->rss_indir_tbl[j] = (j * num_rx_queues) / IGB_RETA_SIZE;
+			adapter->rss_indir_tbl[j] =
+			(j * num_rx_queues) / IGB_RETA_SIZE;
 		adapter->rss_indir_tbl_init = num_rx_queues;
 	}
 	igb_write_rss_indir_tbl(adapter);
@@ -3430,6 +3430,7 @@
 		if (hw->mac.type > e1000_82575) {
 			/* Set the default pool for the PF's first queue */
 			u32 vtctl = rd32(E1000_VT_CTL);
+
 			vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
 				   E1000_VT_CTL_DISABLE_DEF_POOL);
 			vtctl |= adapter->vfs_allocated_count <<
@@ -3511,7 +3512,7 @@
 }
 
 static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
-                                   int vfn)
+				   int vfn)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 vmolr;
@@ -4058,7 +4059,8 @@
 	switch (hw->mac.type) {
 	case e1000_82576:
 	case e1000_i350:
-		if (!(wvbr = rd32(E1000_WVBR)))
+		wvbr = rd32(E1000_WVBR);
+		if (!wvbr)
 			return;
 		break;
 	default:
@@ -4077,7 +4079,7 @@
 	if (!adapter->wvbr)
 		return;
 
-	for(j = 0; j < adapter->vfs_allocated_count; j++) {
+	for (j = 0; j < adapter->vfs_allocated_count; j++) {
 		if (adapter->wvbr & (1 << j) ||
 		    adapter->wvbr & (1 << (j + IGB_STAGGERED_QUEUE_OFFSET))) {
 			dev_warn(&adapter->pdev->dev,
@@ -4209,14 +4211,15 @@
 
 		if (!netif_carrier_ok(netdev)) {
 			u32 ctrl;
+
 			hw->mac.ops.get_speed_and_duplex(hw,
 							 &adapter->link_speed,
 							 &adapter->link_duplex);
 
 			ctrl = rd32(E1000_CTRL);
 			/* Links status message must follow this format */
-			printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s "
-			       "Duplex, Flow Control: %s\n",
+			netdev_info(netdev,
+			       "igb: %s NIC Link is Up %d Mbps %s Duplex, Flow Control: %s\n",
 			       netdev->name,
 			       adapter->link_speed,
 			       adapter->link_duplex == FULL_DUPLEX ?
@@ -4242,11 +4245,8 @@
 
 			/* check for thermal sensor event */
 			if (igb_thermal_sensor_event(hw,
-			    E1000_THSTAT_LINK_THROTTLE)) {
-				netdev_info(netdev, "The network adapter link "
-					    "speed was downshifted because it "
-					    "overheated\n");
-			}
+			    E1000_THSTAT_LINK_THROTTLE))
+				netdev_info(netdev, "The network adapter link speed was downshifted because it overheated\n");
 
 			/* adjust timeout factor according to speed/duplex */
 			adapter->tx_timeout_factor = 1;
@@ -4277,12 +4277,11 @@
 			/* check for thermal sensor event */
 			if (igb_thermal_sensor_event(hw,
 			    E1000_THSTAT_PWR_DOWN)) {
-				netdev_err(netdev, "The network adapter was "
-					   "stopped because it overheated\n");
+				netdev_err(netdev, "The network adapter was stopped because it overheated\n");
 			}
 
 			/* Links status message must follow this format */
-			printk(KERN_INFO "igb: %s NIC Link is Down\n",
+			netdev_info(netdev, "igb: %s NIC Link is Down\n",
 			       netdev->name);
 			netif_carrier_off(netdev);
 
@@ -4344,6 +4343,7 @@
 	/* Cause software interrupt to ensure Rx ring is cleaned */
 	if (adapter->flags & IGB_FLAG_HAS_MSIX) {
 		u32 eics = 0;
+
 		for (i = 0; i < adapter->num_q_vectors; i++)
 			eics |= adapter->q_vector[i]->eims_value;
 		wr32(E1000_EICS, eics);
@@ -4483,13 +4483,12 @@
 	case low_latency:  /* 50 usec aka 20000 ints/s */
 		if (bytes > 10000) {
 			/* this if handles the TSO accounting */
-			if (bytes/packets > 8000) {
+			if (bytes/packets > 8000)
 				itrval = bulk_latency;
-			} else if ((packets < 10) || ((bytes/packets) > 1200)) {
+			else if ((packets < 10) || ((bytes/packets) > 1200))
 				itrval = bulk_latency;
-			} else if ((packets > 35)) {
+			else if ((packets > 35))
 				itrval = lowest_latency;
-			}
 		} else if (bytes/packets > 2000) {
 			itrval = bulk_latency;
 		} else if (packets <= 2 && bytes < 512) {
@@ -4675,6 +4674,7 @@
 			return;
 	} else {
 		u8 l4_hdr = 0;
+
 		switch (first->protocol) {
 		case htons(ETH_P_IP):
 			vlan_macip_lens |= skb_network_header_len(skb);
@@ -4962,6 +4962,7 @@
 	 */
 	if (NETDEV_FRAG_PAGE_MAX_SIZE > IGB_MAX_DATA_PER_TXD) {
 		unsigned short f;
+
 		for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
 			count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
 	} else {
@@ -5140,7 +5141,7 @@
 		max_frame = ETH_FRAME_LEN + ETH_FCS_LEN;
 
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	/* igb_down has a dependency on max_frame_size */
 	adapter->max_frame_size = max_frame;
@@ -5193,8 +5194,10 @@
 
 	rcu_read_lock();
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		u32 rqdpc = rd32(E1000_RQDPC(i));
 		struct igb_ring *ring = adapter->rx_ring[i];
+		u32 rqdpc = rd32(E1000_RQDPC(i));
+		if (hw->mac.type >= e1000_i210)
+			wr32(E1000_RQDPC(i), 0);
 
 		if (rqdpc) {
 			ring->rx_stats.drops += rqdpc;
@@ -5619,6 +5622,7 @@
 			vmolr |= E1000_VMOLR_MPME;
 		} else if (vf_data->num_vf_mc_hashes) {
 			int j;
+
 			vmolr |= E1000_VMOLR_ROMPE;
 			for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
 				igb_mta_set(hw, vf_data->vf_mc_hashes[j]);
@@ -5670,6 +5674,7 @@
 
 	for (i = 0; i < adapter->vfs_allocated_count; i++) {
 		u32 vmolr = rd32(E1000_VMOLR(i));
+
 		vmolr &= ~(E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
 
 		vf_data = &adapter->vf_data[i];
@@ -5768,6 +5773,7 @@
 
 			if (!adapter->vf_data[vf].vlans_enabled) {
 				u32 size;
+
 				reg = rd32(E1000_VMOLR(vf));
 				size = reg & E1000_VMOLR_RLPML_MASK;
 				size += 4;
@@ -5796,6 +5802,7 @@
 			adapter->vf_data[vf].vlans_enabled--;
 			if (!adapter->vf_data[vf].vlans_enabled) {
 				u32 size;
+
 				reg = rd32(E1000_VMOLR(vf));
 				size = reg & E1000_VMOLR_RLPML_MASK;
 				size -= 4;
@@ -5900,8 +5907,8 @@
 	 */
 	if (!add && (adapter->netdev->flags & IFF_PROMISC)) {
 		u32 vlvf, bits;
-
 		int regndx = igb_find_vlvf_entry(adapter, vid);
+
 		if (regndx < 0)
 			goto out;
 		/* See if any other pools are set for this VLAN filter
@@ -6492,7 +6499,7 @@
 	rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
 
 	/* transfer page from old buffer to new buffer */
-	memcpy(new_buff, old_buff, sizeof(struct igb_rx_buffer));
+	*new_buff = *old_buff;
 
 	/* sync the buffer for use by the device */
 	dma_sync_single_range_for_device(rx_ring->dev, old_buff->dma,
@@ -6961,6 +6968,7 @@
 	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
 	    igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
 		u16 vid;
+
 		if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) &&
 		    test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags))
 			vid = be16_to_cpu(rx_desc->wb.upper.vlan);
@@ -7049,7 +7057,7 @@
 	if (cleaned_count)
 		igb_alloc_rx_buffers(rx_ring, cleaned_count);
 
-	return (total_packets < budget);
+	return total_packets < budget;
 }
 
 static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
@@ -7170,7 +7178,7 @@
 		break;
 	case SIOCGMIIREG:
 		if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
-		                     &data->val_out))
+				     &data->val_out))
 			return -EIO;
 		break;
 	case SIOCSMIIREG:
@@ -7953,11 +7961,13 @@
 		reg = rd32(E1000_DTXCTL);
 		reg |= E1000_DTXCTL_VLAN_ADDED;
 		wr32(E1000_DTXCTL, reg);
+		/* Fall through */
 	case e1000_82580:
 		/* enable replication vlan tag stripping */
 		reg = rd32(E1000_RPLOLR);
 		reg |= E1000_RPLOLR_STRVLAN;
 		wr32(E1000_RPLOLR, reg);
+		/* Fall through */
 	case e1000_i350:
 		/* none of the above registers are supported by i350 */
 		break;
@@ -8047,6 +8057,7 @@
 		} /* endif adapter->dmac is not disabled */
 	} else if (hw->mac.type == e1000_82580) {
 		u32 reg = rd32(E1000_PCIEMISC);
+
 		wr32(E1000_PCIEMISC, reg & ~E1000_PCIEMISC_LX_DECISION);
 		wr32(E1000_DMACR, 0);
 	}
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index 9209d65..ab25e49 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -389,7 +389,7 @@
 		adapter->ptp_tx_skb = NULL;
 		clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
 		adapter->tx_hwtstamp_timeouts++;
-		dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang");
+		dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n");
 		return;
 	}
 
@@ -451,7 +451,7 @@
 		rd32(E1000_RXSTMPH);
 		adapter->last_rx_ptp_check = jiffies;
 		adapter->rx_hwtstamp_cleared++;
-		dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang");
+		dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang\n");
 	}
 }
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 1a12c1d..c688c8a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -155,7 +155,6 @@
 struct vf_macvlans {
 	struct list_head l;
 	int vf;
-	int rar_entry;
 	bool free;
 	bool is_macvlan;
 	u8 vf_macvlan[ETH_ALEN];
@@ -256,7 +255,6 @@
 		struct ixgbe_tx_buffer *tx_buffer_info;
 		struct ixgbe_rx_buffer *rx_buffer_info;
 	};
-	unsigned long last_rx_timestamp;
 	unsigned long state;
 	u8 __iomem *tail;
 	dma_addr_t dma;			/* phys. address of descriptor ring */
@@ -614,6 +612,15 @@
 #define MAX_MSIX_VECTORS_82598 18
 #define MAX_Q_VECTORS_82598 16
 
+struct ixgbe_mac_addr {
+	u8 addr[ETH_ALEN];
+	u16 queue;
+	u16 state; /* bitmask */
+};
+#define IXGBE_MAC_STATE_DEFAULT		0x1
+#define IXGBE_MAC_STATE_MODIFIED	0x2
+#define IXGBE_MAC_STATE_IN_USE		0x4
+
 #define MAX_Q_VECTORS MAX_Q_VECTORS_82599
 #define MAX_MSIX_COUNT MAX_MSIX_VECTORS_82599
 
@@ -770,6 +777,7 @@
 	unsigned long ptp_tx_start;
 	unsigned long last_overflow_check;
 	unsigned long last_rx_ptp_check;
+	unsigned long last_rx_timestamp;
 	spinlock_t tmreg_lock;
 	struct cyclecounter cc;
 	struct timecounter tc;
@@ -785,6 +793,7 @@
 
 	u32 timer_event_accumulator;
 	u32 vferr_refcount;
+	struct ixgbe_mac_addr *mac_table;
 	struct kobject *info_kobj;
 #ifdef CONFIG_IXGBE_HWMON
 	struct hwmon_buff *ixgbe_hwmon_buff;
@@ -863,6 +872,13 @@
 int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
 int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
 			       u16 subdevice_id);
+#ifdef CONFIG_PCI_IOV
+void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter);
+#endif
+int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
+			 u8 *addr, u16 queue);
+int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
+			 u8 *addr, u16 queue);
 void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
 netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *,
 				  struct ixgbe_ring *);
@@ -944,24 +960,7 @@
 void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
-void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
-			     struct sk_buff *skb);
-static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
-					 union ixgbe_adv_rx_desc *rx_desc,
-					 struct sk_buff *skb)
-{
-	if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
-		return;
-
-	__ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb);
-
-	/*
-	 * Update the last_rx_timestamp timer in order to enable watchdog check
-	 * for error case of latched timestamp on a dropped packet.
-	 */
-	rx_ring->last_rx_timestamp = jiffies;
-}
-
+void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb);
 int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
 int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
 void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 4c78ea8..1c52e47 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -337,19 +337,25 @@
 	int i;
 	bool link_up;
 
-	/*
-	 * Validate the water mark configuration for packet buffer 0.  Zero
-	 * water marks indicate that the packet buffer was not configured
-	 * and the watermarks for packet buffer 0 should always be configured.
-	 */
-	if (!hw->fc.low_water ||
-	    !hw->fc.high_water[0] ||
-	    !hw->fc.pause_time) {
-		hw_dbg(hw, "Invalid water mark configuration\n");
+	/* Validate the water mark configuration */
+	if (!hw->fc.pause_time) {
 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
 		goto out;
 	}
 
+	/* Low water mark of zero causes XOFF floods */
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+		    hw->fc.high_water[i]) {
+			if (!hw->fc.low_water[i] ||
+			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
+				hw_dbg(hw, "Invalid water mark configuration\n");
+				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+				goto out;
+			}
+		}
+	}
+
 	/*
 	 * On 82598 having Rx FC on causes resets while doing 1G
 	 * so if it's on turn it off once we know link_speed. For
@@ -432,12 +438,11 @@
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
 
-	fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
-
 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
 		    hw->fc.high_water[i]) {
+			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 24fba39..bdc5581 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -271,6 +271,7 @@
  **/
 s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 {
+	s32 ret_val;
 	u32 ctrl_ext;
 
 	/* Set the media type */
@@ -292,12 +293,15 @@
 	IXGBE_WRITE_FLUSH(hw);
 
 	/* Setup flow control */
-	ixgbe_setup_fc(hw);
+	ret_val = ixgbe_setup_fc(hw);
+	if (!ret_val)
+		goto out;
 
 	/* Clear adapter stopped flag */
 	hw->adapter_stopped = false;
 
-	return 0;
+out:
+	return ret_val;
 }
 
 /**
@@ -1195,7 +1199,7 @@
 	 */
 	hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
 
-	hw_dbg(hw, "Detected EEPROM page size = %d words.",
+	hw_dbg(hw, "Detected EEPROM page size = %d words.\n",
 	       hw->eeprom.word_page_size);
 out:
 	return status;
@@ -2106,19 +2110,25 @@
 	u32 fcrtl, fcrth;
 	int i;
 
-	/*
-	 * Validate the water mark configuration for packet buffer 0.  Zero
-	 * water marks indicate that the packet buffer was not configured
-	 * and the watermarks for packet buffer 0 should always be configured.
-	 */
-	if (!hw->fc.low_water ||
-	    !hw->fc.high_water[0] ||
-	    !hw->fc.pause_time) {
-		hw_dbg(hw, "Invalid water mark configuration\n");
+	/* Validate the water mark configuration. */
+	if (!hw->fc.pause_time) {
 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
 		goto out;
 	}
 
+	/* Low water mark of zero causes XOFF floods */
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+		    hw->fc.high_water[i]) {
+			if (!hw->fc.low_water[i] ||
+			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
+				hw_dbg(hw, "Invalid water mark configuration\n");
+				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+				goto out;
+			}
+		}
+	}
+
 	/* Negotiate the fc mode to use */
 	ixgbe_fc_autoneg(hw);
 
@@ -2181,12 +2191,11 @@
 	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
 	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
 
-	fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
-
 	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
 		    hw->fc.high_water[i]) {
+			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
 			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
 		} else {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index f12c40f..d15ff2e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -141,8 +141,6 @@
 	return unlikely(!addr);
 }
 
-void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg);
-
 static inline void ixgbe_write_reg(struct ixgbe_hw *hw, u32 reg, u32 value)
 {
 	u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr);
@@ -172,18 +170,7 @@
 }
 #define IXGBE_WRITE_REG64(a, reg, value) ixgbe_write_reg64((a), (reg), (value))
 
-static inline u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg)
-{
-	u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr);
-	u32 value;
-
-	if (ixgbe_removed(reg_addr))
-		return IXGBE_FAILED_READ_REG;
-	value = readl(reg_addr + reg);
-	if (unlikely(value == IXGBE_FAILED_READ_REG))
-		ixgbe_check_remove(hw, reg);
-	return value;
-}
+u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg);
 #define IXGBE_READ_REG(a, reg) ixgbe_read_reg((a), (reg))
 
 #define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) \
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
index 7a77f37..d3ba63f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
@@ -208,7 +208,6 @@
 
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
 
-	fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
 	/* Configure PFC Tx thresholds per TC */
 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 		if (!(pfc_en & (1 << i))) {
@@ -217,6 +216,7 @@
 			continue;
 		}
 
+		fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
 		reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
index bdb99b3..3b932fe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
@@ -242,7 +242,6 @@
 			max_tc = prio_tc[i];
 	}
 
-	fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
 
 	/* Configure PFC Tx thresholds per TC */
 	for (i = 0; i <= max_tc; i++) {
@@ -257,6 +256,7 @@
 
 		if (enabled) {
 			reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
+			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
 		} else {
 			reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
index b16cc78..0772b77 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
@@ -81,9 +81,7 @@
 	void *extra_ddp_buffer;
 	dma_addr_t extra_ddp_buffer_dma;
 	unsigned long mode;
-#ifdef CONFIG_IXGBE_DCB
 	u8 up;
-#endif
 };
 
 #endif /* _IXGBE_FCOE_H */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index c4c526b..8089ea9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -301,7 +301,7 @@
 		ixgbe_service_event_schedule(adapter);
 }
 
-void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
+static void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
 {
 	u32 value;
 
@@ -320,6 +320,32 @@
 		ixgbe_remove_adapter(hw);
 }
 
+/**
+ * ixgbe_read_reg - Read from device register
+ * @hw: hw specific details
+ * @reg: offset of register to read
+ *
+ * Returns : value read or IXGBE_FAILED_READ_REG if removed
+ *
+ * This function is used to read device registers. It checks for device
+ * removal by confirming any read that returns all ones by checking the
+ * status register value for all ones. This function avoids reading from
+ * the hardware if a removal was previously detected in which case it
+ * returns IXGBE_FAILED_READ_REG (all ones).
+ */
+u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg)
+{
+	u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr);
+	u32 value;
+
+	if (ixgbe_removed(reg_addr))
+		return IXGBE_FAILED_READ_REG;
+	value = readl(reg_addr + reg);
+	if (unlikely(value == IXGBE_FAILED_READ_REG))
+		ixgbe_check_remove(hw, reg);
+	return value;
+}
+
 static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev)
 {
 	u16 value;
@@ -1664,7 +1690,8 @@
 
 	ixgbe_rx_checksum(rx_ring, rx_desc, skb);
 
-	ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
+	if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
+		ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector->adapter, skb);
 
 	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
 	    ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
@@ -3742,35 +3769,6 @@
 }
 
 /**
- * ixgbe_vlan_filter_disable - helper to disable hw vlan filtering
- * @adapter: driver data
- */
-static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
-{
-	struct ixgbe_hw *hw = &adapter->hw;
-	u32 vlnctrl;
-
-	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
-	vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
-	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
-}
-
-/**
- * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
- * @adapter: driver data
- */
-static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
-{
-	struct ixgbe_hw *hw = &adapter->hw;
-	u32 vlnctrl;
-
-	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
-	vlnctrl |= IXGBE_VLNCTRL_VFE;
-	vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
-	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
-}
-
-/**
  * ixgbe_vlan_strip_disable - helper to disable hw vlan stripping
  * @adapter: driver data
  */
@@ -3849,6 +3847,158 @@
 }
 
 /**
+ * ixgbe_write_mc_addr_list - write multicast addresses to MTA
+ * @netdev: network interface device structure
+ *
+ * Writes multicast address list to the MTA hash table.
+ * Returns: -ENOMEM on failure
+ *                0 on no addresses written
+ *                X on writing X addresses to MTA
+ **/
+static int ixgbe_write_mc_addr_list(struct net_device *netdev)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	if (!netif_running(netdev))
+		return 0;
+
+	if (hw->mac.ops.update_mc_addr_list)
+		hw->mac.ops.update_mc_addr_list(hw, netdev);
+	else
+		return -ENOMEM;
+
+#ifdef CONFIG_PCI_IOV
+	ixgbe_restore_vf_multicasts(adapter);
+#endif
+
+	return netdev_mc_count(netdev);
+}
+
+#ifdef CONFIG_PCI_IOV
+void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
+	for (i = 0; i < hw->mac.num_rar_entries; i++) {
+		if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
+			hw->mac.ops.set_rar(hw, i, adapter->mac_table[i].addr,
+					    adapter->mac_table[i].queue,
+					    IXGBE_RAH_AV);
+		else
+			hw->mac.ops.clear_rar(hw, i);
+
+		adapter->mac_table[i].state &= ~(IXGBE_MAC_STATE_MODIFIED);
+	}
+}
+#endif
+
+static void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
+	for (i = 0; i < hw->mac.num_rar_entries; i++) {
+		if (adapter->mac_table[i].state & IXGBE_MAC_STATE_MODIFIED) {
+			if (adapter->mac_table[i].state &
+			    IXGBE_MAC_STATE_IN_USE)
+				hw->mac.ops.set_rar(hw, i,
+						adapter->mac_table[i].addr,
+						adapter->mac_table[i].queue,
+						IXGBE_RAH_AV);
+			else
+				hw->mac.ops.clear_rar(hw, i);
+
+			adapter->mac_table[i].state &=
+						~(IXGBE_MAC_STATE_MODIFIED);
+		}
+	}
+}
+
+static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter)
+{
+	int i;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	for (i = 0; i < hw->mac.num_rar_entries; i++) {
+		adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
+		adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
+		memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
+		adapter->mac_table[i].queue = 0;
+	}
+	ixgbe_sync_mac_table(adapter);
+}
+
+static int ixgbe_available_rars(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i, count = 0;
+
+	for (i = 0; i < hw->mac.num_rar_entries; i++) {
+		if (adapter->mac_table[i].state == 0)
+			count++;
+	}
+	return count;
+}
+
+/* this function destroys the first RAR entry */
+static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter,
+					 u8 *addr)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN);
+	adapter->mac_table[0].queue = VMDQ_P(0);
+	adapter->mac_table[0].state = (IXGBE_MAC_STATE_DEFAULT |
+				       IXGBE_MAC_STATE_IN_USE);
+	hw->mac.ops.set_rar(hw, 0, adapter->mac_table[0].addr,
+			    adapter->mac_table[0].queue,
+			    IXGBE_RAH_AV);
+}
+
+int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
+
+	if (is_zero_ether_addr(addr))
+		return -EINVAL;
+
+	for (i = 0; i < hw->mac.num_rar_entries; i++) {
+		if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
+			continue;
+		adapter->mac_table[i].state |= (IXGBE_MAC_STATE_MODIFIED |
+						IXGBE_MAC_STATE_IN_USE);
+		ether_addr_copy(adapter->mac_table[i].addr, addr);
+		adapter->mac_table[i].queue = queue;
+		ixgbe_sync_mac_table(adapter);
+		return i;
+	}
+	return -ENOMEM;
+}
+
+int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
+{
+	/* search table for addr, if found, set to 0 and sync */
+	int i;
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	if (is_zero_ether_addr(addr))
+		return -EINVAL;
+
+	for (i = 0; i < hw->mac.num_rar_entries; i++) {
+		if (ether_addr_equal(addr, adapter->mac_table[i].addr) &&
+		    adapter->mac_table[i].queue == queue) {
+			adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
+			adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
+			memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
+			adapter->mac_table[i].queue = 0;
+			ixgbe_sync_mac_table(adapter);
+			return 0;
+		}
+	}
+	return -ENOMEM;
+}
+/**
  * ixgbe_write_uc_addr_list - write unicast addresses to RAR table
  * @netdev: network interface device structure
  *
@@ -3857,39 +4007,23 @@
  *                0 on no addresses written
  *                X on writing X addresses to the RAR table
  **/
-static int ixgbe_write_uc_addr_list(struct net_device *netdev)
+static int ixgbe_write_uc_addr_list(struct net_device *netdev, int vfn)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	struct ixgbe_hw *hw = &adapter->hw;
-	unsigned int rar_entries = hw->mac.num_rar_entries - 1;
 	int count = 0;
 
-	/* In SR-IOV/VMDQ modes significantly less RAR entries are available */
-	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
-		rar_entries = IXGBE_MAX_PF_MACVLANS - 1;
-
 	/* return ENOMEM indicating insufficient memory for addresses */
-	if (netdev_uc_count(netdev) > rar_entries)
+	if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter))
 		return -ENOMEM;
 
 	if (!netdev_uc_empty(netdev)) {
 		struct netdev_hw_addr *ha;
-		/* return error if we do not support writing to RAR table */
-		if (!hw->mac.ops.set_rar)
-			return -ENOMEM;
-
 		netdev_for_each_uc_addr(ha, netdev) {
-			if (!rar_entries)
-				break;
-			hw->mac.ops.set_rar(hw, rar_entries--, ha->addr,
-					    VMDQ_P(0), IXGBE_RAH_AV);
+			ixgbe_del_mac_filter(adapter, ha->addr, vfn);
+			ixgbe_add_mac_filter(adapter, ha->addr, vfn);
 			count++;
 		}
 	}
-	/* write the addresses in reverse order to avoid write combining */
-	for (; rar_entries > 0 ; rar_entries--)
-		hw->mac.ops.clear_rar(hw, rar_entries);
-
 	return count;
 }
 
@@ -3907,11 +4041,12 @@
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
+	u32 vlnctrl;
 	int count;
 
 	/* Check for Promiscuous and All Multicast modes */
-
 	fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
 
 	/* set all bits that we expect to always be set */
 	fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
@@ -3921,26 +4056,24 @@
 
 	/* clear the bits we are changing the status of */
 	fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-
+	vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
 	if (netdev->flags & IFF_PROMISC) {
 		hw->addr_ctrl.user_set_promisc = true;
 		fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-		vmolr |= (IXGBE_VMOLR_ROPE | IXGBE_VMOLR_MPE);
+		vmolr |= IXGBE_VMOLR_MPE;
 		/* Only disable hardware filter vlans in promiscuous mode
 		 * if SR-IOV and VMDQ are disabled - otherwise ensure
 		 * that hardware VLAN filters remain enabled.
 		 */
 		if (!(adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
 					IXGBE_FLAG_SRIOV_ENABLED)))
-			ixgbe_vlan_filter_disable(adapter);
-		else
-			ixgbe_vlan_filter_enable(adapter);
+			vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
 	} else {
 		if (netdev->flags & IFF_ALLMULTI) {
 			fctrl |= IXGBE_FCTRL_MPE;
 			vmolr |= IXGBE_VMOLR_MPE;
 		}
-		ixgbe_vlan_filter_enable(adapter);
+		vlnctrl |= IXGBE_VLNCTRL_VFE;
 		hw->addr_ctrl.user_set_promisc = false;
 	}
 
@@ -3949,7 +4082,7 @@
 	 * sufficient space to store all the addresses then enable
 	 * unicast promiscuous mode
 	 */
-	count = ixgbe_write_uc_addr_list(netdev);
+	count = ixgbe_write_uc_addr_list(netdev, VMDQ_P(0));
 	if (count < 0) {
 		fctrl |= IXGBE_FCTRL_UPE;
 		vmolr |= IXGBE_VMOLR_ROPE;
@@ -3959,11 +4092,13 @@
 	 * then we should just turn on promiscuous mode so
 	 * that we can at least receive multicast traffic
 	 */
-	hw->mac.ops.update_mc_addr_list(hw, netdev);
-	vmolr |= IXGBE_VMOLR_ROMPE;
-
-	if (adapter->num_vfs)
-		ixgbe_restore_vf_multicasts(adapter);
+	count = ixgbe_write_mc_addr_list(netdev);
+	if (count < 0) {
+		fctrl |= IXGBE_FCTRL_MPE;
+		vmolr |= IXGBE_VMOLR_MPE;
+	} else if (count) {
+		vmolr |= IXGBE_VMOLR_ROMPE;
+	}
 
 	if (hw->mac.type != ixgbe_mac_82598EB) {
 		vmolr |= IXGBE_READ_REG(hw, IXGBE_VMOLR(VMDQ_P(0))) &
@@ -3984,6 +4119,7 @@
 		/* NOTE:  VLAN filtering is disabled by setting PROMISC */
 	}
 
+	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
 
 	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
@@ -4100,8 +4236,8 @@
 	    (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
 	    (pb == ixgbe_fcoe_get_tc(adapter)))
 		tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
-
 #endif
+
 	/* Calculate delay value for device */
 	switch (hw->mac.type) {
 	case ixgbe_mac_X540:
@@ -4142,7 +4278,7 @@
  * @adapter: board private structure to calculate for
  * @pb: packet buffer to calculate
  */
-static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter)
+static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int pb)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct net_device *dev = adapter->netdev;
@@ -4152,6 +4288,14 @@
 	/* Calculate max LAN frame size */
 	tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
 
+#ifdef IXGBE_FCOE
+	/* FCoE traffic class uses FCOE jumbo frames */
+	if ((dev->features & NETIF_F_FCOE_MTU) &&
+	    (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
+	    (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up)))
+		tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
+#endif
+
 	/* Calculate delay value for device */
 	switch (hw->mac.type) {
 	case ixgbe_mac_X540:
@@ -4178,15 +4322,17 @@
 	if (!num_tc)
 		num_tc = 1;
 
-	hw->fc.low_water = ixgbe_lpbthresh(adapter);
-
 	for (i = 0; i < num_tc; i++) {
 		hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i);
+		hw->fc.low_water[i] = ixgbe_lpbthresh(adapter, i);
 
 		/* Low water marks must not be larger than high water marks */
-		if (hw->fc.low_water > hw->fc.high_water[i])
-			hw->fc.low_water = 0;
+		if (hw->fc.low_water[i] > hw->fc.high_water[i])
+			hw->fc.low_water[i] = 0;
 	}
+
+	for (; i < MAX_TRAFFIC_CLASS; i++)
+		hw->fc.high_water[i] = 0;
 }
 
 static void ixgbe_configure_pb(struct ixgbe_adapter *adapter)
@@ -4248,20 +4394,10 @@
 		vmolr |= IXGBE_VMOLR_ROMPE;
 		hw->mac.ops.update_mc_addr_list(hw, dev);
 	}
-	ixgbe_write_uc_addr_list(adapter->netdev);
+	ixgbe_write_uc_addr_list(adapter->netdev, pool);
 	IXGBE_WRITE_REG(hw, IXGBE_VMOLR(pool), vmolr);
 }
 
-static void ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
-				 u8 *addr, u16 pool)
-{
-	struct ixgbe_hw *hw = &adapter->hw;
-	unsigned int entry;
-
-	entry = hw->mac.num_rar_entries - pool;
-	hw->mac.ops.set_rar(hw, entry, addr, VMDQ_P(pool), IXGBE_RAH_AV);
-}
-
 static void ixgbe_fwd_psrtype(struct ixgbe_fwd_adapter *vadapter)
 {
 	struct ixgbe_adapter *adapter = vadapter->real_adapter;
@@ -4741,7 +4877,9 @@
 void ixgbe_reset(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
 	int err;
+	u8 old_addr[ETH_ALEN];
 
 	if (ixgbe_removed(hw->hw_addr))
 		return;
@@ -4777,9 +4915,10 @@
 	}
 
 	clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
-
-	/* reprogram the RAR[0] in case user changed it. */
-	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, VMDQ_P(0), IXGBE_RAH_AV);
+	/* do not flush user set addresses */
+	memcpy(old_addr, &adapter->mac_table[0].addr, netdev->addr_len);
+	ixgbe_flush_sw_mac_table(adapter);
+	ixgbe_mac_set_default_filter(adapter, old_addr);
 
 	/* update SAN MAC vmdq pool selection */
 	if (hw->mac.san_mac_rar_index)
@@ -5025,6 +5164,10 @@
 #endif /* CONFIG_IXGBE_DCB */
 #endif /* IXGBE_FCOE */
 
+	adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
+				     hw->mac.num_rar_entries,
+				     GFP_ATOMIC);
+
 	/* Set MAC specific capability flags and exceptions */
 	switch (hw->mac.type) {
 	case ixgbe_mac_82598EB:
@@ -7171,16 +7314,17 @@
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct sockaddr *addr = p;
+	int ret;
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
+	ixgbe_del_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
 
-	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, VMDQ_P(0), IXGBE_RAH_AV);
-
-	return 0;
+	ret = ixgbe_add_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
+	return ret > 0 ? 0 : ret;
 }
 
 static int
@@ -8186,6 +8330,8 @@
 		goto err_sw_init;
 	}
 
+	ixgbe_mac_set_default_filter(adapter, hw->mac.perm_addr);
+
 	setup_timer(&adapter->service_timer, &ixgbe_service_timer,
 		    (unsigned long) adapter);
 
@@ -8318,6 +8464,7 @@
 	ixgbe_disable_sriov(adapter);
 	adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
 	iounmap(adapter->io_addr);
+	kfree(adapter->mac_table);
 err_ioremap:
 	free_netdev(netdev);
 err_alloc_etherdev:
@@ -8391,6 +8538,7 @@
 
 	e_dev_info("complete\n");
 
+	kfree(adapter->mac_table);
 	free_netdev(netdev);
 
 	pci_disable_pcie_error_reporting(pdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index 23f7652..a76af8e2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -536,7 +536,7 @@
 
 	if (time_out == max_time_out) {
 		status = IXGBE_ERR_LINK_SETUP;
-		hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out");
+		hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out\n");
 	}
 
 	return status;
@@ -745,7 +745,7 @@
 
 	if (time_out == max_time_out) {
 		status = IXGBE_ERR_LINK_SETUP;
-		hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out");
+		hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out\n");
 	}
 
 	return status;
@@ -1175,7 +1175,7 @@
 				status = 0;
 			} else {
 				if (hw->allow_unsupported_sfp) {
-					e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics.  Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter.  Intel Corporation is not responsible for any harm caused by using untested modules.");
+					e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics.  Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter.  Intel Corporation is not responsible for any harm caused by using untested modules.\n");
 					status = 0;
 				} else {
 					hw_dbg(hw,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 63515a6..8902ae6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -435,10 +435,8 @@
 void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	struct ixgbe_ring *rx_ring;
 	u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
 	unsigned long rx_event;
-	int n;
 
 	/* if we don't have a valid timestamp in the registers, just update the
 	 * timeout counter and exit
@@ -450,18 +448,15 @@
 
 	/* determine the most recent watchdog or rx_timestamp event */
 	rx_event = adapter->last_rx_ptp_check;
-	for (n = 0; n < adapter->num_rx_queues; n++) {
-		rx_ring = adapter->rx_ring[n];
-		if (time_after(rx_ring->last_rx_timestamp, rx_event))
-			rx_event = rx_ring->last_rx_timestamp;
-	}
+	if (time_after(adapter->last_rx_timestamp, rx_event))
+		rx_event = adapter->last_rx_timestamp;
 
 	/* only need to read the high RXSTMP register to clear the lock */
 	if (time_is_before_jiffies(rx_event + 5*HZ)) {
 		IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
 		adapter->last_rx_ptp_check = jiffies;
 
-		e_warn(drv, "clearing RX Timestamp hang");
+		e_warn(drv, "clearing RX Timestamp hang\n");
 	}
 }
 
@@ -517,7 +512,7 @@
 		dev_kfree_skb_any(adapter->ptp_tx_skb);
 		adapter->ptp_tx_skb = NULL;
 		clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
-		e_warn(drv, "clearing Tx Timestamp hang");
+		e_warn(drv, "clearing Tx Timestamp hang\n");
 		return;
 	}
 
@@ -530,35 +525,22 @@
 }
 
 /**
- * __ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
- * @q_vector: structure containing interrupt and ring information
+ * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
+ * @adapter: pointer to adapter struct
  * @skb: particular skb to send timestamp with
  *
  * if the timestamp is valid, we convert it into the timecounter ns
  * value, then store that result into the shhwtstamps structure which
  * is passed up the network stack
  */
-void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
-			     struct sk_buff *skb)
+void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb)
 {
-	struct ixgbe_adapter *adapter;
-	struct ixgbe_hw *hw;
+	struct ixgbe_hw *hw = &adapter->hw;
 	struct skb_shared_hwtstamps *shhwtstamps;
 	u64 regval = 0, ns;
 	u32 tsyncrxctl;
 	unsigned long flags;
 
-	/* we cannot process timestamps on a ring without a q_vector */
-	if (!q_vector || !q_vector->adapter)
-		return;
-
-	adapter = q_vector->adapter;
-	hw = &adapter->hw;
-
-	/*
-	 * Read the tsyncrxctl register afterwards in order to prevent taking an
-	 * I/O hit on every packet.
-	 */
 	tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
 	if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
 		return;
@@ -566,13 +548,17 @@
 	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
 	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
 
-
 	spin_lock_irqsave(&adapter->tmreg_lock, flags);
 	ns = timecounter_cyc2time(&adapter->tc, regval);
 	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
 
 	shhwtstamps = skb_hwtstamps(skb);
 	shhwtstamps->hwtstamp = ns_to_ktime(ns);
+
+	/* Update the last_rx_timestamp timer in order to enable watchdog check
+	 * for error case of latched timestamp on a dropped packet.
+	 */
+	adapter->last_rx_timestamp = jiffies;
 }
 
 int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index e6c68d3..a01417c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -72,8 +72,6 @@
 		for (i = 0; i < num_vf_macvlans; i++) {
 			mv_list->vf = -1;
 			mv_list->free = true;
-			mv_list->rar_entry = hw->mac.num_rar_entries -
-				(i + adapter->num_vfs + 1);
 			list_add(&mv_list->l, &adapter->vf_mvs.l);
 			mv_list++;
 		}
@@ -327,6 +325,7 @@
 	u32 vector_bit;
 	u32 vector_reg;
 	u32 mta_reg;
+	u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
 
 	/* only so many hash values supported */
 	entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);
@@ -353,25 +352,13 @@
 		mta_reg |= (1 << vector_bit);
 		IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
 	}
+	vmolr |= IXGBE_VMOLR_ROMPE;
+	IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
 
 	return 0;
 }
 
-static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
-{
-	struct ixgbe_hw *hw = &adapter->hw;
-	struct list_head *pos;
-	struct vf_macvlans *entry;
-
-	list_for_each(pos, &adapter->vf_mvs.l) {
-		entry = list_entry(pos, struct vf_macvlans, l);
-		if (!entry->free)
-			hw->mac.ops.set_rar(hw, entry->rar_entry,
-					    entry->vf_macvlan,
-					    entry->vf, IXGBE_RAH_AV);
-	}
-}
-
+#ifdef CONFIG_PCI_IOV
 void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
@@ -382,6 +369,7 @@
 	u32 mta_reg;
 
 	for (i = 0; i < adapter->num_vfs; i++) {
+		u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(i));
 		vfinfo = &adapter->vfinfo[i];
 		for (j = 0; j < vfinfo->num_vf_mc_hashes; j++) {
 			hw->addr_ctrl.mta_in_use++;
@@ -391,11 +379,18 @@
 			mta_reg |= (1 << vector_bit);
 			IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
 		}
+
+		if (vfinfo->num_vf_mc_hashes)
+			vmolr |= IXGBE_VMOLR_ROMPE;
+		else
+			vmolr &= ~IXGBE_VMOLR_ROMPE;
+		IXGBE_WRITE_REG(hw, IXGBE_VMOLR(i), vmolr);
 	}
 
 	/* Restore any VF macvlans */
-	ixgbe_restore_vf_macvlans(adapter);
+	ixgbe_full_sync_mac_table(adapter);
 }
+#endif
 
 static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
 			     u32 vf)
@@ -495,8 +490,7 @@
 static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
 {
 	u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
-	vmolr |= (IXGBE_VMOLR_ROMPE |
-		  IXGBE_VMOLR_BAM);
+	vmolr |= IXGBE_VMOLR_BAM;
 	if (aupe)
 		vmolr |= IXGBE_VMOLR_AUPE;
 	else
@@ -514,7 +508,6 @@
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
-	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
 	u8 num_tcs = netdev_get_num_tc(adapter->netdev);
 
 	/* add PF assigned VLAN or VLAN 0 */
@@ -544,7 +537,7 @@
 	/* Flush and reset the mta with the new values */
 	ixgbe_set_rx_mode(adapter->netdev);
 
-	hw->mac.ops.clear_rar(hw, rar_entry);
+	ixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
 
 	/* reset VF api back to unknown */
 	adapter->vfinfo[vf].vf_api = ixgbe_mbox_api_10;
@@ -553,11 +546,9 @@
 static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
 			    int vf, unsigned char *mac_addr)
 {
-	struct ixgbe_hw *hw = &adapter->hw;
-	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
-
+	ixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
 	memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
-	hw->mac.ops.set_rar(hw, rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+	ixgbe_add_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
 
 	return 0;
 }
@@ -565,7 +556,6 @@
 static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
 				int vf, int index, unsigned char *mac_addr)
 {
-	struct ixgbe_hw *hw = &adapter->hw;
 	struct list_head *pos;
 	struct vf_macvlans *entry;
 
@@ -576,7 +566,8 @@
 				entry->vf = -1;
 				entry->free = true;
 				entry->is_macvlan = false;
-				hw->mac.ops.clear_rar(hw, entry->rar_entry);
+				ixgbe_del_mac_filter(adapter,
+						     entry->vf_macvlan, vf);
 			}
 		}
 	}
@@ -612,7 +603,7 @@
 	entry->vf = vf;
 	memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
 
-	hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+	ixgbe_add_mac_filter(adapter, mac_addr, vf);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index 139eadd..cea6401 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -34,7 +34,9 @@
  */
 #define IXGBE_MAX_VFS_DRV_LIMIT  (IXGBE_MAX_VF_FUNCTIONS - 1)
 
+#ifdef CONFIG_PCI_IOV
 void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
+#endif
 void ixgbe_msg_task(struct ixgbe_adapter *adapter);
 int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
 void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 8a6ff24..551d608 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2746,7 +2746,7 @@
 /* Flow control parameters */
 struct ixgbe_fc_info {
 	u32 high_water[MAX_TRAFFIC_CLASS]; /* Flow Control High-water */
-	u32 low_water; /* Flow Control Low-water */
+	u32 low_water[MAX_TRAFFIC_CLASS]; /* Flow Control Low-water */
 	u16 pause_time; /* Flow Control Pause timer */
 	bool send_xon; /* Flow control send XON */
 	bool strict_ieee; /* Strict IEEE mode */
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index d0799e8..eacce3a 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -85,7 +85,7 @@
 MODULE_DEVICE_TABLE(pci, ixgbevf_pci_tbl);
 
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
-MODULE_DESCRIPTION("Intel(R) 82599 Virtual Function Driver");
+MODULE_DESCRIPTION("Intel(R) 10 Gigabit Virtual Function Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index a2844ff..e900c1a 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -534,15 +534,6 @@
 	netif_tx_start_all_queues(sp->dev);
 }
 
-static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no)
-{
-	if (!sp->config.multiq)
-		sp->mac_control.fifos[fifo_no].queue_state =
-			FIFO_QUEUE_START;
-
-	netif_tx_start_all_queues(sp->dev);
-}
-
 static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp)
 {
 	if (!sp->config.multiq) {
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
index c14bd31..b818432 100644
--- a/drivers/net/ethernet/qlogic/Kconfig
+++ b/drivers/net/ethernet/qlogic/Kconfig
@@ -66,6 +66,17 @@
 	  Say Y here if you want to enable hardware offload support for
 	  Virtual eXtensible Local Area Network (VXLAN) in the driver.
 
+config QLCNIC_HWMON
+	bool "QLOGIC QLCNIC 82XX and 83XX family HWMON support"
+	depends on QLCNIC && HWMON
+	default y
+	---help---
+	  This configuration parameter can be used to read the
+	  board temperature in Converged Ethernet devices
+	  supported by qlcnic.
+
+	  This data is available via the hwmon sysfs interface.
+
 config QLGE
 	tristate "QLogic QLGE 10Gb Ethernet Driver Support"
 	depends on PCI
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 7b52a88..09fe9c2 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -39,8 +39,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 57
-#define QLCNIC_LINUX_VERSIONID  "5.3.57"
+#define _QLCNIC_LINUX_SUBVERSION 58
+#define QLCNIC_LINUX_VERSIONID  "5.3.58"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -537,6 +537,7 @@
 	u8 phys_port_id[ETH_ALEN];
 	u8 lb_mode;
 	u16 vxlan_port;
+	struct device *hwmon_dev;
 };
 
 struct qlcnic_adapter_stats {
@@ -2361,4 +2362,18 @@
 	else
 		return QLC_DEFAULT_VNIC_COUNT;
 }
+
+#ifdef CONFIG_QLCNIC_HWMON
+void qlcnic_register_hwmon_dev(struct qlcnic_adapter *);
+void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *);
+#else
+static inline void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+	return;
+}
+static inline void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+	return;
+}
+#endif
 #endif				/* __QLCNIC_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index b7cffb4..7c125d7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -33,6 +33,7 @@
 #define RSS_HASHTYPE_IP_TCP		0x3
 #define QLC_83XX_FW_MBX_CMD		0
 #define QLC_SKIP_INACTIVE_PCI_REGS	7
+#define QLC_MAX_LEGACY_FUNC_SUPP	8
 
 static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
 	{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
@@ -357,8 +358,15 @@
 	if (!ahw->intr_tbl)
 		return -ENOMEM;
 
-	if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
+	if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
+		if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) {
+			dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n",
+				ahw->pci_func);
+			return -EOPNOTSUPP;
+		}
+
 		qlcnic_83xx_enable_legacy(adapter);
+	}
 
 	for (i = 0; i < num_msix; i++) {
 		if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -879,6 +887,9 @@
 			return 0;
 		}
 	}
+
+	dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n",
+		__func__, type);
 	return -EINVAL;
 }
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index ba20c72..34d2737 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2181,6 +2181,8 @@
 		max_sds_rings = QLCNIC_MAX_SDS_RINGS;
 		max_tx_rings = QLCNIC_MAX_TX_RINGS;
 	} else {
+		dev_err(&adapter->pdev->dev, "%s: Invalid opmode %d\n",
+			__func__, ret);
 		return -EIO;
 	}
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index c1e11f5..304e247 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -1027,8 +1027,11 @@
 	u32 arg1;
 
 	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC ||
-	    !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE))
+	    !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
+		dev_err(&adapter->pdev->dev, "%s: Not a management function\n",
+			__func__);
 		return err;
+	}
 
 	arg1 = id | (enable_mirroring ? BIT_4 : 0);
 	arg1 |= pci_func << 8;
@@ -1318,8 +1321,12 @@
 	u32 arg1, arg2 = 0;
 	u8 pci_func;
 
-	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
+	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
+		dev_err(&adapter->pdev->dev, "%s: Not a management function\n",
+			__func__);
 		return err;
+	}
+
 	pci_func = esw_cfg->pci_func;
 	index = qlcnic_is_valid_nic_func(adapter, pci_func);
 	if (index < 0)
@@ -1363,6 +1370,8 @@
 			arg1 &= ~(0x0ffff << 16);
 			break;
 	default:
+		dev_err(&adapter->pdev->dev, "%s: Invalid opmode 0x%x\n",
+			__func__, esw_cfg->op_mode);
 		return err;
 	}
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 173b3d1..deb2278 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -305,7 +305,6 @@
 {
 	struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data);
 	struct ethhdr *phdr = (struct ethhdr *)(skb->data);
-	struct net_device *netdev = adapter->netdev;
 	u16 protocol = ntohs(skb->protocol);
 	struct qlcnic_filter *fil, *tmp_fil;
 	struct hlist_head *head;
@@ -330,13 +329,6 @@
 			return;
 	}
 
-	if (adapter->fhash.fnum >= adapter->fhash.fmax) {
-		adapter->stats.mac_filter_limit_overrun++;
-		netdev_info(netdev, "Can not add more than %d mac-vlan filters, configured %d\n",
-			    adapter->fhash.fmax, adapter->fhash.fnum);
-		return;
-	}
-
 	memcpy(&src_addr, phdr->h_source, ETH_ALEN);
 	hval = qlcnic_mac_hash(src_addr, vlan_id);
 	hindex = hval & (adapter->fhash.fbucket_size - 1);
@@ -353,6 +345,11 @@
 		}
 	}
 
+	if (unlikely(adapter->fhash.fnum >= adapter->fhash.fmax)) {
+		adapter->stats.mac_filter_limit_overrun++;
+		return;
+	}
+
 	fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC);
 	if (!fil)
 		return;
@@ -1216,8 +1213,7 @@
 	if (!skb)
 		return buffer;
 
-	if (adapter->drv_mac_learn &&
-	    (adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
+	if (adapter->rx_mac_learn) {
 		t_vid = 0;
 		is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0);
 		qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid);
@@ -1293,8 +1289,7 @@
 	if (!skb)
 		return buffer;
 
-	if (adapter->drv_mac_learn &&
-	    (adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
+	if (adapter->rx_mac_learn) {
 		t_vid = 0;
 		is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0);
 		qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index dbf7539..7023d35 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -690,10 +690,10 @@
 		adapter->msix_entries[vector].entry = vector;
 
 restore:
-	err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
-	if (err > 0) {
+	err = pci_enable_msix_exact(pdev, adapter->msix_entries, num_msix);
+	if (err == -ENOSPC) {
 		if (!adapter->drv_tss_rings && !adapter->drv_rss_rings)
-			return -ENOSPC;
+			return err;
 
 		netdev_info(adapter->netdev,
 			    "Unable to allocate %d MSI-X vectors, Available vectors %d\n",
@@ -1014,6 +1014,8 @@
 
 		if (pfn >= ahw->max_vnic_func) {
 			ret = QL_STATUS_INVALID_PARAM;
+			dev_err(&adapter->pdev->dev, "%s: Invalid function 0x%x, max 0x%x\n",
+				__func__, pfn, ahw->max_vnic_func);
 			goto err_eswitch;
 		}
 
@@ -2052,6 +2054,7 @@
 
 static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	int err = 0;
 
 	adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
@@ -2061,6 +2064,18 @@
 		goto err_out;
 	}
 
+	if (qlcnic_83xx_check(adapter)) {
+		ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX;
+		ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
+		ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
+		ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
+		ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
+	} else {
+		ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
+		ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
+		ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
+	}
+
 	/* clear stats */
 	memset(&adapter->stats, 0, sizeof(adapter->stats));
 err_out:
@@ -2517,9 +2532,11 @@
 			case -ENOMEM:
 				dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n");
 				goto err_out_free_hw;
+			case -EOPNOTSUPP:
+				dev_err(&pdev->dev, "Adapter initialization failed\n");
+				goto err_out_free_hw;
 			default:
-				dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure\n");
-				dev_err(&pdev->dev, "If reboot does not help to recover from this failure, try a flash update of the adapter\n");
+				dev_err(&pdev->dev, "Adapter initialization failed. Driver will load in maintenance mode to recover the adapter using the application\n");
 				goto err_out_maintenance_mode;
 			}
 		}
@@ -2593,7 +2610,7 @@
 		qlcnic_alloc_lb_filters_mem(adapter);
 
 	qlcnic_add_sysfs(adapter);
-
+	qlcnic_register_hwmon_dev(adapter);
 	return 0;
 
 err_out_disable_mbx_intr:
@@ -2700,6 +2717,8 @@
 
 	qlcnic_remove_sysfs(adapter);
 
+	qlcnic_unregister_hwmon_dev(adapter);
+
 	qlcnic_cleanup_pci_map(adapter->ahw);
 
 	qlcnic_release_firmware(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index 2801379..c7926ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -16,6 +16,7 @@
 #define QLC_VF_FLOOD_BIT	BIT_16
 #define QLC_FLOOD_MODE		0x5
 #define QLC_SRIOV_ALLOW_VLAN0	BIT_19
+#define QLC_INTR_COAL_TYPE_MASK	0x7
 
 static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8);
 
@@ -1178,19 +1179,41 @@
 {
 	struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
 	u16 ctx_id, pkts, time;
+	int err = -EINVAL;
+	u8 type;
 
+	type = cmd->req.arg[1] & QLC_INTR_COAL_TYPE_MASK;
 	ctx_id = cmd->req.arg[1] >> 16;
 	pkts = cmd->req.arg[2] & 0xffff;
 	time = cmd->req.arg[2] >> 16;
 
-	if (ctx_id != vf->rx_ctx_id)
-		return -EINVAL;
-	if (pkts > coal->rx_packets)
-		return -EINVAL;
-	if (time < coal->rx_time_us)
-		return -EINVAL;
+	switch (type) {
+	case QLCNIC_INTR_COAL_TYPE_RX:
+		if (ctx_id != vf->rx_ctx_id || pkts > coal->rx_packets ||
+		    time < coal->rx_time_us)
+			goto err_label;
+		break;
+	case QLCNIC_INTR_COAL_TYPE_TX:
+		if (ctx_id != vf->tx_ctx_id || pkts > coal->tx_packets ||
+		    time < coal->tx_time_us)
+			goto err_label;
+		break;
+	default:
+		netdev_err(adapter->netdev, "Invalid coalescing type 0x%x received\n",
+			   type);
+		return err;
+	}
 
 	return 0;
+
+err_label:
+	netdev_err(adapter->netdev, "Expected: rx_ctx_id 0x%x rx_packets 0x%x rx_time_us 0x%x tx_ctx_id 0x%x tx_packets 0x%x tx_time_us 0x%x\n",
+		   vf->rx_ctx_id, coal->rx_packets, coal->rx_time_us,
+		   vf->tx_ctx_id, coal->tx_packets, coal->tx_time_us);
+	netdev_err(adapter->netdev, "Received: ctx_id 0x%x packets 0x%x time_us 0x%x type 0x%x\n",
+		   ctx_id, pkts, time, type);
+
+	return err;
 }
 
 static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index cd346e2..f5786d5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -19,6 +19,10 @@
 #include <linux/sysfs.h>
 #include <linux/aer.h>
 #include <linux/log2.h>
+#ifdef CONFIG_QLCNIC_HWMON
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#endif
 
 #define QLC_STATUS_UNSUPPORTED_CMD	-2
 
@@ -358,6 +362,8 @@
 		if (adapter->npars[i].pci_func == pci_func)
 			return i;
 	}
+
+	dev_err(&adapter->pdev->dev, "%s: Invalid nic function\n", __func__);
 	return -EINVAL;
 }
 
@@ -1243,6 +1249,68 @@
 	.write = qlcnic_83xx_sysfs_flash_write_handler,
 };
 
+#ifdef CONFIG_QLCNIC_HWMON
+
+static ssize_t qlcnic_hwmon_show_temp(struct device *dev,
+				      struct device_attribute *dev_attr,
+				      char *buf)
+{
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	unsigned int temperature = 0, value = 0;
+
+	if (qlcnic_83xx_check(adapter))
+		value = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP);
+	else if (qlcnic_82xx_check(adapter))
+		value = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP);
+
+	temperature = qlcnic_get_temp_val(value);
+	/* display millidegree celcius */
+	temperature *= 1000;
+	return sprintf(buf, "%u\n", temperature);
+}
+
+/* hwmon-sysfs attributes */
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+			  qlcnic_hwmon_show_temp, NULL, 1);
+
+static struct attribute *qlcnic_hwmon_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	NULL
+};
+
+ATTRIBUTE_GROUPS(qlcnic_hwmon);
+
+void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+	struct device *dev = &adapter->pdev->dev;
+	struct device *hwmon_dev;
+
+	/* Skip hwmon registration for a VF device */
+	if (qlcnic_sriov_vf_check(adapter)) {
+		adapter->ahw->hwmon_dev = NULL;
+		return;
+	}
+	hwmon_dev = hwmon_device_register_with_groups(dev, qlcnic_driver_name,
+						      adapter,
+						      qlcnic_hwmon_groups);
+	if (IS_ERR(hwmon_dev)) {
+		dev_err(dev, "Cannot register with hwmon, err=%ld\n",
+			PTR_ERR(hwmon_dev));
+		hwmon_dev = NULL;
+	}
+	adapter->ahw->hwmon_dev = hwmon_dev;
+}
+
+void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+	struct device *hwmon_dev = adapter->ahw->hwmon_dev;
+	if (hwmon_dev) {
+		hwmon_device_unregister(hwmon_dev);
+		adapter->ahw->hwmon_dev = NULL;
+	}
+}
+#endif
+
 void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 0a1d76ac..6e36fe1 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -3595,7 +3595,7 @@
 	}
 	return status;
 err_irq:
-	netif_err(qdev, ifup, qdev->ndev, "Failed to get the interrupts!!!/n");
+	netif_err(qdev, ifup, qdev->ndev, "Failed to get the interrupts!!!\n");
 	ql_free_irq(qdev);
 	return status;
 }
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c
index e896dbb..d71691b 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c
@@ -45,10 +45,10 @@
 	p->tdes23.tx_rd_des23.first_desc = is_fd;
 	p->tdes23.tx_rd_des23.buf1_size = buf1_len;
 
-	p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.total_pkt_len = pkt_len;
+	p->tdes23.tx_rd_des23.tx_pkt_len.pkt_len.total_pkt_len = pkt_len;
 
 	if (cksum)
-		p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.cksum_ctl = cic_full;
+		p->tdes23.tx_rd_des23.cksum_ctl = cic_full;
 }
 
 /* Set VLAN control information */
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h
index 838cb9f..0226300 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h
@@ -39,22 +39,22 @@
 			u32 int_on_com:1;
 			/* TDES3 */
 			union {
-				u32 tcp_payload_len:18;
+				u16 tcp_payload_len;
 				struct {
 					u32 total_pkt_len:15;
 					u32 reserved1:1;
-					u32 cksum_ctl:2;
-				} cksum_pktlen;
+				} pkt_len;
 			} tx_pkt_len;
 
-			u32 tse_bit:1;
-			u32 tcp_hdr_len:4;
-			u32 sa_insert_ctl:3;
-			u32 crc_pad_ctl:2;
-			u32 last_desc:1;
-			u32 first_desc:1;
-			u32 ctxt_bit:1;
-			u32 own_bit:1;
+			u16 cksum_ctl:2;
+			u16 tse_bit:1;
+			u16 tcp_hdr_len:4;
+			u16 sa_insert_ctl:3;
+			u16 crc_pad_ctl:2;
+			u16 last_desc:1;
+			u16 first_desc:1;
+			u16 ctxt_bit:1;
+			u16 own_bit:1;
 		} tx_rd_des23;
 
 		/* tx write back Desc 2,3 */
@@ -70,25 +70,20 @@
 
 struct sxgbe_rx_norm_desc {
 	union {
-		u32 rdes0; /* buf1 address */
-		struct {
+		u64 rdes01; /* buf1 address */
+		union {
 			u32 out_vlan_tag:16;
 			u32 in_vlan_tag:16;
-		} wb_rx_des0;
-	} rd_wb_des0;
-
-	union {
-		u32 rdes1;	/* buf2 address or buf1[63:32] */
-		u32 rss_hash;	/* Write-back RX */
-	} rd_wb_des1;
+			u32 rss_hash;
+		} rx_wb_des01;
+	} rdes01;
 
 	union {
 		/* RX Read format Desc 2,3 */
 		struct{
 			/* RDES2 */
-			u32 buf2_addr;
+			u64 buf2_addr:62;
 			/* RDES3 */
-			u32 buf2_hi_addr:30;
 			u32 int_on_com:1;
 			u32 own_bit:1;
 		} rx_rd_des23;
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 27e8c82..137f366 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -425,8 +425,8 @@
  * @rx_rsize: ring size
  * Description:  this function initializes the DMA RX descriptor
  */
-void free_rx_ring(struct device *dev, struct sxgbe_rx_queue *rx_ring,
-		  int rx_rsize)
+static void free_rx_ring(struct device *dev, struct sxgbe_rx_queue *rx_ring,
+			 int rx_rsize)
 {
 	dma_free_coherent(dev, rx_rsize * sizeof(struct sxgbe_rx_norm_desc),
 			  rx_ring->dma_rx, rx_ring->dma_rx_phy);
@@ -519,8 +519,8 @@
  * @tx_rsize: ring size
  * Description:  this function initializes the DMA TX descriptor
  */
-void free_tx_ring(struct device *dev, struct sxgbe_tx_queue *tx_ring,
-		  int tx_rsize)
+static void free_tx_ring(struct device *dev, struct sxgbe_tx_queue *tx_ring,
+			 int tx_rsize)
 {
 	dma_free_coherent(dev, tx_rsize * sizeof(struct sxgbe_tx_norm_desc),
 			  tx_ring->dma_tx, tx_ring->dma_tx_phy);
@@ -1218,11 +1218,10 @@
 
 	return 0;
 }
-
 /* Prepare first Tx descriptor for doing TSO operation */
-void sxgbe_tso_prepare(struct sxgbe_priv_data *priv,
-		       struct sxgbe_tx_norm_desc *first_desc,
-		       struct sk_buff *skb)
+static void sxgbe_tso_prepare(struct sxgbe_priv_data *priv,
+			      struct sxgbe_tx_norm_desc *first_desc,
+			      struct sk_buff *skb)
 {
 	unsigned int total_hdr_len, tcp_hdr_len;
 
@@ -1910,40 +1909,6 @@
 		   readl(ioaddr + SXGBE_HASH_LOW));
 }
 
-/**
- * sxgbe_config - entry point for changing configuration mode passed on by
- * ifconfig
- * @dev : pointer to the device structure
- * @map : pointer to the device mapping structure
- * Description:
- * This function is a driver entry point which gets called by the kernel
- * whenever some device configuration is changed.
- * Return value:
- * This function returns 0 if success and appropriate error otherwise.
- */
-static int sxgbe_config(struct net_device *dev, struct ifmap *map)
-{
-	struct sxgbe_priv_data *priv = netdev_priv(dev);
-
-	/* Can't act on a running interface */
-	if (dev->flags & IFF_UP)
-		return -EBUSY;
-
-	/* Don't allow changing the I/O address */
-	if (map->base_addr != (unsigned long)priv->ioaddr) {
-		netdev_warn(dev, "can't change I/O address\n");
-		return -EOPNOTSUPP;
-	}
-
-	/* Don't allow changing the IRQ */
-	if (map->irq != priv->irq) {
-		netdev_warn(dev, "not change IRQ number %d\n", priv->irq);
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /**
  * sxgbe_poll_controller - entry point for polling receive by device
@@ -2005,7 +1970,6 @@
 	.ndo_set_rx_mode	= sxgbe_set_rx_mode,
 	.ndo_tx_timeout		= sxgbe_tx_timeout,
 	.ndo_do_ioctl		= sxgbe_ioctl,
-	.ndo_set_config		= sxgbe_config,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= sxgbe_poll_controller,
 #endif
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c
index 01af2cb..43ccb4a 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c
@@ -27,7 +27,7 @@
 #define SXGBE_SMA_PREAD_CMD	0x02 /* post read  increament address */
 #define SXGBE_SMA_READ_CMD	0x03 /* read command */
 #define SXGBE_SMA_SKIP_ADDRFRM	0x00040000 /* skip the address frame */
-#define SXGBE_MII_BUSY		0x00800000 /* mii busy */
+#define SXGBE_MII_BUSY		0x00400000 /* mii busy */
 
 static int sxgbe_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_data)
 {
@@ -147,6 +147,7 @@
 	struct sxgbe_mdio_bus_data *mdio_data = priv->plat->mdio_bus_data;
 	int err, phy_addr;
 	int *irqlist;
+	bool phy_found = false;
 	bool act;
 
 	/* allocate the new mdio bus */
@@ -162,7 +163,7 @@
 		irqlist = priv->mii_irq;
 
 	/* assign mii bus fields */
-	mdio_bus->name = "samsxgbe";
+	mdio_bus->name = "sxgbe";
 	mdio_bus->read = &sxgbe_mdio_read;
 	mdio_bus->write = &sxgbe_mdio_write;
 	snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%x",
@@ -216,13 +217,22 @@
 			netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n",
 				    phy->phy_id, phy_addr, irq_str,
 				    dev_name(&phy->dev), act ? " active" : "");
+			phy_found = true;
 		}
 	}
 
+	if (!phy_found) {
+		netdev_err(ndev, "PHY not found\n");
+		goto phyfound_err;
+	}
+
 	priv->mii = mdio_bus;
 
 	return 0;
 
+phyfound_err:
+	err = -ENODEV;
+	mdiobus_unregister(mdio_bus);
 mdiobus_err:
 	mdiobus_free(mdio_bus);
 	return err;
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index d1b4dca..bcaa41a 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -147,18 +147,19 @@
  */
 #define MII_DELAY		1
 
-#if SMC_DEBUG > 0
-#define DBG(n, dev, args...)				\
-	do {						\
-		if (SMC_DEBUG >= (n))			\
-			netdev_dbg(dev, args);		\
+#define DBG(n, dev, fmt, ...)					\
+	do {							\
+		if (SMC_DEBUG >= (n))				\
+			netdev_dbg(dev, fmt, ##__VA_ARGS__);	\
 	} while (0)
 
-#define PRINTK(dev, args...)   netdev_info(dev, args)
-#else
-#define DBG(n, dev, args...)   do { } while (0)
-#define PRINTK(dev, args...)   netdev_dbg(dev, args)
-#endif
+#define PRINTK(dev, fmt, ...)					\
+	do {							\
+		if (SMC_DEBUG > 0)				\
+			netdev_info(dev, fmt, ##__VA_ARGS__);	\
+		else						\
+			netdev_dbg(dev, fmt, ##__VA_ARGS__);	\
+	} while (0)
 
 #if SMC_DEBUG > 3
 static void PRINT_PKT(u_char *buf, int length)
@@ -191,7 +192,7 @@
 	pr_cont("\n");
 }
 #else
-#define PRINT_PKT(x...)  do { } while (0)
+static inline void PRINT_PKT(u_char *buf, int length) { }
 #endif
 
 
@@ -1781,7 +1782,7 @@
 	int timeout = 20;
 	unsigned long cookie;
 
-	DBG(2, dev, "%s: %s\n", CARDNAME, __func__);
+	DBG(2, lp->dev, "%s: %s\n", CARDNAME, __func__);
 
 	cookie = probe_irq_on();
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d940034..93cf4f6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2214,27 +2214,6 @@
 	stmmac_tx_err(priv);
 }
 
-/* Configuration changes (passed on by ifconfig) */
-static int stmmac_config(struct net_device *dev, struct ifmap *map)
-{
-	if (dev->flags & IFF_UP)	/* can't act on a running interface */
-		return -EBUSY;
-
-	/* Don't allow changing the I/O address */
-	if (map->base_addr != dev->base_addr) {
-		pr_warn("%s: can't change I/O address\n", dev->name);
-		return -EOPNOTSUPP;
-	}
-
-	/* Don't allow changing the IRQ */
-	if (map->irq != dev->irq) {
-		pr_warn("%s: not change IRQ number %d\n", dev->name, dev->irq);
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
 /**
  *  stmmac_set_rx_mode - entry point for multicast addressing
  *  @dev : pointer to the device structure
@@ -2600,7 +2579,6 @@
 	.ndo_set_rx_mode = stmmac_set_rx_mode,
 	.ndo_tx_timeout = stmmac_tx_timeout,
 	.ndo_do_ioctl = stmmac_ioctl,
-	.ndo_set_config = stmmac_config,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = stmmac_poll_controller,
 #endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index a468eb1..a5b1e1b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -205,10 +205,13 @@
 	if (new_bus == NULL)
 		return -ENOMEM;
 
-	if (mdio_bus_data->irqs)
+	if (mdio_bus_data->irqs) {
 		irqlist = mdio_bus_data->irqs;
-	else
+	} else {
+		for (addr = 0; addr < PHY_MAX_ADDR; addr++)
+			priv->mii_irq[addr] = PHY_POLL;
 		irqlist = priv->mii_irq;
+	}
 
 #ifdef CONFIG_OF
 	if (priv->device->of_node)
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 73f74f3..7399a52 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -313,19 +313,6 @@
 
 static struct mii_bus *cpmac_mii;
 
-static int cpmac_config(struct net_device *dev, struct ifmap *map)
-{
-	if (dev->flags & IFF_UP)
-		return -EBUSY;
-
-	/* Don't allow changing the I/O address */
-	if (map->base_addr != dev->base_addr)
-		return -EOPNOTSUPP;
-
-	/* ignore other fields */
-	return 0;
-}
-
 static void cpmac_set_multicast_list(struct net_device *dev)
 {
 	struct netdev_hw_addr *ha;
@@ -1100,7 +1087,6 @@
 	.ndo_tx_timeout		= cpmac_tx_timeout,
 	.ndo_set_rx_mode	= cpmac_set_multicast_list,
 	.ndo_do_ioctl		= cpmac_ioctl,
-	.ndo_set_config		= cpmac_config,
 	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= eth_mac_addr,
diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig
index 8a049a2..f66ddae 100644
--- a/drivers/net/ethernet/via/Kconfig
+++ b/drivers/net/ethernet/via/Kconfig
@@ -19,7 +19,7 @@
 
 config VIA_RHINE
 	tristate "VIA Rhine support"
-	depends on PCI
+	depends on (PCI || USE_OF)
 	select CRC32
 	select MII
 	---help---
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index f61dc2b..4fa9201 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -94,6 +94,10 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -279,6 +283,15 @@
 };
 MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
 
+/* OpenFirmware identifiers for platform-bus devices
+ * The .data field is currently only used to store chip revision
+ * (for quirks etc.)
+ */
+static struct of_device_id rhine_of_tbl[] = {
+	{ .compatible = "via,vt8500-rhine", .data = (void *)0x84 },
+	{ }	/* terminate list */
+};
+MODULE_DEVICE_TABLE(of, rhine_of_tbl);
 
 /* Offsets to the device registers. */
 enum register_offsets {
@@ -446,7 +459,8 @@
 	unsigned char *tx_bufs;
 	dma_addr_t tx_bufs_dma;
 
-	struct pci_dev *pdev;
+	int revision;
+	int irq;
 	long pioaddr;
 	struct net_device *dev;
 	struct napi_struct napi;
@@ -701,7 +715,7 @@
 static void rhine_poll(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-	const int irq = rp->pdev->irq;
+	const int irq = rp->irq;
 
 	disable_irq(irq);
 	rhine_interrupt(irq, dev);
@@ -846,7 +860,8 @@
 		msleep(5);
 
 	/* Reload EEPROM controlled bytes cleared by soft reset */
-	rhine_reload_eeprom(pioaddr, dev);
+	if (dev_is_pci(dev->dev.parent))
+		rhine_reload_eeprom(pioaddr, dev);
 }
 
 static const struct net_device_ops rhine_netdev_ops = {
@@ -867,126 +882,56 @@
 #endif
 };
 
-static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int rhine_init_one_common(struct device *hwdev, int revision,
+				 long pioaddr, void __iomem *ioaddr, int irq)
 {
 	struct net_device *dev;
 	struct rhine_private *rp;
-	int i, rc;
-	u32 quirks;
-	long pioaddr;
-	long memaddr;
-	void __iomem *ioaddr;
-	int io_size, phy_id;
+	int i, rc, phy_id;
 	const char *name;
-#ifdef USE_MMIO
-	int bar = 1;
-#else
-	int bar = 0;
-#endif
 
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
-	pr_info_once("%s\n", version);
-#endif
-
-	io_size = 256;
-	phy_id = 0;
-	quirks = 0;
-	name = "Rhine";
-	if (pdev->revision < VTunknown0) {
-		quirks = rqRhineI;
-		io_size = 128;
+	/* this should always be supported */
+	rc = dma_set_mask(hwdev, DMA_BIT_MASK(32));
+	if (rc) {
+		dev_err(hwdev, "32-bit DMA addresses not supported by the card!?\n");
+		goto err_out;
 	}
-	else if (pdev->revision >= VT6102) {
-		quirks = rqWOL | rqForceReset;
-		if (pdev->revision < VT6105) {
+
+	dev = alloc_etherdev(sizeof(struct rhine_private));
+	if (!dev) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	SET_NETDEV_DEV(dev, hwdev);
+
+	rp = netdev_priv(dev);
+	rp->dev = dev;
+	rp->revision = revision;
+	rp->pioaddr = pioaddr;
+	rp->base = ioaddr;
+	rp->irq = irq;
+	rp->msg_enable = netif_msg_init(debug, RHINE_MSG_DEFAULT);
+
+	phy_id = 0;
+	name = "Rhine";
+	if (revision < VTunknown0) {
+		rp->quirks = rqRhineI;
+	} else if (revision >= VT6102) {
+		rp->quirks = rqWOL | rqForceReset;
+		if (revision < VT6105) {
 			name = "Rhine II";
-			quirks |= rqStatusWBRace;	/* Rhine-II exclusive */
-		}
-		else {
+			rp->quirks |= rqStatusWBRace;	/* Rhine-II exclusive */
+		} else {
 			phy_id = 1;	/* Integrated PHY, phy_id fixed to 1 */
-			if (pdev->revision >= VT6105_B0)
-				quirks |= rq6patterns;
-			if (pdev->revision < VT6105M)
+			if (revision >= VT6105_B0)
+				rp->quirks |= rq6patterns;
+			if (revision < VT6105M)
 				name = "Rhine III";
 			else
 				name = "Rhine III (Management Adapter)";
 		}
 	}
 
-	rc = pci_enable_device(pdev);
-	if (rc)
-		goto err_out;
-
-	/* this should always be supported */
-	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-	if (rc) {
-		dev_err(&pdev->dev,
-			"32-bit PCI DMA addresses not supported by the card!?\n");
-		goto err_out_pci_disable;
-	}
-
-	/* sanity check */
-	if ((pci_resource_len(pdev, 0) < io_size) ||
-	    (pci_resource_len(pdev, 1) < io_size)) {
-		rc = -EIO;
-		dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n");
-		goto err_out_pci_disable;
-	}
-
-	pioaddr = pci_resource_start(pdev, 0);
-	memaddr = pci_resource_start(pdev, 1);
-
-	pci_set_master(pdev);
-
-	dev = alloc_etherdev(sizeof(struct rhine_private));
-	if (!dev) {
-		rc = -ENOMEM;
-		goto err_out_pci_disable;
-	}
-	SET_NETDEV_DEV(dev, &pdev->dev);
-
-	rp = netdev_priv(dev);
-	rp->dev = dev;
-	rp->quirks = quirks;
-	rp->pioaddr = pioaddr;
-	rp->pdev = pdev;
-	rp->msg_enable = netif_msg_init(debug, RHINE_MSG_DEFAULT);
-
-	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
-		goto err_out_free_netdev;
-
-	ioaddr = pci_iomap(pdev, bar, io_size);
-	if (!ioaddr) {
-		rc = -EIO;
-		dev_err(&pdev->dev,
-			"ioremap failed for device %s, region 0x%X @ 0x%lX\n",
-			pci_name(pdev), io_size, memaddr);
-		goto err_out_free_res;
-	}
-
-#ifdef USE_MMIO
-	enable_mmio(pioaddr, quirks);
-
-	/* Check that selected MMIO registers match the PIO ones */
-	i = 0;
-	while (mmio_verify_registers[i]) {
-		int reg = mmio_verify_registers[i++];
-		unsigned char a = inb(pioaddr+reg);
-		unsigned char b = readb(ioaddr+reg);
-		if (a != b) {
-			rc = -EIO;
-			dev_err(&pdev->dev,
-				"MMIO do not match PIO [%02x] (%02x != %02x)\n",
-				reg, a, b);
-			goto err_out_unmap;
-		}
-	}
-#endif /* USE_MMIO */
-
-	rp->base = ioaddr;
-
 	u64_stats_init(&rp->tx_stats.syncp);
 	u64_stats_init(&rp->rx_stats.syncp);
 
@@ -1030,7 +975,7 @@
 	if (rp->quirks & rqRhineI)
 		dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
 
-	if (pdev->revision >= VT6105M)
+	if (rp->revision >= VT6105M)
 		dev->features |= NETIF_F_HW_VLAN_CTAG_TX |
 				 NETIF_F_HW_VLAN_CTAG_RX |
 				 NETIF_F_HW_VLAN_CTAG_FILTER;
@@ -1038,18 +983,12 @@
 	/* dev->name not defined before register_netdev()! */
 	rc = register_netdev(dev);
 	if (rc)
-		goto err_out_unmap;
+		goto err_out_free_netdev;
 
 	netdev_info(dev, "VIA %s at 0x%lx, %pM, IRQ %d\n",
-		    name,
-#ifdef USE_MMIO
-		    memaddr,
-#else
-		    (long)ioaddr,
-#endif
-		    dev->dev_addr, pdev->irq);
+		    name, (long)ioaddr, dev->dev_addr, rp->irq);
 
-	pci_set_drvdata(pdev, dev);
+	dev_set_drvdata(hwdev, dev);
 
 	{
 		u16 mii_cmd;
@@ -1078,41 +1017,152 @@
 
 	return 0;
 
+err_out_free_netdev:
+	free_netdev(dev);
+err_out:
+	return rc;
+}
+
+static int rhine_init_one_pci(struct pci_dev *pdev,
+			      const struct pci_device_id *ent)
+{
+	struct device *hwdev = &pdev->dev;
+	int i, rc;
+	long pioaddr, memaddr;
+	void __iomem *ioaddr;
+	int io_size = pdev->revision < VTunknown0 ? 128 : 256;
+	u32 quirks = pdev->revision < VTunknown0 ? rqRhineI : 0;
+#ifdef USE_MMIO
+	int bar = 1;
+#else
+	int bar = 0;
+#endif
+
+/* when built into the kernel, we only print version if device is found */
+#ifndef MODULE
+	pr_info_once("%s\n", version);
+#endif
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		goto err_out;
+
+	/* sanity check */
+	if ((pci_resource_len(pdev, 0) < io_size) ||
+	    (pci_resource_len(pdev, 1) < io_size)) {
+		rc = -EIO;
+		dev_err(hwdev, "Insufficient PCI resources, aborting\n");
+		goto err_out_pci_disable;
+	}
+
+	pioaddr = pci_resource_start(pdev, 0);
+	memaddr = pci_resource_start(pdev, 1);
+
+	pci_set_master(pdev);
+
+	rc = pci_request_regions(pdev, DRV_NAME);
+	if (rc)
+		goto err_out_pci_disable;
+
+	ioaddr = pci_iomap(pdev, bar, io_size);
+	if (!ioaddr) {
+		rc = -EIO;
+		dev_err(hwdev,
+			"ioremap failed for device %s, region 0x%X @ 0x%lX\n",
+			dev_name(hwdev), io_size, memaddr);
+		goto err_out_free_res;
+	}
+
+#ifdef USE_MMIO
+	enable_mmio(pioaddr, quirks);
+
+	/* Check that selected MMIO registers match the PIO ones */
+	i = 0;
+	while (mmio_verify_registers[i]) {
+		int reg = mmio_verify_registers[i++];
+		unsigned char a = inb(pioaddr+reg);
+		unsigned char b = readb(ioaddr+reg);
+
+		if (a != b) {
+			rc = -EIO;
+			dev_err(hwdev,
+				"MMIO do not match PIO [%02x] (%02x != %02x)\n",
+				reg, a, b);
+			goto err_out_unmap;
+		}
+	}
+#endif /* USE_MMIO */
+
+	rc = rhine_init_one_common(&pdev->dev, pdev->revision,
+				   pioaddr, ioaddr, pdev->irq);
+	if (!rc)
+		return 0;
+
 err_out_unmap:
 	pci_iounmap(pdev, ioaddr);
 err_out_free_res:
 	pci_release_regions(pdev);
-err_out_free_netdev:
-	free_netdev(dev);
 err_out_pci_disable:
 	pci_disable_device(pdev);
 err_out:
 	return rc;
 }
 
+static int rhine_init_one_platform(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	u32 revision;
+	int irq;
+	struct resource *res;
+	void __iomem *ioaddr;
+
+	match = of_match_device(rhine_of_tbl, &pdev->dev);
+	if (!match)
+		return -EINVAL;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ioaddr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ioaddr))
+		return PTR_ERR(ioaddr);
+
+	irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (!irq)
+		return -EINVAL;
+
+	revision = (u32)match->data;
+	if (!revision)
+		return -EINVAL;
+
+	return rhine_init_one_common(&pdev->dev, revision,
+				     (long)ioaddr, ioaddr, irq);
+}
+
 static int alloc_ring(struct net_device* dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 	void *ring;
 	dma_addr_t ring_dma;
 
-	ring = pci_alloc_consistent(rp->pdev,
-				    RX_RING_SIZE * sizeof(struct rx_desc) +
-				    TX_RING_SIZE * sizeof(struct tx_desc),
-				    &ring_dma);
+	ring = dma_alloc_coherent(hwdev,
+				  RX_RING_SIZE * sizeof(struct rx_desc) +
+				  TX_RING_SIZE * sizeof(struct tx_desc),
+				  &ring_dma,
+				  GFP_ATOMIC);
 	if (!ring) {
 		netdev_err(dev, "Could not allocate DMA memory\n");
 		return -ENOMEM;
 	}
 	if (rp->quirks & rqRhineI) {
-		rp->tx_bufs = pci_alloc_consistent(rp->pdev,
-						   PKT_BUF_SZ * TX_RING_SIZE,
-						   &rp->tx_bufs_dma);
+		rp->tx_bufs = dma_alloc_coherent(hwdev,
+						 PKT_BUF_SZ * TX_RING_SIZE,
+						 &rp->tx_bufs_dma,
+						 GFP_ATOMIC);
 		if (rp->tx_bufs == NULL) {
-			pci_free_consistent(rp->pdev,
-				    RX_RING_SIZE * sizeof(struct rx_desc) +
-				    TX_RING_SIZE * sizeof(struct tx_desc),
-				    ring, ring_dma);
+			dma_free_coherent(hwdev,
+					  RX_RING_SIZE * sizeof(struct rx_desc) +
+					  TX_RING_SIZE * sizeof(struct tx_desc),
+					  ring, ring_dma);
 			return -ENOMEM;
 		}
 	}
@@ -1128,16 +1178,17 @@
 static void free_ring(struct net_device* dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 
-	pci_free_consistent(rp->pdev,
-			    RX_RING_SIZE * sizeof(struct rx_desc) +
-			    TX_RING_SIZE * sizeof(struct tx_desc),
-			    rp->rx_ring, rp->rx_ring_dma);
+	dma_free_coherent(hwdev,
+			  RX_RING_SIZE * sizeof(struct rx_desc) +
+			  TX_RING_SIZE * sizeof(struct tx_desc),
+			  rp->rx_ring, rp->rx_ring_dma);
 	rp->tx_ring = NULL;
 
 	if (rp->tx_bufs)
-		pci_free_consistent(rp->pdev, PKT_BUF_SZ * TX_RING_SIZE,
-				    rp->tx_bufs, rp->tx_bufs_dma);
+		dma_free_coherent(hwdev, PKT_BUF_SZ * TX_RING_SIZE,
+				  rp->tx_bufs, rp->tx_bufs_dma);
 
 	rp->tx_bufs = NULL;
 
@@ -1146,6 +1197,7 @@
 static void alloc_rbufs(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 	dma_addr_t next;
 	int i;
 
@@ -1174,9 +1226,9 @@
 			break;
 
 		rp->rx_skbuff_dma[i] =
-			pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz,
-				       PCI_DMA_FROMDEVICE);
-		if (dma_mapping_error(&rp->pdev->dev, rp->rx_skbuff_dma[i])) {
+			dma_map_single(hwdev, skb->data, rp->rx_buf_sz,
+				       DMA_FROM_DEVICE);
+		if (dma_mapping_error(hwdev, rp->rx_skbuff_dma[i])) {
 			rp->rx_skbuff_dma[i] = 0;
 			dev_kfree_skb(skb);
 			break;
@@ -1190,6 +1242,7 @@
 static void free_rbufs(struct net_device* dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 	int i;
 
 	/* Free all the skbuffs in the Rx queue. */
@@ -1197,9 +1250,9 @@
 		rp->rx_ring[i].rx_status = 0;
 		rp->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
 		if (rp->rx_skbuff[i]) {
-			pci_unmap_single(rp->pdev,
+			dma_unmap_single(hwdev,
 					 rp->rx_skbuff_dma[i],
-					 rp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+					 rp->rx_buf_sz, DMA_FROM_DEVICE);
 			dev_kfree_skb(rp->rx_skbuff[i]);
 		}
 		rp->rx_skbuff[i] = NULL;
@@ -1230,6 +1283,7 @@
 static void free_tbufs(struct net_device* dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 	int i;
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
@@ -1238,10 +1292,10 @@
 		rp->tx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
 		if (rp->tx_skbuff[i]) {
 			if (rp->tx_skbuff_dma[i]) {
-				pci_unmap_single(rp->pdev,
+				dma_unmap_single(hwdev,
 						 rp->tx_skbuff_dma[i],
 						 rp->tx_skbuff[i]->len,
-						 PCI_DMA_TODEVICE);
+						 DMA_TO_DEVICE);
 			}
 			dev_kfree_skb(rp->tx_skbuff[i]);
 		}
@@ -1469,7 +1523,7 @@
 
 	rhine_set_rx_mode(dev);
 
-	if (rp->pdev->revision >= VT6105M)
+	if (rp->revision >= VT6105M)
 		rhine_init_cam_filter(dev);
 
 	napi_enable(&rp->napi);
@@ -1581,16 +1635,15 @@
 	void __iomem *ioaddr = rp->base;
 	int rc;
 
-	rc = request_irq(rp->pdev->irq, rhine_interrupt, IRQF_SHARED, dev->name,
-			dev);
+	rc = request_irq(rp->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev);
 	if (rc)
 		return rc;
 
-	netif_dbg(rp, ifup, dev, "%s() irq %d\n", __func__, rp->pdev->irq);
+	netif_dbg(rp, ifup, dev, "%s() irq %d\n", __func__, rp->irq);
 
 	rc = alloc_ring(dev);
 	if (rc) {
-		free_irq(rp->pdev->irq, dev);
+		free_irq(rp->irq, dev);
 		return rc;
 	}
 	alloc_rbufs(dev);
@@ -1659,6 +1712,7 @@
 				  struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 	void __iomem *ioaddr = rp->base;
 	unsigned entry;
 
@@ -1695,9 +1749,9 @@
 						       rp->tx_bufs));
 	} else {
 		rp->tx_skbuff_dma[entry] =
-			pci_map_single(rp->pdev, skb->data, skb->len,
-				       PCI_DMA_TODEVICE);
-		if (dma_mapping_error(&rp->pdev->dev, rp->tx_skbuff_dma[entry])) {
+			dma_map_single(hwdev, skb->data, skb->len,
+				       DMA_TO_DEVICE);
+		if (dma_mapping_error(hwdev, rp->tx_skbuff_dma[entry])) {
 			dev_kfree_skb_any(skb);
 			rp->tx_skbuff_dma[entry] = 0;
 			dev->stats.tx_dropped++;
@@ -1788,6 +1842,7 @@
 static void rhine_tx(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 	int txstatus = 0, entry = rp->dirty_tx % TX_RING_SIZE;
 
 	/* find and cleanup dirty tx descriptors */
@@ -1831,10 +1886,10 @@
 		}
 		/* Free the original skb. */
 		if (rp->tx_skbuff_dma[entry]) {
-			pci_unmap_single(rp->pdev,
+			dma_unmap_single(hwdev,
 					 rp->tx_skbuff_dma[entry],
 					 rp->tx_skbuff[entry]->len,
-					 PCI_DMA_TODEVICE);
+					 DMA_TO_DEVICE);
 		}
 		dev_consume_skb_any(rp->tx_skbuff[entry]);
 		rp->tx_skbuff[entry] = NULL;
@@ -1863,6 +1918,7 @@
 static int rhine_rx(struct net_device *dev, int limit)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 	int count;
 	int entry = rp->cur_rx % RX_RING_SIZE;
 
@@ -1924,19 +1980,19 @@
 			if (pkt_len < rx_copybreak)
 				skb = netdev_alloc_skb_ip_align(dev, pkt_len);
 			if (skb) {
-				pci_dma_sync_single_for_cpu(rp->pdev,
-							    rp->rx_skbuff_dma[entry],
-							    rp->rx_buf_sz,
-							    PCI_DMA_FROMDEVICE);
+				dma_sync_single_for_cpu(hwdev,
+							rp->rx_skbuff_dma[entry],
+							rp->rx_buf_sz,
+							DMA_FROM_DEVICE);
 
 				skb_copy_to_linear_data(skb,
 						 rp->rx_skbuff[entry]->data,
 						 pkt_len);
 				skb_put(skb, pkt_len);
-				pci_dma_sync_single_for_device(rp->pdev,
-							       rp->rx_skbuff_dma[entry],
-							       rp->rx_buf_sz,
-							       PCI_DMA_FROMDEVICE);
+				dma_sync_single_for_device(hwdev,
+							   rp->rx_skbuff_dma[entry],
+							   rp->rx_buf_sz,
+							   DMA_FROM_DEVICE);
 			} else {
 				skb = rp->rx_skbuff[entry];
 				if (skb == NULL) {
@@ -1945,10 +2001,10 @@
 				}
 				rp->rx_skbuff[entry] = NULL;
 				skb_put(skb, pkt_len);
-				pci_unmap_single(rp->pdev,
+				dma_unmap_single(hwdev,
 						 rp->rx_skbuff_dma[entry],
 						 rp->rx_buf_sz,
-						 PCI_DMA_FROMDEVICE);
+						 DMA_FROM_DEVICE);
 			}
 
 			if (unlikely(desc_length & DescTag))
@@ -1979,10 +2035,11 @@
 			if (skb == NULL)
 				break;	/* Better luck next round. */
 			rp->rx_skbuff_dma[entry] =
-				pci_map_single(rp->pdev, skb->data,
+				dma_map_single(hwdev, skb->data,
 					       rp->rx_buf_sz,
-					       PCI_DMA_FROMDEVICE);
-			if (dma_mapping_error(&rp->pdev->dev, rp->rx_skbuff_dma[entry])) {
+					       DMA_FROM_DEVICE);
+			if (dma_mapping_error(hwdev,
+					      rp->rx_skbuff_dma[entry])) {
 				dev_kfree_skb(skb);
 				rp->rx_skbuff_dma[entry] = 0;
 				break;
@@ -2103,7 +2160,7 @@
 		/* Too many to match, or accept all multicasts. */
 		iowrite32(0xffffffff, ioaddr + MulticastFilter0);
 		iowrite32(0xffffffff, ioaddr + MulticastFilter1);
-	} else if (rp->pdev->revision >= VT6105M) {
+	} else if (rp->revision >= VT6105M) {
 		int i = 0;
 		u32 mCAMmask = 0;	/* 32 mCAMs (6105M and better) */
 		netdev_for_each_mc_addr(ha, dev) {
@@ -2125,7 +2182,7 @@
 		iowrite32(mc_filter[1], ioaddr + MulticastFilter1);
 	}
 	/* enable/disable VLAN receive filtering */
-	if (rp->pdev->revision >= VT6105M) {
+	if (rp->revision >= VT6105M) {
 		if (dev->flags & IFF_PROMISC)
 			BYTE_REG_BITS_OFF(BCR1_VIDFR, ioaddr + PCIBusConfig1);
 		else
@@ -2136,11 +2193,11 @@
 
 static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	struct rhine_private *rp = netdev_priv(dev);
+	struct device *hwdev = dev->dev.parent;
 
 	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
 	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-	strlcpy(info->bus_info, pci_name(rp->pdev), sizeof(info->bus_info));
+	strlcpy(info->bus_info, dev_name(hwdev), sizeof(info->bus_info));
 }
 
 static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -2277,7 +2334,7 @@
 	/* Stop the chip's Tx and Rx processes. */
 	iowrite16(CmdStop, ioaddr + ChipCmd);
 
-	free_irq(rp->pdev->irq, dev);
+	free_irq(rp->irq, dev);
 	free_rbufs(dev);
 	free_tbufs(dev);
 	free_ring(dev);
@@ -2286,7 +2343,7 @@
 }
 
 
-static void rhine_remove_one(struct pci_dev *pdev)
+static void rhine_remove_one_pci(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
@@ -2300,7 +2357,21 @@
 	pci_disable_device(pdev);
 }
 
-static void rhine_shutdown (struct pci_dev *pdev)
+static int rhine_remove_one_platform(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct rhine_private *rp = netdev_priv(dev);
+
+	unregister_netdev(dev);
+
+	iounmap(rp->base);
+
+	free_netdev(dev);
+
+	return 0;
+}
+
+static void rhine_shutdown_pci(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
@@ -2354,8 +2425,7 @@
 #ifdef CONFIG_PM_SLEEP
 static int rhine_suspend(struct device *device)
 {
-	struct pci_dev *pdev = to_pci_dev(device);
-	struct net_device *dev = pci_get_drvdata(pdev);
+	struct net_device *dev = dev_get_drvdata(device);
 	struct rhine_private *rp = netdev_priv(dev);
 
 	if (!netif_running(dev))
@@ -2367,15 +2437,15 @@
 
 	netif_device_detach(dev);
 
-	rhine_shutdown(pdev);
+	if (dev_is_pci(device))
+		rhine_shutdown_pci(to_pci_dev(device));
 
 	return 0;
 }
 
 static int rhine_resume(struct device *device)
 {
-	struct pci_dev *pdev = to_pci_dev(device);
-	struct net_device *dev = pci_get_drvdata(pdev);
+	struct net_device *dev = dev_get_drvdata(device);
 	struct rhine_private *rp = netdev_priv(dev);
 
 	if (!netif_running(dev))
@@ -2408,15 +2478,26 @@
 
 #endif /* !CONFIG_PM_SLEEP */
 
-static struct pci_driver rhine_driver = {
+static struct pci_driver rhine_driver_pci = {
 	.name		= DRV_NAME,
 	.id_table	= rhine_pci_tbl,
-	.probe		= rhine_init_one,
-	.remove		= rhine_remove_one,
-	.shutdown	= rhine_shutdown,
+	.probe		= rhine_init_one_pci,
+	.remove		= rhine_remove_one_pci,
+	.shutdown	= rhine_shutdown_pci,
 	.driver.pm	= RHINE_PM_OPS,
 };
 
+static struct platform_driver rhine_driver_platform = {
+	.probe		= rhine_init_one_platform,
+	.remove		= rhine_remove_one_platform,
+	.driver = {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table	= rhine_of_tbl,
+		.pm		= RHINE_PM_OPS,
+	}
+};
+
 static struct dmi_system_id rhine_dmi_table[] __initdata = {
 	{
 		.ident = "EPIA-M",
@@ -2437,6 +2518,8 @@
 
 static int __init rhine_init(void)
 {
+	int ret_pci, ret_platform;
+
 /* when a module, this is printed whether or not devices are found in probe */
 #ifdef MODULE
 	pr_info("%s\n", version);
@@ -2449,13 +2532,19 @@
 	else if (avoid_D3)
 		pr_info("avoid_D3 set\n");
 
-	return pci_register_driver(&rhine_driver);
+	ret_pci = pci_register_driver(&rhine_driver_pci);
+	ret_platform = platform_driver_register(&rhine_driver_platform);
+	if ((ret_pci < 0) && (ret_platform < 0))
+		return ret_pci;
+
+	return 0;
 }
 
 
 static void __exit rhine_cleanup(void)
 {
-	pci_unregister_driver(&rhine_driver);
+	platform_driver_unregister(&rhine_driver_platform);
+	pci_unregister_driver(&rhine_driver_pci);
 }
 
 
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index d18f711d..4b7df5a 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -28,50 +28,119 @@
 #include <linux/hyperv.h>
 #include <linux/rndis.h>
 
-/* Fwd declaration */
-struct hv_netvsc_packet;
-struct ndis_tcp_ip_checksum_info;
+/* RSS related */
+#define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203  /* query only */
+#define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204  /* query and set */
 
-/* Represent the xfer page packet which contains 1 or more netvsc packet */
-struct xferpage_packet {
-	struct list_head list_ent;
-	u32 status;
+#define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88
+#define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89
 
-	/* # of netvsc packets this xfer packet contains */
-	u32 count;
+#define NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2
+#define NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2
+
+struct ndis_obj_header {
+	u8 type;
+	u8 rev;
+	u16 size;
+} __packed;
+
+/* ndis_recv_scale_cap/cap_flag */
+#define NDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000
+#define NDIS_RSS_CAPS_CLASSIFICATION_AT_ISR       0x02000000
+#define NDIS_RSS_CAPS_CLASSIFICATION_AT_DPC       0x04000000
+#define NDIS_RSS_CAPS_USING_MSI_X                 0x08000000
+#define NDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS      0x10000000
+#define NDIS_RSS_CAPS_SUPPORTS_MSI_X              0x20000000
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4          0x00000100
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6          0x00000200
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX       0x00000400
+
+struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */
+	struct ndis_obj_header hdr;
+	u32 cap_flag;
+	u32 num_int_msg;
+	u32 num_recv_que;
+	u16 num_indirect_tabent;
+} __packed;
+
+
+/* ndis_recv_scale_param flags */
+#define NDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED     0x0001
+#define NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED    0x0002
+#define NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED       0x0004
+#define NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED     0x0008
+#define NDIS_RSS_PARAM_FLAG_DISABLE_RSS            0x0010
+
+/* Hash info bits */
+#define NDIS_HASH_FUNC_TOEPLITZ 0x00000001
+#define NDIS_HASH_IPV4          0x00000100
+#define NDIS_HASH_TCP_IPV4      0x00000200
+#define NDIS_HASH_IPV6          0x00000400
+#define NDIS_HASH_IPV6_EX       0x00000800
+#define NDIS_HASH_TCP_IPV6      0x00001000
+#define NDIS_HASH_TCP_IPV6_EX   0x00002000
+
+#define NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4)
+#define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2   40
+
+#define ITAB_NUM 128
+#define HASH_KEYLEN NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2
+extern u8 netvsc_hash_key[];
+
+struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
+	struct ndis_obj_header hdr;
+
+	/* Qualifies the rest of the information */
+	u16 flag;
+
+	/* The base CPU number to do receive processing. not used */
+	u16 base_cpu_number;
+
+	/* This describes the hash function and type being enabled */
+	u32 hashinfo;
+
+	/* The size of indirection table array */
+	u16 indirect_tabsize;
+
+	/* The offset of the indirection table from the beginning of this
+	 * structure
+	 */
+	u32 indirect_taboffset;
+
+	/* The size of the hash secret key */
+	u16 hashkey_size;
+
+	/* The offset of the secret key from the beginning of this structure */
+	u32 kashkey_offset;
+
+	u32 processor_masks_offset;
+	u32 num_processor_masks;
+	u32 processor_masks_entry_size;
 };
 
+/* Fwd declaration */
+struct ndis_tcp_ip_checksum_info;
+
 /*
  * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
  * within the RNDIS
  */
 struct hv_netvsc_packet {
 	/* Bookkeeping stuff */
-	struct list_head list_ent;
 	u32 status;
 
 	struct hv_device *device;
 	bool is_data_pkt;
 	u16 vlan_tci;
 
-	/*
-	 * Valid only for receives when we break a xfer page packet
-	 * into multiple netvsc packets
-	 */
-	struct xferpage_packet *xfer_page_pkt;
+	u16 q_idx;
+	struct vmbus_channel *channel;
 
-	union {
-		struct {
-			u64 recv_completion_tid;
-			void *recv_completion_ctx;
-			void (*recv_completion)(void *context);
-		} recv;
-		struct {
-			u64 send_completion_tid;
-			void *send_completion_ctx;
-			void (*send_completion)(void *context);
-		} send;
-	} completion;
+	u64 send_completion_tid;
+	void *send_completion_ctx;
+	void (*send_completion)(void *context);
+
+	u32 send_buf_index;
 
 	/* This points to the memory after page_buf */
 	struct rndis_message *rndis_msg;
@@ -120,6 +189,7 @@
 int netvsc_recv_callback(struct hv_device *device_obj,
 			struct hv_netvsc_packet *packet,
 			struct ndis_tcp_ip_checksum_info *csum_info);
+void netvsc_channel_cb(void *context);
 int rndis_filter_open(struct hv_device *dev);
 int rndis_filter_close(struct hv_device *dev);
 int rndis_filter_device_add(struct hv_device *dev,
@@ -514,14 +584,16 @@
 
 #define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024*16)	/* 16MB */
 #define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY	(1024*1024*15)  /* 15MB */
+#define NETVSC_SEND_BUFFER_SIZE			(1024 * 1024)   /* 1MB */
+#define NETVSC_INVALID_INDEX			-1
+
 
 #define NETVSC_RECEIVE_BUFFER_ID		0xcafe
 
-/* Preallocated receive packets */
-#define NETVSC_RECEIVE_PACKETLIST_COUNT		256
-
 #define NETVSC_PACKET_SIZE                      2048
 
+#define VRSS_SEND_TAB_SIZE 16
+
 /* Per netvsc channel-specific */
 struct netvsc_device {
 	struct hv_device *dev;
@@ -532,12 +604,6 @@
 	wait_queue_head_t wait_drain;
 	bool start_remove;
 	bool destroy;
-	/*
-	 * List of free preallocated hv_netvsc_packet to represent receive
-	 * packet
-	 */
-	struct list_head recv_pkt_list;
-	spinlock_t recv_pkt_list_lock;
 
 	/* Receive buffer allocated by us but manages by NetVSP */
 	void *recv_buf;
@@ -546,6 +612,15 @@
 	u32 recv_section_cnt;
 	struct nvsp_1_receive_buffer_section *recv_section;
 
+	/* Send buffer allocated by us */
+	void *send_buf;
+	u32 send_buf_size;
+	u32 send_buf_gpadl_handle;
+	u32 send_section_cnt;
+	u32 send_section_size;
+	unsigned long *send_section_map;
+	int map_words;
+
 	/* Used for NetVSP initialization protocol */
 	struct completion channel_init_wait;
 	struct nvsp_message channel_init_pkt;
@@ -555,10 +630,20 @@
 
 	struct net_device *ndev;
 
+	struct vmbus_channel *chn_table[NR_CPUS];
+	u32 send_table[VRSS_SEND_TAB_SIZE];
+	u32 num_chn;
+	atomic_t queue_sends[NR_CPUS];
+
 	/* Holds rndis device info */
 	void *extension;
-	/* The recive buffer for this device */
+
+	int ring_size;
+
+	/* The primary channel callback buffer */
 	unsigned char cb_buffer[NETVSC_PACKET_SIZE];
+	/* The sub channel callback buffer */
+	unsigned char *sub_cb_buf;
 };
 
 /* NdisInitialize message */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index f7629ec..c041f63 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/if_ether.h>
+#include <asm/sync_bitops.h>
 
 #include "hyperv_net.h"
 
@@ -80,7 +81,7 @@
 }
 
 
-static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
+static int netvsc_destroy_buf(struct netvsc_device *net_device)
 {
 	struct nvsp_message *revoke_packet;
 	int ret = 0;
@@ -146,10 +147,62 @@
 		net_device->recv_section = NULL;
 	}
 
+	/* Deal with the send buffer we may have setup.
+	 * If we got a  send section size, it means we received a
+	 * SendsendBufferComplete msg (ie sent
+	 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
+	 * to send a revoke msg here
+	 */
+	if (net_device->send_section_size) {
+		/* Send the revoke receive buffer */
+		revoke_packet = &net_device->revoke_packet;
+		memset(revoke_packet, 0, sizeof(struct nvsp_message));
+
+		revoke_packet->hdr.msg_type =
+			NVSP_MSG1_TYPE_REVOKE_SEND_BUF;
+		revoke_packet->msg.v1_msg.revoke_recv_buf.id = 0;
+
+		ret = vmbus_sendpacket(net_device->dev->channel,
+				       revoke_packet,
+				       sizeof(struct nvsp_message),
+				       (unsigned long)revoke_packet,
+				       VM_PKT_DATA_INBAND, 0);
+		/* If we failed here, we might as well return and
+		 * have a leak rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			netdev_err(ndev, "unable to send "
+				   "revoke send buffer to netvsp\n");
+			return ret;
+		}
+	}
+	/* Teardown the gpadl on the vsp end */
+	if (net_device->send_buf_gpadl_handle) {
+		ret = vmbus_teardown_gpadl(net_device->dev->channel,
+					   net_device->send_buf_gpadl_handle);
+
+		/* If we failed here, we might as well return and have a leak
+		 * rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			netdev_err(ndev,
+				   "unable to teardown send buffer's gpadl\n");
+			return ret;
+		}
+		net_device->recv_buf_gpadl_handle = 0;
+	}
+	if (net_device->send_buf) {
+		/* Free up the receive buffer */
+		free_pages((unsigned long)net_device->send_buf,
+			   get_order(net_device->send_buf_size));
+		net_device->send_buf = NULL;
+	}
+	kfree(net_device->send_section_map);
+
 	return ret;
 }
 
-static int netvsc_init_recv_buf(struct hv_device *device)
+static int netvsc_init_buf(struct hv_device *device)
 {
 	int ret = 0;
 	int t;
@@ -248,10 +301,90 @@
 		goto cleanup;
 	}
 
+	/* Now setup the send buffer.
+	 */
+	net_device->send_buf =
+		(void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
+					 get_order(net_device->send_buf_size));
+	if (!net_device->send_buf) {
+		netdev_err(ndev, "unable to allocate send "
+			   "buffer of size %d\n", net_device->send_buf_size);
+		ret = -ENOMEM;
+		goto cleanup;
+	}
+
+	/* Establish the gpadl handle for this buffer on this
+	 * channel.  Note: This call uses the vmbus connection rather
+	 * than the channel to establish the gpadl handle.
+	 */
+	ret = vmbus_establish_gpadl(device->channel, net_device->send_buf,
+				    net_device->send_buf_size,
+				    &net_device->send_buf_gpadl_handle);
+	if (ret != 0) {
+		netdev_err(ndev,
+			   "unable to establish send buffer's gpadl\n");
+		goto cleanup;
+	}
+
+	/* Notify the NetVsp of the gpadl handle */
+	init_packet = &net_device->channel_init_pkt;
+	memset(init_packet, 0, sizeof(struct nvsp_message));
+	init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF;
+	init_packet->msg.v1_msg.send_recv_buf.gpadl_handle =
+		net_device->send_buf_gpadl_handle;
+	init_packet->msg.v1_msg.send_recv_buf.id = 0;
+
+	/* Send the gpadl notification request */
+	ret = vmbus_sendpacket(device->channel, init_packet,
+			       sizeof(struct nvsp_message),
+			       (unsigned long)init_packet,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0) {
+		netdev_err(ndev,
+			   "unable to send send buffer's gpadl to netvsp\n");
+		goto cleanup;
+	}
+
+	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
+	BUG_ON(t == 0);
+
+	/* Check the response */
+	if (init_packet->msg.v1_msg.
+	    send_send_buf_complete.status != NVSP_STAT_SUCCESS) {
+		netdev_err(ndev, "Unable to complete send buffer "
+			   "initialization with NetVsp - status %d\n",
+			   init_packet->msg.v1_msg.
+			   send_recv_buf_complete.status);
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	/* Parse the response */
+	net_device->send_section_size = init_packet->msg.
+				v1_msg.send_send_buf_complete.section_size;
+
+	/* Section count is simply the size divided by the section size.
+	 */
+	net_device->send_section_cnt =
+		net_device->send_buf_size/net_device->send_section_size;
+
+	dev_info(&device->device, "Send section size: %d, Section count:%d\n",
+		 net_device->send_section_size, net_device->send_section_cnt);
+
+	/* Setup state for managing the send buffer. */
+	net_device->map_words = DIV_ROUND_UP(net_device->send_section_cnt,
+					     BITS_PER_LONG);
+
+	net_device->send_section_map =
+		kzalloc(net_device->map_words * sizeof(ulong), GFP_KERNEL);
+	if (net_device->send_section_map == NULL)
+		goto cleanup;
+
 	goto exit;
 
 cleanup:
-	netvsc_destroy_recv_buf(net_device);
+	netvsc_destroy_buf(net_device);
 
 exit:
 	return ret;
@@ -369,8 +502,9 @@
 		net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
 	else
 		net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
+	net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
 
-	ret = netvsc_init_recv_buf(device);
+	ret = netvsc_init_buf(device);
 
 cleanup:
 	return ret;
@@ -378,7 +512,7 @@
 
 static void netvsc_disconnect_vsp(struct netvsc_device *net_device)
 {
-	netvsc_destroy_recv_buf(net_device);
+	netvsc_destroy_buf(net_device);
 }
 
 /*
@@ -387,7 +521,6 @@
 int netvsc_device_remove(struct hv_device *device)
 {
 	struct netvsc_device *net_device;
-	struct hv_netvsc_packet *netvsc_packet, *pos;
 	unsigned long flags;
 
 	net_device = hv_get_drvdata(device);
@@ -416,11 +549,8 @@
 	vmbus_close(device->channel);
 
 	/* Release all resources */
-	list_for_each_entry_safe(netvsc_packet, pos,
-				 &net_device->recv_pkt_list, list_ent) {
-		list_del(&netvsc_packet->list_ent);
-		kfree(netvsc_packet);
-	}
+	if (net_device->sub_cb_buf)
+		vfree(net_device->sub_cb_buf);
 
 	kfree(net_device);
 	return 0;
@@ -444,6 +574,12 @@
 	return avail_write * 100 / ring_info->ring_datasize;
 }
 
+static inline void netvsc_free_send_slot(struct netvsc_device *net_device,
+					 u32 index)
+{
+	sync_change_bit(index, net_device->send_section_map);
+}
+
 static void netvsc_send_completion(struct netvsc_device *net_device,
 				   struct hv_device *device,
 				   struct vmpacket_descriptor *packet)
@@ -451,6 +587,7 @@
 	struct nvsp_message *nvsp_packet;
 	struct hv_netvsc_packet *nvsc_packet;
 	struct net_device *ndev;
+	u32 send_index;
 
 	ndev = net_device->ndev;
 
@@ -461,7 +598,9 @@
 	    (nvsp_packet->hdr.msg_type ==
 	     NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) ||
 	    (nvsp_packet->hdr.msg_type ==
-	     NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE)) {
+	     NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE) ||
+	    (nvsp_packet->hdr.msg_type ==
+	     NVSP_MSG5_TYPE_SUBCHANNEL)) {
 		/* Copy the response back */
 		memcpy(&net_device->channel_init_pkt, nvsp_packet,
 		       sizeof(struct nvsp_message));
@@ -469,28 +608,39 @@
 	} else if (nvsp_packet->hdr.msg_type ==
 		   NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
 		int num_outstanding_sends;
+		u16 q_idx = 0;
+		struct vmbus_channel *channel = device->channel;
+		int queue_sends;
 
 		/* Get the send context */
 		nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
 			packet->trans_id;
 
 		/* Notify the layer above us */
-		if (nvsc_packet)
-			nvsc_packet->completion.send.send_completion(
-				nvsc_packet->completion.send.
-				send_completion_ctx);
+		if (nvsc_packet) {
+			send_index = nvsc_packet->send_buf_index;
+			if (send_index != NETVSC_INVALID_INDEX)
+				netvsc_free_send_slot(net_device, send_index);
+			q_idx = nvsc_packet->q_idx;
+			channel = nvsc_packet->channel;
+			nvsc_packet->send_completion(nvsc_packet->
+						     send_completion_ctx);
+		}
 
 		num_outstanding_sends =
 			atomic_dec_return(&net_device->num_outstanding_sends);
+		queue_sends = atomic_dec_return(&net_device->
+						queue_sends[q_idx]);
 
 		if (net_device->destroy && num_outstanding_sends == 0)
 			wake_up(&net_device->wait_drain);
 
-		if (netif_queue_stopped(ndev) && !net_device->start_remove &&
-			(hv_ringbuf_avail_percent(&device->channel->outbound)
-			> RING_AVAIL_PERCENT_HIWATER ||
-			num_outstanding_sends < 1))
-				netif_wake_queue(ndev);
+		if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
+		    !net_device->start_remove &&
+		    (hv_ringbuf_avail_percent(&channel->outbound) >
+		     RING_AVAIL_PERCENT_HIWATER || queue_sends < 1))
+				netif_tx_wake_queue(netdev_get_tx_queue(
+						    ndev, q_idx));
 	} else {
 		netdev_err(ndev, "Unknown send completion packet type- "
 			   "%d received!!\n", nvsp_packet->hdr.msg_type);
@@ -498,6 +648,52 @@
 
 }
 
+static u32 netvsc_get_next_send_section(struct netvsc_device *net_device)
+{
+	unsigned long index;
+	u32 max_words = net_device->map_words;
+	unsigned long *map_addr = (unsigned long *)net_device->send_section_map;
+	u32 section_cnt = net_device->send_section_cnt;
+	int ret_val = NETVSC_INVALID_INDEX;
+	int i;
+	int prev_val;
+
+	for (i = 0; i < max_words; i++) {
+		if (!~(map_addr[i]))
+			continue;
+		index = ffz(map_addr[i]);
+		prev_val = sync_test_and_set_bit(index, &map_addr[i]);
+		if (prev_val)
+			continue;
+		if ((index + (i * BITS_PER_LONG)) >= section_cnt)
+			break;
+		ret_val = (index + (i * BITS_PER_LONG));
+		break;
+	}
+	return ret_val;
+}
+
+u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device,
+			    unsigned int section_index,
+			    struct hv_netvsc_packet *packet)
+{
+	char *start = net_device->send_buf;
+	char *dest = (start + (section_index * net_device->send_section_size));
+	int i;
+	u32 msg_size = 0;
+
+	for (i = 0; i < packet->page_buf_cnt; i++) {
+		char *src = phys_to_virt(packet->page_buf[i].pfn << PAGE_SHIFT);
+		u32 offset = packet->page_buf[i].offset;
+		u32 len = packet->page_buf[i].len;
+
+		memcpy(dest, (src + offset), len);
+		msg_size += len;
+		dest += len;
+	}
+	return msg_size;
+}
+
 int netvsc_send(struct hv_device *device,
 			struct hv_netvsc_packet *packet)
 {
@@ -505,7 +701,12 @@
 	int ret = 0;
 	struct nvsp_message sendMessage;
 	struct net_device *ndev;
+	struct vmbus_channel *out_channel = NULL;
 	u64 req_id;
+	unsigned int section_index = NETVSC_INVALID_INDEX;
+	u32 msg_size = 0;
+	struct sk_buff *skb;
+
 
 	net_device = get_outbound_net_device(device);
 	if (!net_device)
@@ -521,25 +722,46 @@
 		sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 1;
 	}
 
-	/* Not using send buffer section */
-	sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_index =
-		0xFFFFFFFF;
-	sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0;
+	/* Attempt to send via sendbuf */
+	if (packet->total_data_buflen < net_device->send_section_size) {
+		section_index = netvsc_get_next_send_section(net_device);
+		if (section_index != NETVSC_INVALID_INDEX) {
+			msg_size = netvsc_copy_to_send_buf(net_device,
+							   section_index,
+							   packet);
+			skb = (struct sk_buff *)
+			      (unsigned long)packet->send_completion_tid;
+			if (skb)
+				dev_kfree_skb_any(skb);
+			packet->page_buf_cnt = 0;
+		}
+	}
+	packet->send_buf_index = section_index;
 
-	if (packet->completion.send.send_completion)
+
+	sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_index =
+		section_index;
+	sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = msg_size;
+
+	if (packet->send_completion)
 		req_id = (ulong)packet;
 	else
 		req_id = 0;
 
+	out_channel = net_device->chn_table[packet->q_idx];
+	if (out_channel == NULL)
+		out_channel = device->channel;
+	packet->channel = out_channel;
+
 	if (packet->page_buf_cnt) {
-		ret = vmbus_sendpacket_pagebuffer(device->channel,
+		ret = vmbus_sendpacket_pagebuffer(out_channel,
 						  packet->page_buf,
 						  packet->page_buf_cnt,
 						  &sendMessage,
 						  sizeof(struct nvsp_message),
 						  req_id);
 	} else {
-		ret = vmbus_sendpacket(device->channel, &sendMessage,
+		ret = vmbus_sendpacket(out_channel, &sendMessage,
 				sizeof(struct nvsp_message),
 				req_id,
 				VM_PKT_DATA_INBAND,
@@ -548,17 +770,24 @@
 
 	if (ret == 0) {
 		atomic_inc(&net_device->num_outstanding_sends);
-		if (hv_ringbuf_avail_percent(&device->channel->outbound) <
+		atomic_inc(&net_device->queue_sends[packet->q_idx]);
+
+		if (hv_ringbuf_avail_percent(&out_channel->outbound) <
 			RING_AVAIL_PERCENT_LOWATER) {
-			netif_stop_queue(ndev);
+			netif_tx_stop_queue(netdev_get_tx_queue(
+					    ndev, packet->q_idx));
+
 			if (atomic_read(&net_device->
-				num_outstanding_sends) < 1)
-				netif_wake_queue(ndev);
+				queue_sends[packet->q_idx]) < 1)
+				netif_tx_wake_queue(netdev_get_tx_queue(
+						    ndev, packet->q_idx));
 		}
 	} else if (ret == -EAGAIN) {
-		netif_stop_queue(ndev);
-		if (atomic_read(&net_device->num_outstanding_sends) < 1) {
-			netif_wake_queue(ndev);
+		netif_tx_stop_queue(netdev_get_tx_queue(
+				    ndev, packet->q_idx));
+		if (atomic_read(&net_device->queue_sends[packet->q_idx]) < 1) {
+			netif_tx_wake_queue(netdev_get_tx_queue(
+					    ndev, packet->q_idx));
 			ret = -ENOSPC;
 		}
 	} else {
@@ -570,6 +799,7 @@
 }
 
 static void netvsc_send_recv_completion(struct hv_device *device,
+					struct vmbus_channel *channel,
 					struct netvsc_device *net_device,
 					u64 transaction_id, u32 status)
 {
@@ -587,7 +817,7 @@
 
 retry_send_cmplt:
 	/* Send the completion */
-	ret = vmbus_sendpacket(device->channel, &recvcompMessage,
+	ret = vmbus_sendpacket(channel, &recvcompMessage,
 			       sizeof(struct nvsp_message), transaction_id,
 			       VM_PKT_COMP, 0);
 	if (ret == 0) {
@@ -613,76 +843,20 @@
 	}
 }
 
-/* Send a receive completion packet to RNDIS device (ie NetVsp) */
-static void netvsc_receive_completion(void *context)
-{
-	struct hv_netvsc_packet *packet = context;
-	struct hv_device *device = packet->device;
-	struct netvsc_device *net_device;
-	u64 transaction_id = 0;
-	bool fsend_receive_comp = false;
-	unsigned long flags;
-	struct net_device *ndev;
-	u32 status = NVSP_STAT_NONE;
-
-	/*
-	 * Even though it seems logical to do a GetOutboundNetDevice() here to
-	 * send out receive completion, we are using GetInboundNetDevice()
-	 * since we may have disable outbound traffic already.
-	 */
-	net_device = get_inbound_net_device(device);
-	if (!net_device)
-		return;
-	ndev = net_device->ndev;
-
-	/* Overloading use of the lock. */
-	spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
-
-	if (packet->status != NVSP_STAT_SUCCESS)
-		packet->xfer_page_pkt->status = NVSP_STAT_FAIL;
-
-	packet->xfer_page_pkt->count--;
-
-	/*
-	 * Last one in the line that represent 1 xfer page packet.
-	 * Return the xfer page packet itself to the freelist
-	 */
-	if (packet->xfer_page_pkt->count == 0) {
-		fsend_receive_comp = true;
-		transaction_id = packet->completion.recv.recv_completion_tid;
-		status = packet->xfer_page_pkt->status;
-		list_add_tail(&packet->xfer_page_pkt->list_ent,
-			      &net_device->recv_pkt_list);
-
-	}
-
-	/* Put the packet back */
-	list_add_tail(&packet->list_ent, &net_device->recv_pkt_list);
-	spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
-
-	/* Send a receive completion for the xfer page packet */
-	if (fsend_receive_comp)
-		netvsc_send_recv_completion(device, net_device, transaction_id,
-					status);
-
-}
-
 static void netvsc_receive(struct netvsc_device *net_device,
+			struct vmbus_channel *channel,
 			struct hv_device *device,
 			struct vmpacket_descriptor *packet)
 {
 	struct vmtransfer_page_packet_header *vmxferpage_packet;
 	struct nvsp_message *nvsp_packet;
-	struct hv_netvsc_packet *netvsc_packet = NULL;
-	/* struct netvsc_driver *netvscDriver; */
-	struct xferpage_packet *xferpage_packet = NULL;
+	struct hv_netvsc_packet nv_pkt;
+	struct hv_netvsc_packet *netvsc_packet = &nv_pkt;
+	u32 status = NVSP_STAT_SUCCESS;
 	int i;
 	int count = 0;
-	unsigned long flags;
 	struct net_device *ndev;
 
-	LIST_HEAD(listHead);
-
 	ndev = net_device->ndev;
 
 	/*
@@ -715,77 +889,14 @@
 		return;
 	}
 
-	/*
-	 * Grab free packets (range count + 1) to represent this xfer
-	 * page packet. +1 to represent the xfer page packet itself.
-	 * We grab it here so that we know exactly how many we can
-	 * fulfil
-	 */
-	spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
-	while (!list_empty(&net_device->recv_pkt_list)) {
-		list_move_tail(net_device->recv_pkt_list.next, &listHead);
-		if (++count == vmxferpage_packet->range_cnt + 1)
-			break;
-	}
-	spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
-
-	/*
-	 * We need at least 2 netvsc pkts (1 to represent the xfer
-	 * page and at least 1 for the range) i.e. we can handled
-	 * some of the xfer page packet ranges...
-	 */
-	if (count < 2) {
-		netdev_err(ndev, "Got only %d netvsc pkt...needed "
-			"%d pkts. Dropping this xfer page packet completely!\n",
-			count, vmxferpage_packet->range_cnt + 1);
-
-		/* Return it to the freelist */
-		spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
-		for (i = count; i != 0; i--) {
-			list_move_tail(listHead.next,
-				       &net_device->recv_pkt_list);
-		}
-		spin_unlock_irqrestore(&net_device->recv_pkt_list_lock,
-				       flags);
-
-		netvsc_send_recv_completion(device, net_device,
-					    vmxferpage_packet->d.trans_id,
-					    NVSP_STAT_FAIL);
-
-		return;
-	}
-
-	/* Remove the 1st packet to represent the xfer page packet itself */
-	xferpage_packet = (struct xferpage_packet *)listHead.next;
-	list_del(&xferpage_packet->list_ent);
-	xferpage_packet->status = NVSP_STAT_SUCCESS;
-
-	/* This is how much we can satisfy */
-	xferpage_packet->count = count - 1;
-
-	if (xferpage_packet->count != vmxferpage_packet->range_cnt) {
-		netdev_err(ndev, "Needed %d netvsc pkts to satisfy "
-			"this xfer page...got %d\n",
-			vmxferpage_packet->range_cnt, xferpage_packet->count);
-	}
+	count = vmxferpage_packet->range_cnt;
+	netvsc_packet->device = device;
+	netvsc_packet->channel = channel;
 
 	/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
-	for (i = 0; i < (count - 1); i++) {
-		netvsc_packet = (struct hv_netvsc_packet *)listHead.next;
-		list_del(&netvsc_packet->list_ent);
-
+	for (i = 0; i < count; i++) {
 		/* Initialize the netvsc packet */
 		netvsc_packet->status = NVSP_STAT_SUCCESS;
-		netvsc_packet->xfer_page_pkt = xferpage_packet;
-		netvsc_packet->completion.recv.recv_completion =
-					netvsc_receive_completion;
-		netvsc_packet->completion.recv.recv_completion_ctx =
-					netvsc_packet;
-		netvsc_packet->device = device;
-		/* Save this so that we can send it back */
-		netvsc_packet->completion.recv.recv_completion_tid =
-					vmxferpage_packet->d.trans_id;
-
 		netvsc_packet->data = (void *)((unsigned long)net_device->
 			recv_buf + vmxferpage_packet->ranges[i].byte_offset);
 		netvsc_packet->total_data_buflen =
@@ -794,16 +905,53 @@
 		/* Pass it to the upper layer */
 		rndis_filter_receive(device, netvsc_packet);
 
-		netvsc_receive_completion(netvsc_packet->
-				completion.recv.recv_completion_ctx);
+		if (netvsc_packet->status != NVSP_STAT_SUCCESS)
+			status = NVSP_STAT_FAIL;
 	}
 
+	netvsc_send_recv_completion(device, channel, net_device,
+				    vmxferpage_packet->d.trans_id, status);
 }
 
-static void netvsc_channel_cb(void *context)
+
+static void netvsc_send_table(struct hv_device *hdev,
+			      struct vmpacket_descriptor *vmpkt)
+{
+	struct netvsc_device *nvscdev;
+	struct net_device *ndev;
+	struct nvsp_message *nvmsg;
+	int i;
+	u32 count, *tab;
+
+	nvscdev = get_outbound_net_device(hdev);
+	if (!nvscdev)
+		return;
+	ndev = nvscdev->ndev;
+
+	nvmsg = (struct nvsp_message *)((unsigned long)vmpkt +
+					(vmpkt->offset8 << 3));
+
+	if (nvmsg->hdr.msg_type != NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE)
+		return;
+
+	count = nvmsg->msg.v5_msg.send_table.count;
+	if (count != VRSS_SEND_TAB_SIZE) {
+		netdev_err(ndev, "Received wrong send-table size:%u\n", count);
+		return;
+	}
+
+	tab = (u32 *)((unsigned long)&nvmsg->msg.v5_msg.send_table +
+		      nvmsg->msg.v5_msg.send_table.offset);
+
+	for (i = 0; i < count; i++)
+		nvscdev->send_table[i] = tab[i];
+}
+
+void netvsc_channel_cb(void *context)
 {
 	int ret;
-	struct hv_device *device = context;
+	struct vmbus_channel *channel = (struct vmbus_channel *)context;
+	struct hv_device *device;
 	struct netvsc_device *net_device;
 	u32 bytes_recvd;
 	u64 request_id;
@@ -812,14 +960,19 @@
 	int bufferlen = NETVSC_PACKET_SIZE;
 	struct net_device *ndev;
 
+	if (channel->primary_channel != NULL)
+		device = channel->primary_channel->device_obj;
+	else
+		device = channel->device_obj;
+
 	net_device = get_inbound_net_device(device);
 	if (!net_device)
 		return;
 	ndev = net_device->ndev;
-	buffer = net_device->cb_buffer;
+	buffer = get_per_channel_state(channel);
 
 	do {
-		ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen,
+		ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
 					   &bytes_recvd, &request_id);
 		if (ret == 0) {
 			if (bytes_recvd > 0) {
@@ -831,8 +984,12 @@
 					break;
 
 				case VM_PKT_DATA_USING_XFER_PAGES:
-					netvsc_receive(net_device,
-							device, desc);
+					netvsc_receive(net_device, channel,
+						       device, desc);
+					break;
+
+				case VM_PKT_DATA_INBAND:
+					netvsc_send_table(device, desc);
 					break;
 
 				default:
@@ -880,11 +1037,9 @@
 int netvsc_device_add(struct hv_device *device, void *additional_info)
 {
 	int ret = 0;
-	int i;
 	int ring_size =
 	((struct netvsc_device_info *)additional_info)->ring_size;
 	struct netvsc_device *net_device;
-	struct hv_netvsc_packet *packet, *pos;
 	struct net_device *ndev;
 
 	net_device = alloc_net_device(device);
@@ -893,6 +1048,8 @@
 		goto cleanup;
 	}
 
+	net_device->ring_size = ring_size;
+
 	/*
 	 * Coming into this function, struct net_device * is
 	 * registered as the driver private data.
@@ -903,24 +1060,14 @@
 	ndev = net_device->ndev;
 
 	/* Initialize the NetVSC channel extension */
-	spin_lock_init(&net_device->recv_pkt_list_lock);
-
-	INIT_LIST_HEAD(&net_device->recv_pkt_list);
-
-	for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
-		packet = kzalloc(sizeof(struct hv_netvsc_packet), GFP_KERNEL);
-		if (!packet)
-			break;
-
-		list_add_tail(&packet->list_ent,
-			      &net_device->recv_pkt_list);
-	}
 	init_completion(&net_device->channel_init_wait);
 
+	set_per_channel_state(device->channel, net_device->cb_buffer);
+
 	/* Open the channel */
 	ret = vmbus_open(device->channel, ring_size * PAGE_SIZE,
 			 ring_size * PAGE_SIZE, NULL, 0,
-			 netvsc_channel_cb, device);
+			 netvsc_channel_cb, device->channel);
 
 	if (ret != 0) {
 		netdev_err(ndev, "unable to open channel: %d\n", ret);
@@ -930,6 +1077,8 @@
 	/* Channel is opened */
 	pr_info("hv_netvsc channel opened successfully\n");
 
+	net_device->chn_table[0] = device->channel;
+
 	/* Connect with the NetVsp */
 	ret = netvsc_connect_vsp(device);
 	if (ret != 0) {
@@ -946,16 +1095,8 @@
 
 cleanup:
 
-	if (net_device) {
-		list_for_each_entry_safe(packet, pos,
-					 &net_device->recv_pkt_list,
-					 list_ent) {
-			list_del(&packet->list_ent);
-			kfree(packet);
-		}
-
+	if (net_device)
 		kfree(net_device);
-	}
 
 	return ret;
 }
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 31e55fb..939e3af 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -101,7 +101,7 @@
 		return ret;
 	}
 
-	netif_start_queue(net);
+	netif_tx_start_all_queues(net);
 
 	nvdev = hv_get_drvdata(device_obj);
 	rdev = nvdev->extension;
@@ -149,15 +149,98 @@
 	return ppi;
 }
 
+union sub_key {
+	u64 k;
+	struct {
+		u8 pad[3];
+		u8 kb;
+		u32 ka;
+	};
+};
+
+/* Toeplitz hash function
+ * data: network byte order
+ * return: host byte order
+ */
+static u32 comp_hash(u8 *key, int klen, u8 *data, int dlen)
+{
+	union sub_key subk;
+	int k_next = 4;
+	u8 dt;
+	int i, j;
+	u32 ret = 0;
+
+	subk.k = 0;
+	subk.ka = ntohl(*(u32 *)key);
+
+	for (i = 0; i < dlen; i++) {
+		subk.kb = key[k_next];
+		k_next = (k_next + 1) % klen;
+		dt = data[i];
+		for (j = 0; j < 8; j++) {
+			if (dt & 0x80)
+				ret ^= subk.ka;
+			dt <<= 1;
+			subk.k <<= 1;
+		}
+	}
+
+	return ret;
+}
+
+static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb)
+{
+	struct iphdr *iphdr;
+	int data_len;
+	bool ret = false;
+
+	if (eth_hdr(skb)->h_proto != htons(ETH_P_IP))
+		return false;
+
+	iphdr = ip_hdr(skb);
+
+	if (iphdr->version == 4) {
+		if (iphdr->protocol == IPPROTO_TCP)
+			data_len = 12;
+		else
+			data_len = 8;
+		*hash = comp_hash(netvsc_hash_key, HASH_KEYLEN,
+				  (u8 *)&iphdr->saddr, data_len);
+		ret = true;
+	}
+
+	return ret;
+}
+
+static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
+			void *accel_priv, select_queue_fallback_t fallback)
+{
+	struct net_device_context *net_device_ctx = netdev_priv(ndev);
+	struct hv_device *hdev =  net_device_ctx->device_ctx;
+	struct netvsc_device *nvsc_dev = hv_get_drvdata(hdev);
+	u32 hash;
+	u16 q_idx = 0;
+
+	if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1)
+		return 0;
+
+	if (netvsc_set_hash(&hash, skb))
+		q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] %
+			ndev->real_num_tx_queues;
+
+	return q_idx;
+}
+
 static void netvsc_xmit_completion(void *context)
 {
 	struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
 	struct sk_buff *skb = (struct sk_buff *)
-		(unsigned long)packet->completion.send.send_completion_tid;
+		(unsigned long)packet->send_completion_tid;
+	u32 index = packet->send_buf_index;
 
 	kfree(packet);
 
-	if (skb)
+	if (skb && (index == NETVSC_INVALID_INDEX))
 		dev_kfree_skb_any(skb);
 }
 
@@ -333,6 +416,8 @@
 
 	packet->vlan_tci = skb->vlan_tci;
 
+	packet->q_idx = skb_get_queue_mapping(skb);
+
 	packet->is_data_pkt = true;
 	packet->total_data_buflen = skb->len;
 
@@ -341,9 +426,9 @@
 				(num_data_pgs * sizeof(struct hv_page_buffer)));
 
 	/* Set the completion routine */
-	packet->completion.send.send_completion = netvsc_xmit_completion;
-	packet->completion.send.send_completion_ctx = packet;
-	packet->completion.send.send_completion_tid = (unsigned long)skb;
+	packet->send_completion = netvsc_xmit_completion;
+	packet->send_completion_ctx = packet;
+	packet->send_completion_tid = (unsigned long)skb;
 
 	isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
 
@@ -554,6 +639,10 @@
 		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
 				       packet->vlan_tci);
 
+	skb_record_rx_queue(skb, packet->channel->
+			    offermsg.offer.sub_channel_index %
+			    net->real_num_rx_queues);
+
 	net->stats.rx_packets++;
 	net->stats.rx_bytes += packet->total_data_buflen;
 
@@ -602,7 +691,7 @@
 	hv_set_drvdata(hdev, ndev);
 	device_info.ring_size = ring_size;
 	rndis_filter_device_add(hdev, &device_info);
-	netif_wake_queue(ndev);
+	netif_tx_wake_all_queues(ndev);
 
 	return 0;
 }
@@ -648,6 +737,7 @@
 	.ndo_change_mtu =		netvsc_change_mtu,
 	.ndo_validate_addr =		eth_validate_addr,
 	.ndo_set_mac_address =		netvsc_set_mac_addr,
+	.ndo_select_queue =		netvsc_select_queue,
 };
 
 /*
@@ -694,9 +784,11 @@
 	struct net_device *net = NULL;
 	struct net_device_context *net_device_ctx;
 	struct netvsc_device_info device_info;
+	struct netvsc_device *nvdev;
 	int ret;
 
-	net = alloc_etherdev(sizeof(struct net_device_context));
+	net = alloc_etherdev_mq(sizeof(struct net_device_context),
+				num_online_cpus());
 	if (!net)
 		return -ENOMEM;
 
@@ -729,6 +821,12 @@
 	}
 	memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
 
+	nvdev = hv_get_drvdata(dev);
+	netif_set_real_num_tx_queues(net, nvdev->num_chn);
+	netif_set_real_num_rx_queues(net, nvdev->num_chn);
+	dev_info(&dev->device, "real num tx,rx queues:%u, %u\n",
+		 net->real_num_tx_queues, net->real_num_rx_queues);
+
 	ret = register_netdev(net);
 	if (ret != 0) {
 		pr_err("Unable to register netdev.\n");
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 143a98c..99c527a 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -31,7 +31,7 @@
 #include "hyperv_net.h"
 
 
-#define RNDIS_EXT_LEN 100
+#define RNDIS_EXT_LEN PAGE_SIZE
 struct rndis_request {
 	struct list_head list_ent;
 	struct completion  wait_event;
@@ -94,6 +94,8 @@
 	rndis_msg->ndis_msg_type = msg_type;
 	rndis_msg->msg_len = msg_len;
 
+	request->pkt.q_idx = 0;
+
 	/*
 	 * Set the request id. This field is always after the rndis header for
 	 * request/response packet types so we just used the SetRequest as a
@@ -234,7 +236,7 @@
 			packet->page_buf[0].len;
 	}
 
-	packet->completion.send.send_completion = NULL;
+	packet->send_completion = NULL;
 
 	ret = netvsc_send(dev->net_dev->dev, packet);
 	return ret;
@@ -399,8 +401,6 @@
 	pkt->total_data_buflen = rndis_pkt->data_len;
 	pkt->data = (void *)((unsigned long)pkt->data + data_offset);
 
-	pkt->is_data_pkt = true;
-
 	vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
 	if (vlan) {
 		pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
@@ -509,6 +509,19 @@
 	query->info_buflen = 0;
 	query->dev_vc_handle = 0;
 
+	if (oid == OID_GEN_RECEIVE_SCALE_CAPABILITIES) {
+		struct ndis_recv_scale_cap *cap;
+
+		request->request_msg.msg_len +=
+			sizeof(struct ndis_recv_scale_cap);
+		query->info_buflen = sizeof(struct ndis_recv_scale_cap);
+		cap = (struct ndis_recv_scale_cap *)((unsigned long)query +
+						     query->info_buf_offset);
+		cap->hdr.type = NDIS_OBJECT_TYPE_RSS_CAPABILITIES;
+		cap->hdr.rev = NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2;
+		cap->hdr.size = sizeof(struct ndis_recv_scale_cap);
+	}
+
 	ret = rndis_filter_send_request(dev, request);
 	if (ret != 0)
 		goto cleanup;
@@ -695,6 +708,89 @@
 	return ret;
 }
 
+u8 netvsc_hash_key[HASH_KEYLEN] = {
+	0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
+	0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
+	0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
+	0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
+	0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
+};
+
+int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
+{
+	struct net_device *ndev = rdev->net_dev->ndev;
+	struct rndis_request *request;
+	struct rndis_set_request *set;
+	struct rndis_set_complete *set_complete;
+	u32 extlen = sizeof(struct ndis_recv_scale_param) +
+		     4*ITAB_NUM + HASH_KEYLEN;
+	struct ndis_recv_scale_param *rssp;
+	u32 *itab;
+	u8 *keyp;
+	int i, t, ret;
+
+	request = get_rndis_request(
+			rdev, RNDIS_MSG_SET,
+			RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
+	if (!request)
+		return -ENOMEM;
+
+	set = &request->request_msg.msg.set_req;
+	set->oid = OID_GEN_RECEIVE_SCALE_PARAMETERS;
+	set->info_buflen = extlen;
+	set->info_buf_offset = sizeof(struct rndis_set_request);
+	set->dev_vc_handle = 0;
+
+	rssp = (struct ndis_recv_scale_param *)(set + 1);
+	rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
+	rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
+	rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
+	rssp->flag = 0;
+	rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
+			 NDIS_HASH_TCP_IPV4;
+	rssp->indirect_tabsize = 4*ITAB_NUM;
+	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
+	rssp->hashkey_size = HASH_KEYLEN;
+	rssp->kashkey_offset = rssp->indirect_taboffset +
+			       rssp->indirect_tabsize;
+
+	/* Set indirection table entries */
+	itab = (u32 *)(rssp + 1);
+	for (i = 0; i < ITAB_NUM; i++)
+		itab[i] = i % num_queue;
+
+	/* Set hask key values */
+	keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
+	for (i = 0; i < HASH_KEYLEN; i++)
+		keyp[i] = netvsc_hash_key[i];
+
+
+	ret = rndis_filter_send_request(rdev, request);
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		netdev_err(ndev, "timeout before we got a set response...\n");
+		/* can't put_rndis_request, since we may still receive a
+		 * send-completion.
+		 */
+		return -ETIMEDOUT;
+	} else {
+		set_complete = &request->response_msg.msg.set_complete;
+		if (set_complete->status != RNDIS_STATUS_SUCCESS) {
+			netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
+				   set_complete->status);
+			ret = -EINVAL;
+		}
+	}
+
+cleanup:
+	put_rndis_request(rdev, request);
+	return ret;
+}
+
+
 static int rndis_filter_query_device_link_status(struct rndis_device *dev)
 {
 	u32 size = sizeof(u32);
@@ -886,6 +982,28 @@
 	return ret;
 }
 
+static void netvsc_sc_open(struct vmbus_channel *new_sc)
+{
+	struct netvsc_device *nvscdev;
+	u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
+	int ret;
+
+	nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
+
+	if (chn_index >= nvscdev->num_chn)
+		return;
+
+	set_per_channel_state(new_sc, nvscdev->sub_cb_buf + (chn_index - 1) *
+			      NETVSC_PACKET_SIZE);
+
+	ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
+			 nvscdev->ring_size * PAGE_SIZE, NULL, 0,
+			 netvsc_channel_cb, new_sc);
+
+	if (ret == 0)
+		nvscdev->chn_table[chn_index] = new_sc;
+}
+
 int rndis_filter_device_add(struct hv_device *dev,
 				  void *additional_info)
 {
@@ -894,6 +1012,10 @@
 	struct rndis_device *rndis_device;
 	struct netvsc_device_info *device_info = additional_info;
 	struct ndis_offload_params offloads;
+	struct nvsp_message *init_packet;
+	int t;
+	struct ndis_recv_scale_cap rsscap;
+	u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
 
 	rndis_device = get_rndis_device();
 	if (!rndis_device)
@@ -913,6 +1035,7 @@
 
 	/* Initialize the rndis device */
 	net_device = hv_get_drvdata(dev);
+	net_device->num_chn = 1;
 
 	net_device->extension = rndis_device;
 	rndis_device->net_dev = net_device;
@@ -952,7 +1075,6 @@
 	if (ret)
 		goto err_dev_remv;
 
-
 	rndis_filter_query_device_link_status(rndis_device);
 
 	device_info->link_state = rndis_device->link_state;
@@ -961,7 +1083,66 @@
 		 rndis_device->hw_mac_adr,
 		 device_info->link_state ? "down" : "up");
 
-	return ret;
+	if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
+		return 0;
+
+	/* vRSS setup */
+	memset(&rsscap, 0, rsscap_size);
+	ret = rndis_filter_query_device(rndis_device,
+					OID_GEN_RECEIVE_SCALE_CAPABILITIES,
+					&rsscap, &rsscap_size);
+	if (ret || rsscap.num_recv_que < 2)
+		goto out;
+
+	net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
+			       num_online_cpus() : rsscap.num_recv_que;
+	if (net_device->num_chn == 1)
+		goto out;
+
+	net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
+					 NETVSC_PACKET_SIZE);
+	if (!net_device->sub_cb_buf) {
+		net_device->num_chn = 1;
+		dev_info(&dev->device, "No memory for subchannels.\n");
+		goto out;
+	}
+
+	vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
+
+	init_packet = &net_device->channel_init_pkt;
+	memset(init_packet, 0, sizeof(struct nvsp_message));
+	init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
+	init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
+	init_packet->msg.v5_msg.subchn_req.num_subchannels =
+						net_device->num_chn - 1;
+	ret = vmbus_sendpacket(dev->channel, init_packet,
+			       sizeof(struct nvsp_message),
+			       (unsigned long)init_packet,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret)
+		goto out;
+	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+	if (init_packet->msg.v5_msg.subchn_comp.status !=
+	    NVSP_STAT_SUCCESS) {
+		ret = -ENODEV;
+		goto out;
+	}
+	net_device->num_chn = 1 +
+		init_packet->msg.v5_msg.subchn_comp.num_subchannels;
+
+	vmbus_are_subchannels_present(dev->channel);
+
+	ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
+
+out:
+	if (ret)
+		net_device->num_chn = 1;
+	return 0; /* return 0 because primary channel can be used alone */
 
 err_dev_remv:
 	rndis_filter_device_remove(dev);
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index e36f194..4517b14 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
@@ -692,10 +693,7 @@
 	if (rc < 0)
 		goto err_rx;
 
-	rc = at86rf230_start(dev);
-
-	return rc;
-
+	return at86rf230_start(dev);
 err_rx:
 	at86rf230_start(dev);
 err:
@@ -963,33 +961,24 @@
 	return at86rf230_isr(irq, data);
 }
 
-static int at86rf230_irq_polarity(struct at86rf230_local *lp, int pol)
-{
-	return at86rf230_write_subreg(lp, SR_IRQ_POLARITY, pol);
-}
-
 static int at86rf230_hw_init(struct at86rf230_local *lp)
 {
-	struct at86rf230_platform_data *pdata = lp->spi->dev.platform_data;
-	int rc, irq_pol;
-	u8 status;
+	int rc, irq_pol, irq_type;
+	u8 dvdd;
 	u8 csma_seed[2];
 
-	rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
-	if (rc)
-		return rc;
-
 	rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_FORCE_TRX_OFF);
 	if (rc)
 		return rc;
 
+	irq_type = irq_get_trigger_type(lp->spi->irq);
 	/* configure irq polarity, defaults to high active */
-	if (pdata->irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+	if (irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
 		irq_pol = IRQ_ACTIVE_LOW;
 	else
 		irq_pol = IRQ_ACTIVE_HIGH;
 
-	rc = at86rf230_irq_polarity(lp, irq_pol);
+	rc = at86rf230_write_subreg(lp, SR_IRQ_POLARITY, irq_pol);
 	if (rc)
 		return rc;
 
@@ -1017,10 +1006,10 @@
 	/* Wait the next SLEEP cycle */
 	msleep(100);
 
-	rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &status);
+	rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &dvdd);
 	if (rc)
 		return rc;
-	if (!status) {
+	if (!dvdd) {
 		dev_err(&lp->spi->dev, "DVDD error\n");
 		return -EINVAL;
 	}
@@ -1032,7 +1021,6 @@
 at86rf230_get_pdata(struct spi_device *spi)
 {
 	struct at86rf230_platform_data *pdata;
-	const char *irq_type;
 
 	if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node)
 		return spi->dev.platform_data;
@@ -1044,19 +1032,6 @@
 	pdata->rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
 	pdata->slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0);
 
-	pdata->irq_type = IRQF_TRIGGER_RISING;
-	of_property_read_string(spi->dev.of_node, "irq-type", &irq_type);
-	if (!strcmp(irq_type, "level-high"))
-		pdata->irq_type = IRQF_TRIGGER_HIGH;
-	else if (!strcmp(irq_type, "level-low"))
-		pdata->irq_type = IRQF_TRIGGER_LOW;
-	else if (!strcmp(irq_type, "edge-rising"))
-		pdata->irq_type = IRQF_TRIGGER_RISING;
-	else if (!strcmp(irq_type, "edge-falling"))
-		pdata->irq_type = IRQF_TRIGGER_FALLING;
-	else
-		dev_warn(&spi->dev, "wrong irq-type specified using edge-rising\n");
-
 	spi->dev.platform_data = pdata;
 done:
 	return pdata;
@@ -1071,7 +1046,7 @@
 	u8 part = 0, version = 0, status;
 	irq_handler_t irq_handler;
 	work_func_t irq_worker;
-	int rc;
+	int rc, irq_type;
 	const char *chip;
 	struct ieee802154_ops *ops = NULL;
 
@@ -1087,27 +1062,17 @@
 	}
 
 	if (gpio_is_valid(pdata->rstn)) {
-		rc = gpio_request(pdata->rstn, "rstn");
+		rc = devm_gpio_request_one(&spi->dev, pdata->rstn,
+					   GPIOF_OUT_INIT_HIGH, "rstn");
 		if (rc)
 			return rc;
 	}
 
 	if (gpio_is_valid(pdata->slp_tr)) {
-		rc = gpio_request(pdata->slp_tr, "slp_tr");
+		rc = devm_gpio_request_one(&spi->dev, pdata->slp_tr,
+					   GPIOF_OUT_INIT_LOW, "slp_tr");
 		if (rc)
-			goto err_slp_tr;
-	}
-
-	if (gpio_is_valid(pdata->rstn)) {
-		rc = gpio_direction_output(pdata->rstn, 1);
-		if (rc)
-			goto err_gpio_dir;
-	}
-
-	if (gpio_is_valid(pdata->slp_tr)) {
-		rc = gpio_direction_output(pdata->slp_tr, 0);
-		if (rc)
-			goto err_gpio_dir;
+			return rc;
 	}
 
 	/* Reset */
@@ -1121,13 +1086,12 @@
 
 	rc = __at86rf230_detect_device(spi, &man_id, &part, &version);
 	if (rc < 0)
-		goto err_gpio_dir;
+		return rc;
 
 	if (man_id != 0x001f) {
 		dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
 			man_id >> 8, man_id & 0xFF);
-		rc = -EINVAL;
-		goto err_gpio_dir;
+		return -EINVAL;
 	}
 
 	switch (part) {
@@ -1154,16 +1118,12 @@
 	}
 
 	dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version);
-	if (!ops) {
-		rc = -ENOTSUPP;
-		goto err_gpio_dir;
-	}
+	if (!ops)
+		return -ENOTSUPP;
 
 	dev = ieee802154_alloc_device(sizeof(*lp), ops);
-	if (!dev) {
-		rc = -ENOMEM;
-		goto err_gpio_dir;
-	}
+	if (!dev)
+		return -ENOMEM;
 
 	lp = dev->priv;
 	lp->dev = dev;
@@ -1176,7 +1136,8 @@
 	dev->extra_tx_headroom = 0;
 	dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
 
-	if (pdata->irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+	irq_type = irq_get_trigger_type(spi->irq);
+	if (irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
 		irq_worker = at86rf230_irqwork;
 		irq_handler = at86rf230_isr;
 	} else {
@@ -1202,75 +1163,65 @@
 	if (rc)
 		goto err_hw_init;
 
-	rc = request_irq(spi->irq, irq_handler,
-			 IRQF_SHARED | pdata->irq_type,
-			 dev_name(&spi->dev), lp);
-	if (rc)
-		goto err_hw_init;
-
 	/* Read irq status register to reset irq line */
 	rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &status);
 	if (rc)
-		goto err_irq;
+		goto err_hw_init;
+
+	rc = devm_request_irq(&spi->dev, spi->irq, irq_handler, IRQF_SHARED,
+			      dev_name(&spi->dev), lp);
+	if (rc)
+		goto err_hw_init;
 
 	rc = ieee802154_register_device(lp->dev);
 	if (rc)
-		goto err_irq;
+		goto err_hw_init;
 
 	return rc;
 
-err_irq:
-	free_irq(spi->irq, lp);
 err_hw_init:
 	flush_work(&lp->irqwork);
-	spi_set_drvdata(spi, NULL);
 	mutex_destroy(&lp->bmux);
 	ieee802154_free_device(lp->dev);
 
-err_gpio_dir:
-	if (gpio_is_valid(pdata->slp_tr))
-		gpio_free(pdata->slp_tr);
-err_slp_tr:
-	if (gpio_is_valid(pdata->rstn))
-		gpio_free(pdata->rstn);
 	return rc;
 }
 
 static int at86rf230_remove(struct spi_device *spi)
 {
 	struct at86rf230_local *lp = spi_get_drvdata(spi);
-	struct at86rf230_platform_data *pdata = spi->dev.platform_data;
 
 	/* mask all at86rf230 irq's */
 	at86rf230_write_subreg(lp, SR_IRQ_MASK, 0);
 	ieee802154_unregister_device(lp->dev);
-
-	free_irq(spi->irq, lp);
 	flush_work(&lp->irqwork);
-
-	if (gpio_is_valid(pdata->slp_tr))
-		gpio_free(pdata->slp_tr);
-	if (gpio_is_valid(pdata->rstn))
-		gpio_free(pdata->rstn);
-
 	mutex_destroy(&lp->bmux);
 	ieee802154_free_device(lp->dev);
-
 	dev_dbg(&spi->dev, "unregistered at86rf230\n");
+
 	return 0;
 }
 
-#if IS_ENABLED(CONFIG_OF)
-static struct of_device_id at86rf230_of_match[] = {
+static const struct of_device_id at86rf230_of_match[] = {
 	{ .compatible = "atmel,at86rf230", },
 	{ .compatible = "atmel,at86rf231", },
 	{ .compatible = "atmel,at86rf233", },
 	{ .compatible = "atmel,at86rf212", },
 	{ },
 };
-#endif
+MODULE_DEVICE_TABLE(of, at86rf230_of_match);
+
+static const struct spi_device_id at86rf230_device_id[] = {
+	{ .name = "at86rf230", },
+	{ .name = "at86rf231", },
+	{ .name = "at86rf233", },
+	{ .name = "at86rf212", },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, at86rf230_device_id);
 
 static struct spi_driver at86rf230_driver = {
+	.id_table = at86rf230_device_id,
 	.driver = {
 		.of_match_table = of_match_ptr(at86rf230_of_match),
 		.name	= "at86rf230",
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 753a8c2..cfb27c8 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -30,6 +30,7 @@
 #include <linux/if_link.h>
 #include <linux/if_macvlan.h>
 #include <linux/hash.h>
+#include <linux/workqueue.h>
 #include <net/rtnetlink.h>
 #include <net/xfrm.h>
 
@@ -40,10 +41,18 @@
 	struct hlist_head	vlan_hash[MACVLAN_HASH_SIZE];
 	struct list_head	vlans;
 	struct rcu_head		rcu;
+	struct sk_buff_head	bc_queue;
+	struct work_struct	bc_work;
 	bool 			passthru;
 	int			count;
 };
 
+struct macvlan_skb_cb {
+	const struct macvlan_dev *src;
+};
+
+#define MACVLAN_SKB_CB(__skb) ((struct macvlan_skb_cb *)&((__skb)->cb[0]))
+
 static void macvlan_port_destroy(struct net_device *dev);
 
 static struct macvlan_port *macvlan_port_get_rcu(const struct net_device *dev)
@@ -120,7 +129,7 @@
 	struct net_device *dev = vlan->dev;
 
 	if (local)
-		return dev_forward_skb(dev, skb);
+		return __dev_forward_skb(dev, skb);
 
 	skb->dev = dev;
 	if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast))
@@ -128,7 +137,7 @@
 	else
 		skb->pkt_type = PACKET_MULTICAST;
 
-	return netif_rx(skb);
+	return 0;
 }
 
 static u32 macvlan_hash_mix(const struct macvlan_dev *vlan)
@@ -175,13 +184,87 @@
 			if (likely(nskb))
 				err = macvlan_broadcast_one(
 					nskb, vlan, eth,
-					mode == MACVLAN_MODE_BRIDGE);
+					mode == MACVLAN_MODE_BRIDGE) ?:
+				      netif_rx_ni(nskb);
 			macvlan_count_rx(vlan, skb->len + ETH_HLEN,
 					 err == NET_RX_SUCCESS, 1);
 		}
 	}
 }
 
+static void macvlan_process_broadcast(struct work_struct *w)
+{
+	struct macvlan_port *port = container_of(w, struct macvlan_port,
+						 bc_work);
+	struct sk_buff *skb;
+	struct sk_buff_head list;
+
+	skb_queue_head_init(&list);
+
+	spin_lock_bh(&port->bc_queue.lock);
+	skb_queue_splice_tail_init(&port->bc_queue, &list);
+	spin_unlock_bh(&port->bc_queue.lock);
+
+	while ((skb = __skb_dequeue(&list))) {
+		const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
+
+		rcu_read_lock();
+
+		if (!src)
+			/* frame comes from an external address */
+			macvlan_broadcast(skb, port, NULL,
+					  MACVLAN_MODE_PRIVATE |
+					  MACVLAN_MODE_VEPA    |
+					  MACVLAN_MODE_PASSTHRU|
+					  MACVLAN_MODE_BRIDGE);
+		else if (src->mode == MACVLAN_MODE_VEPA)
+			/* flood to everyone except source */
+			macvlan_broadcast(skb, port, src->dev,
+					  MACVLAN_MODE_VEPA |
+					  MACVLAN_MODE_BRIDGE);
+		else
+			/*
+			 * flood only to VEPA ports, bridge ports
+			 * already saw the frame on the way out.
+			 */
+			macvlan_broadcast(skb, port, src->dev,
+					  MACVLAN_MODE_VEPA);
+
+		rcu_read_unlock();
+
+		kfree_skb(skb);
+	}
+}
+
+static void macvlan_broadcast_enqueue(struct macvlan_port *port,
+				      struct sk_buff *skb)
+{
+	struct sk_buff *nskb;
+	int err = -ENOMEM;
+
+	nskb = skb_clone(skb, GFP_ATOMIC);
+	if (!nskb)
+		goto err;
+
+	spin_lock(&port->bc_queue.lock);
+	if (skb_queue_len(&port->bc_queue) < skb->dev->tx_queue_len) {
+		__skb_queue_tail(&port->bc_queue, nskb);
+		err = 0;
+	}
+	spin_unlock(&port->bc_queue.lock);
+
+	if (err)
+		goto free_nskb;
+
+	schedule_work(&port->bc_work);
+	return;
+
+free_nskb:
+	kfree_skb(nskb);
+err:
+	atomic_long_inc(&skb->dev->rx_dropped);
+}
+
 /* called under rcu_read_lock() from netif_receive_skb */
 static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
 {
@@ -201,32 +284,18 @@
 			return RX_HANDLER_CONSUMED;
 		eth = eth_hdr(skb);
 		src = macvlan_hash_lookup(port, eth->h_source);
-		if (!src)
-			/* frame comes from an external address */
-			macvlan_broadcast(skb, port, NULL,
-					  MACVLAN_MODE_PRIVATE |
-					  MACVLAN_MODE_VEPA    |
-					  MACVLAN_MODE_PASSTHRU|
-					  MACVLAN_MODE_BRIDGE);
-		else if (src->mode == MACVLAN_MODE_VEPA)
-			/* flood to everyone except source */
-			macvlan_broadcast(skb, port, src->dev,
-					  MACVLAN_MODE_VEPA |
-					  MACVLAN_MODE_BRIDGE);
-		else if (src->mode == MACVLAN_MODE_BRIDGE)
-			/*
-			 * flood only to VEPA ports, bridge ports
-			 * already saw the frame on the way out.
-			 */
-			macvlan_broadcast(skb, port, src->dev,
-					  MACVLAN_MODE_VEPA);
-		else {
+		if (src && src->mode != MACVLAN_MODE_VEPA &&
+		    src->mode != MACVLAN_MODE_BRIDGE) {
 			/* forward to original port. */
 			vlan = src;
-			ret = macvlan_broadcast_one(skb, vlan, eth, 0);
+			ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?:
+			      netif_rx(skb);
 			goto out;
 		}
 
+		MACVLAN_SKB_CB(skb)->src = src;
+		macvlan_broadcast_enqueue(port, skb);
+
 		return RX_HANDLER_PASS;
 	}
 
@@ -764,6 +833,9 @@
 	for (i = 0; i < MACVLAN_HASH_SIZE; i++)
 		INIT_HLIST_HEAD(&port->vlan_hash[i]);
 
+	skb_queue_head_init(&port->bc_queue);
+	INIT_WORK(&port->bc_work, macvlan_process_broadcast);
+
 	err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
 	if (err)
 		kfree(port);
@@ -776,6 +848,7 @@
 {
 	struct macvlan_port *port = macvlan_port_get_rtnl(dev);
 
+	cancel_work_sync(&port->bc_work);
 	dev->priv_flags &= ~IFF_MACVLAN_PORT;
 	netdev_rx_handler_unregister(dev);
 	kfree_rcu(port, rcu);
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 643464d..6c622ae 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -144,41 +144,11 @@
 
 static int at803x_config_init(struct phy_device *phydev)
 {
-	int val;
 	int ret;
-	u32 features;
 
-	features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
-		   SUPPORTED_FIBRE | SUPPORTED_BNC;
-
-	val = phy_read(phydev, MII_BMSR);
-	if (val < 0)
-		return val;
-
-	if (val & BMSR_ANEGCAPABLE)
-		features |= SUPPORTED_Autoneg;
-	if (val & BMSR_100FULL)
-		features |= SUPPORTED_100baseT_Full;
-	if (val & BMSR_100HALF)
-		features |= SUPPORTED_100baseT_Half;
-	if (val & BMSR_10FULL)
-		features |= SUPPORTED_10baseT_Full;
-	if (val & BMSR_10HALF)
-		features |= SUPPORTED_10baseT_Half;
-
-	if (val & BMSR_ESTATEN) {
-		val = phy_read(phydev, MII_ESTATUS);
-		if (val < 0)
-			return val;
-
-		if (val & ESTATUS_1000_TFULL)
-			features |= SUPPORTED_1000baseT_Full;
-		if (val & ESTATUS_1000_THALF)
-			features |= SUPPORTED_1000baseT_Half;
-	}
-
-	phydev->supported = features;
-	phydev->advertising = features;
+	ret = genphy_config_init(phydev);
+	if (ret < 0)
+		return ret;
 
 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
 		ret = phy_write(phydev, AT803X_DEBUG_ADDR,
@@ -283,8 +253,7 @@
 
 static void __exit atheros_exit(void)
 {
-	return phy_drivers_unregister(at803x_driver,
-				      ARRAY_SIZE(at803x_driver));
+	phy_drivers_unregister(at803x_driver, ARRAY_SIZE(at803x_driver));
 }
 
 module_init(atheros_init);
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 5ad971a..d849684 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -246,13 +246,13 @@
 	if (val1 != -1)
 		newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0);
 
-	if (val2 != -1)
+	if (val2 != -2)
 		newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4);
 
-	if (val3 != -1)
+	if (val3 != -3)
 		newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8);
 
-	if (val4 != -1)
+	if (val4 != -4)
 		newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12);
 
 	return kszphy_extended_write(phydev, reg, newval);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0ce6066..466ae3e 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1067,7 +1067,7 @@
 }
 EXPORT_SYMBOL(genphy_soft_reset);
 
-static int genphy_config_init(struct phy_device *phydev)
+int genphy_config_init(struct phy_device *phydev)
 {
 	int val;
 	u32 features;
@@ -1118,6 +1118,7 @@
 	/* Do nothing for now */
 	return 0;
 }
+EXPORT_SYMBOL(genphy_config_init);
 
 static int gen10g_config_init(struct phy_device *phydev)
 {
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 11f3481..180c494 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -249,8 +249,7 @@
 
 static void __exit smsc_exit(void)
 {
-	return phy_drivers_unregister(smsc_phy_driver,
-		ARRAY_SIZE(smsc_phy_driver));
+	phy_drivers_unregister(smsc_phy_driver, ARRAY_SIZE(smsc_phy_driver));
 }
 
 MODULE_DESCRIPTION("SMSC PHY driver");
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 14372c6..5dc0935d 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -319,8 +319,7 @@
 
 static void __exit vsc82xx_exit(void)
 {
-	return phy_drivers_unregister(vsc82xx_driver,
-		ARRAY_SIZE(vsc82xx_driver));
+	phy_drivers_unregister(vsc82xx_driver, ARRAY_SIZE(vsc82xx_driver));
 }
 
 module_init(vsc82xx_init);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7b68746..b852bb3 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1285,7 +1285,7 @@
 	if (channels->rx_count || channels->tx_count || channels->other_count)
 		return -EINVAL;
 
-	if (queue_pairs > vi->max_queue_pairs)
+	if (queue_pairs > vi->max_queue_pairs || queue_pairs == 0)
 		return -EINVAL;
 
 	get_online_cpus();
@@ -1724,6 +1724,13 @@
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
 		vi->has_cvq = true;
 
+	if (vi->any_header_sg) {
+		if (vi->mergeable_rx_bufs)
+			dev->needed_headroom = sizeof(struct virtio_net_hdr_mrg_rxbuf);
+		else
+			dev->needed_headroom = sizeof(struct virtio_net_hdr);
+	}
+
 	/* Use single tx/rx queue pair as default */
 	vi->curr_queue_pairs = 1;
 	vi->max_queue_pairs = max_queue_pairs;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 82355d5..1dfee9a 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -127,6 +127,7 @@
 	struct list_head  next;		/* vxlan's per namespace list */
 	struct vxlan_sock *vn_sock;	/* listening socket */
 	struct net_device *dev;
+	struct net	  *net;		/* netns for packet i/o */
 	struct vxlan_rdst default_dst;	/* default destination */
 	union vxlan_addr  saddr;	/* source address */
 	__be16		  dst_port;
@@ -389,8 +390,8 @@
 		+ nla_total_size(sizeof(struct nda_cacheinfo));
 }
 
-static void vxlan_fdb_notify(struct vxlan_dev *vxlan,
-			     struct vxlan_fdb *fdb, int type)
+static void vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
+			     struct vxlan_rdst *rd, int type)
 {
 	struct net *net = dev_net(vxlan->dev);
 	struct sk_buff *skb;
@@ -400,8 +401,7 @@
 	if (skb == NULL)
 		goto errout;
 
-	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0,
-			     first_remote_rtnl(fdb));
+	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, rd);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */
 		WARN_ON(err == -EMSGSIZE);
@@ -427,10 +427,7 @@
 		.remote_vni = VXLAN_N_VID,
 	};
 
-	INIT_LIST_HEAD(&f.remotes);
-	list_add_rcu(&remote.list, &f.remotes);
-
-	vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
+	vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
 }
 
 static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
@@ -438,11 +435,11 @@
 	struct vxlan_fdb f = {
 		.state = NUD_STALE,
 	};
+	struct vxlan_rdst remote = { };
 
-	INIT_LIST_HEAD(&f.remotes);
 	memcpy(f.eth_addr, eth_addr, ETH_ALEN);
 
-	vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
+	vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
 }
 
 /* Hash Ethernet address */
@@ -533,7 +530,8 @@
 
 /* Add/update destinations for multicast */
 static int vxlan_fdb_append(struct vxlan_fdb *f,
-			    union vxlan_addr *ip, __be16 port, __u32 vni, __u32 ifindex)
+			    union vxlan_addr *ip, __be16 port, __u32 vni,
+			    __u32 ifindex, struct vxlan_rdst **rdp)
 {
 	struct vxlan_rdst *rd;
 
@@ -551,6 +549,7 @@
 
 	list_add_tail_rcu(&rd->list, &f->remotes);
 
+	*rdp = rd;
 	return 1;
 }
 
@@ -690,6 +689,7 @@
 			    __be16 port, __u32 vni, __u32 ifindex,
 			    __u8 ndm_flags)
 {
+	struct vxlan_rdst *rd = NULL;
 	struct vxlan_fdb *f;
 	int notify = 0;
 
@@ -726,7 +726,8 @@
 		if ((flags & NLM_F_APPEND) &&
 		    (is_multicast_ether_addr(f->eth_addr) ||
 		     is_zero_ether_addr(f->eth_addr))) {
-			int rc = vxlan_fdb_append(f, ip, port, vni, ifindex);
+			int rc = vxlan_fdb_append(f, ip, port, vni, ifindex,
+						  &rd);
 
 			if (rc < 0)
 				return rc;
@@ -756,15 +757,18 @@
 		INIT_LIST_HEAD(&f->remotes);
 		memcpy(f->eth_addr, mac, ETH_ALEN);
 
-		vxlan_fdb_append(f, ip, port, vni, ifindex);
+		vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
 
 		++vxlan->addrcnt;
 		hlist_add_head_rcu(&f->hlist,
 				   vxlan_fdb_head(vxlan, mac));
 	}
 
-	if (notify)
-		vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH);
+	if (notify) {
+		if (rd == NULL)
+			rd = first_remote_rtnl(f);
+		vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH);
+	}
 
 	return 0;
 }
@@ -785,7 +789,7 @@
 		    "delete %pM\n", f->eth_addr);
 
 	--vxlan->addrcnt;
-	vxlan_fdb_notify(vxlan, f, RTM_DELNEIGH);
+	vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_DELNEIGH);
 
 	hlist_del_rcu(&f->hlist);
 	call_rcu(&f->rcu, vxlan_fdb_free);
@@ -919,6 +923,7 @@
 	 */
 	if (rd && !list_is_singular(&f->remotes)) {
 		list_del_rcu(&rd->list);
+		vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
 		kfree_rcu(rd, rcu);
 		goto out;
 	}
@@ -993,7 +998,7 @@
 
 		rdst->remote_ip = *src_ip;
 		f->updated = jiffies;
-		vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH);
+		vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH);
 	} else {
 		/* learned new entry */
 		spin_lock(&vxlan->hash_lock);
@@ -1199,6 +1204,7 @@
 
 	remote_ip = &vxlan->default_dst.remote_ip;
 	skb_reset_mac_header(skb);
+	skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev)));
 	skb->protocol = eth_type_trans(skb, vxlan->dev);
 
 	/* Ignore packet loops (and multicast echo) */
@@ -1614,7 +1620,8 @@
 			   struct dst_entry *dst, struct sk_buff *skb,
 			   struct net_device *dev, struct in6_addr *saddr,
 			   struct in6_addr *daddr, __u8 prio, __u8 ttl,
-			   __be16 src_port, __be16 dst_port, __be32 vni)
+			   __be16 src_port, __be16 dst_port, __be32 vni,
+			   bool xnet)
 {
 	struct ipv6hdr *ip6h;
 	struct vxlanhdr *vxh;
@@ -1627,7 +1634,7 @@
 		skb->encapsulation = 1;
 	}
 
-	skb_scrub_packet(skb, false);
+	skb_scrub_packet(skb, xnet);
 
 	min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
 			+ VXLAN_HLEN + sizeof(struct ipv6hdr)
@@ -1707,7 +1714,7 @@
 int vxlan_xmit_skb(struct vxlan_sock *vs,
 		   struct rtable *rt, struct sk_buff *skb,
 		   __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
-		   __be16 src_port, __be16 dst_port, __be32 vni)
+		   __be16 src_port, __be16 dst_port, __be32 vni, bool xnet)
 {
 	struct vxlanhdr *vxh;
 	struct udphdr *uh;
@@ -1756,7 +1763,7 @@
 		return err;
 
 	return iptunnel_xmit(vs->sock->sk, rt, skb, src, dst, IPPROTO_UDP,
-			     tos, ttl, df, false);
+			     tos, ttl, df, xnet);
 }
 EXPORT_SYMBOL_GPL(vxlan_xmit_skb);
 
@@ -1849,7 +1856,7 @@
 		fl4.daddr = dst->sin.sin_addr.s_addr;
 		fl4.saddr = vxlan->saddr.sin.sin_addr.s_addr;
 
-		rt = ip_route_output_key(dev_net(dev), &fl4);
+		rt = ip_route_output_key(vxlan->net, &fl4);
 		if (IS_ERR(rt)) {
 			netdev_dbg(dev, "no route to %pI4\n",
 				   &dst->sin.sin_addr.s_addr);
@@ -1870,7 +1877,7 @@
 			struct vxlan_dev *dst_vxlan;
 
 			ip_rt_put(rt);
-			dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+			dst_vxlan = vxlan_find_vni(vxlan->net, vni, dst_port);
 			if (!dst_vxlan)
 				goto tx_error;
 			vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1883,7 +1890,8 @@
 		err = vxlan_xmit_skb(vxlan->vn_sock, rt, skb,
 				     fl4.saddr, dst->sin.sin_addr.s_addr,
 				     tos, ttl, df, src_port, dst_port,
-				     htonl(vni << 8));
+				     htonl(vni << 8),
+				     !net_eq(vxlan->net, dev_net(vxlan->dev)));
 
 		if (err < 0)
 			goto rt_tx_error;
@@ -1923,7 +1931,7 @@
 			struct vxlan_dev *dst_vxlan;
 
 			dst_release(ndst);
-			dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+			dst_vxlan = vxlan_find_vni(vxlan->net, vni, dst_port);
 			if (!dst_vxlan)
 				goto tx_error;
 			vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1934,7 +1942,8 @@
 
 		err = vxlan6_xmit_skb(vxlan->vn_sock, ndst, skb,
 				      dev, &fl6.saddr, &fl6.daddr, 0, ttl,
-				      src_port, dst_port, htonl(vni << 8));
+				      src_port, dst_port, htonl(vni << 8),
+				      !net_eq(vxlan->net, dev_net(vxlan->dev)));
 #endif
 	}
 
@@ -2078,7 +2087,7 @@
 static int vxlan_init(struct net_device *dev)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
-	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+	struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
 	struct vxlan_sock *vs;
 
 	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
@@ -2086,7 +2095,7 @@
 		return -ENOMEM;
 
 	spin_lock(&vn->sock_lock);
-	vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port);
+	vs = vxlan_find_sock(vxlan->net, vxlan->dst_port);
 	if (vs) {
 		/* If we have a socket with same port already, reuse it */
 		atomic_inc(&vs->refcnt);
@@ -2168,8 +2177,8 @@
 /* Cleanup timer and forwarding table on shutdown */
 static int vxlan_stop(struct net_device *dev)
 {
-	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
 	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
 	struct vxlan_sock *vs = vxlan->vn_sock;
 
 	if (vs && vxlan_addr_multicast(&vxlan->default_dst.remote_ip) &&
@@ -2198,7 +2207,7 @@
 	struct net_device *lowerdev;
 	int max_mtu;
 
-	lowerdev = __dev_get_by_index(dev_net(dev), dst->remote_ifindex);
+	lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex);
 	if (lowerdev == NULL)
 		return eth_change_mtu(dev, new_mtu);
 
@@ -2281,7 +2290,6 @@
 
 	dev->tx_queue_len = 0;
 	dev->features	|= NETIF_F_LLTX;
-	dev->features	|= NETIF_F_NETNS_LOCAL;
 	dev->features	|= NETIF_F_SG | NETIF_F_HW_CSUM;
 	dev->features   |= NETIF_F_RXCSUM;
 	dev->features   |= NETIF_F_GSO_SOFTWARE;
@@ -2574,7 +2582,7 @@
 static void vxlan_sock_work(struct work_struct *work)
 {
 	struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, sock_work);
-	struct net *net = dev_net(vxlan->dev);
+	struct net *net = vxlan->net;
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 	__be16 port = vxlan->dst_port;
 	struct vxlan_sock *nvs;
@@ -2601,6 +2609,8 @@
 	if (!data[IFLA_VXLAN_ID])
 		return -EINVAL;
 
+	vxlan->net = dev_net(dev);
+
 	vni = nla_get_u32(data[IFLA_VXLAN_ID]);
 	dst->remote_vni = vni;
 
@@ -2735,8 +2745,8 @@
 
 static void vxlan_dellink(struct net_device *dev, struct list_head *head)
 {
-	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
 	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
 
 	spin_lock(&vn->sock_lock);
 	if (!hlist_unhashed(&vxlan->hlist))
@@ -2901,8 +2911,33 @@
 	return 0;
 }
 
+static void __net_exit vxlan_exit_net(struct net *net)
+{
+	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+	struct vxlan_dev *vxlan, *next;
+	struct net_device *dev, *aux;
+	LIST_HEAD(list);
+
+	rtnl_lock();
+	for_each_netdev_safe(net, dev, aux)
+		if (dev->rtnl_link_ops == &vxlan_link_ops)
+			unregister_netdevice_queue(dev, &list);
+
+	list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) {
+		/* If vxlan->dev is in the same netns, it has already been added
+		 * to the list by the previous loop.
+		 */
+		if (!net_eq(dev_net(vxlan->dev), net))
+			unregister_netdevice_queue(dev, &list);
+	}
+
+	unregister_netdevice_many(&list);
+	rtnl_unlock();
+}
+
 static struct pernet_operations vxlan_net_ops = {
 	.init = vxlan_init_net,
+	.exit = vxlan_exit_net,
 	.id   = &vxlan_net_id,
 	.size = sizeof(struct vxlan_net),
 };
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f72d19b..6d4ee22 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1828,17 +1828,13 @@
 		next = &(*next)->next;
 	}
 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
-	if (rc)
-		return rc;
-
-	/* Update the sysfs attribute */
-	if (oldprop)
-		sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
-	__of_add_property_sysfs(np, newprop);
-
 	if (!found)
 		return -ENODEV;
 
+	/* Update the sysfs attribute */
+	sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
+	__of_add_property_sysfs(np, newprop);
+
 	return 0;
 }
 
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index fa16a91..7a2ef7b 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -491,7 +491,7 @@
  * in /reserved-memory matches the values supported by the current implementation,
  * also check if ranges property has been provided
  */
-static int __reserved_mem_check_root(unsigned long node)
+static int __init __reserved_mem_check_root(unsigned long node)
 {
 	__be32 *prop;
 
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index fd3e3ab..4fe349d 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -180,8 +181,13 @@
 {
 	struct pci_sys_data *sys = dev->bus->sysdata;
 	struct rcar_pci_priv *priv = sys->private_data;
+	int irq;
 
-	return priv->irq;
+	irq = of_irq_parse_and_map_pci(dev, slot, pin);
+	if (!irq)
+		irq = priv->irq;
+
+	return irq;
 }
 
 #ifdef CONFIG_PCI_DEBUG
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 330f7e3..083cf37 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -639,10 +639,15 @@
 static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
 	struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata);
+	int irq;
 
 	tegra_cpuidle_pcie_irqs_in_use();
 
-	return pcie->irq;
+	irq = of_irq_parse_and_map_pci(pdev, slot, pin);
+	if (!irq)
+		irq = pcie->irq;
+
+	return irq;
 }
 
 static void tegra_pcie_add_bus(struct pci_bus *bus)
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 509a29d..c4e3732 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of_address.h>
+#include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/pci_regs.h>
 #include <linux/types.h>
@@ -490,7 +491,7 @@
 	dw_pci.nr_controllers = 1;
 	dw_pci.private_data = (void **)&pp;
 
-	pci_common_init(&dw_pci);
+	pci_common_init_dev(pp->dev, &dw_pci);
 	pci_assign_unassigned_resources();
 #ifdef CONFIG_PCI_DOMAINS
 	dw_pci.domain++;
@@ -520,13 +521,13 @@
 	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
 			  PCIE_ATU_VIEWPORT);
 	dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
-	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 	dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE);
 	dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE);
 	dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1,
 			  PCIE_ATU_LIMIT);
 	dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
 	dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
+	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 }
 
 static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
@@ -535,7 +536,6 @@
 	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
 			  PCIE_ATU_VIEWPORT);
 	dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
-	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 	dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
 	dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
 	dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
@@ -543,6 +543,7 @@
 	dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
 	dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
 			  PCIE_ATU_UPPER_TARGET);
+	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 }
 
 static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
@@ -551,7 +552,6 @@
 	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
 			  PCIE_ATU_VIEWPORT);
 	dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
-	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 	dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
 	dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
 	dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
@@ -559,6 +559,7 @@
 	dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
 	dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
 			  PCIE_ATU_UPPER_TARGET);
+	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 }
 
 static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
@@ -723,7 +724,7 @@
 
 	if (pp) {
 		pp->root_bus_nr = sys->busnr;
-		bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+		bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
 					sys, &sys->resources);
 	} else {
 		bus = NULL;
@@ -736,8 +737,13 @@
 static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
+	int irq;
 
-	return pp->irq;
+	irq = of_irq_parse_and_map_pci(dev, slot, pin);
+	if (!irq)
+		irq = pp->irq;
+
+	return irq;
 }
 
 static void dw_pcie_add_bus(struct pci_bus *bus)
@@ -764,7 +770,7 @@
 	u32 membase;
 	u32 memlimit;
 
-	/* set the number of lines as 4 */
+	/* set the number of lanes */
 	dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
 	val &= ~PORT_LINK_MODE_MASK;
 	switch (pp->lanes) {
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e493240..e00c02d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -104,16 +104,16 @@
 	select PINMUX
 	select PINCONF
 
-config PINCTRL_CAPRI
-	bool "Broadcom Capri pinctrl driver"
+config PINCTRL_BCM281XX
+	bool "Broadcom BCM281xx pinctrl driver"
 	depends on OF
 	select PINMUX
 	select PINCONF
 	select GENERIC_PINCONF
 	select REGMAP_MMIO
 	help
-	  Say Y here to support Broadcom Capri pinctrl driver, which is used for
-	  the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
+	  Say Y here to support Broadcom BCM281xx pinctrl driver, which is used
+	  for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
 	  BCM28145, and BCM28155 SoCs.  This driver requires the pinctrl
 	  framework.  GPIO is provided by a separate GPIO driver.
 
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 4b83588..6d3fd62 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -21,7 +21,7 @@
 obj-$(CONFIG_PINCTRL_AT91)	+= pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_BCM2835)	+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_BAYTRAIL)	+= pinctrl-baytrail.o
-obj-$(CONFIG_PINCTRL_CAPRI)	+= pinctrl-capri.o
+obj-$(CONFIG_PINCTRL_BCM281XX)	+= pinctrl-bcm281xx.o
 obj-$(CONFIG_PINCTRL_IMX)	+= pinctrl-imx.o
 obj-$(CONFIG_PINCTRL_IMX1_CORE)	+= pinctrl-imx1-core.o
 obj-$(CONFIG_PINCTRL_IMX27)	+= pinctrl-imx27.o
diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c
new file mode 100644
index 0000000..3bed792
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-bcm281xx.c
@@ -0,0 +1,1461 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include "core.h"
+#include "pinctrl-utils.h"
+
+/* BCM281XX Pin Control Registers Definitions */
+
+/* Function Select bits are the same for all pin control registers */
+#define BCM281XX_PIN_REG_F_SEL_MASK		0x0700
+#define BCM281XX_PIN_REG_F_SEL_SHIFT		8
+
+/* Standard pin register */
+#define BCM281XX_STD_PIN_REG_DRV_STR_MASK	0x0007
+#define BCM281XX_STD_PIN_REG_DRV_STR_SHIFT	0
+#define BCM281XX_STD_PIN_REG_INPUT_DIS_MASK	0x0008
+#define BCM281XX_STD_PIN_REG_INPUT_DIS_SHIFT	3
+#define BCM281XX_STD_PIN_REG_SLEW_MASK		0x0010
+#define BCM281XX_STD_PIN_REG_SLEW_SHIFT		4
+#define BCM281XX_STD_PIN_REG_PULL_UP_MASK	0x0020
+#define BCM281XX_STD_PIN_REG_PULL_UP_SHIFT	5
+#define BCM281XX_STD_PIN_REG_PULL_DN_MASK	0x0040
+#define BCM281XX_STD_PIN_REG_PULL_DN_SHIFT	6
+#define BCM281XX_STD_PIN_REG_HYST_MASK		0x0080
+#define BCM281XX_STD_PIN_REG_HYST_SHIFT		7
+
+/* I2C pin register */
+#define BCM281XX_I2C_PIN_REG_INPUT_DIS_MASK	0x0004
+#define BCM281XX_I2C_PIN_REG_INPUT_DIS_SHIFT	2
+#define BCM281XX_I2C_PIN_REG_SLEW_MASK		0x0008
+#define BCM281XX_I2C_PIN_REG_SLEW_SHIFT		3
+#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_MASK	0x0070
+#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_SHIFT	4
+
+/* HDMI pin register */
+#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_MASK	0x0008
+#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_SHIFT	3
+#define BCM281XX_HDMI_PIN_REG_MODE_MASK		0x0010
+#define BCM281XX_HDMI_PIN_REG_MODE_SHIFT	4
+
+/**
+ * bcm281xx_pin_type - types of pin register
+ */
+enum bcm281xx_pin_type {
+	BCM281XX_PIN_TYPE_UNKNOWN = 0,
+	BCM281XX_PIN_TYPE_STD,
+	BCM281XX_PIN_TYPE_I2C,
+	BCM281XX_PIN_TYPE_HDMI,
+};
+
+static enum bcm281xx_pin_type std_pin = BCM281XX_PIN_TYPE_STD;
+static enum bcm281xx_pin_type i2c_pin = BCM281XX_PIN_TYPE_I2C;
+static enum bcm281xx_pin_type hdmi_pin = BCM281XX_PIN_TYPE_HDMI;
+
+/**
+ * bcm281xx_pin_function- define pin function
+ */
+struct bcm281xx_pin_function {
+	const char *name;
+	const char * const *groups;
+	const unsigned ngroups;
+};
+
+/**
+ * bcm281xx_pinctrl_data - Broadcom-specific pinctrl data
+ * @reg_base - base of pinctrl registers
+ */
+struct bcm281xx_pinctrl_data {
+	void __iomem *reg_base;
+
+	/* List of all pins */
+	const struct pinctrl_pin_desc *pins;
+	const unsigned npins;
+
+	const struct bcm281xx_pin_function *functions;
+	const unsigned nfunctions;
+
+	struct regmap *regmap;
+};
+
+/*
+ * Pin number definition.  The order here must be the same as defined in the
+ * PADCTRLREG block in the RDB.
+ */
+#define BCM281XX_PIN_ADCSYNC		0
+#define BCM281XX_PIN_BAT_RM		1
+#define BCM281XX_PIN_BSC1_SCL		2
+#define BCM281XX_PIN_BSC1_SDA		3
+#define BCM281XX_PIN_BSC2_SCL		4
+#define BCM281XX_PIN_BSC2_SDA		5
+#define BCM281XX_PIN_CLASSGPWR		6
+#define BCM281XX_PIN_CLK_CX8		7
+#define BCM281XX_PIN_CLKOUT_0		8
+#define BCM281XX_PIN_CLKOUT_1		9
+#define BCM281XX_PIN_CLKOUT_2		10
+#define BCM281XX_PIN_CLKOUT_3		11
+#define BCM281XX_PIN_CLKREQ_IN_0	12
+#define BCM281XX_PIN_CLKREQ_IN_1	13
+#define BCM281XX_PIN_CWS_SYS_REQ1	14
+#define BCM281XX_PIN_CWS_SYS_REQ2	15
+#define BCM281XX_PIN_CWS_SYS_REQ3	16
+#define BCM281XX_PIN_DIGMIC1_CLK	17
+#define BCM281XX_PIN_DIGMIC1_DQ		18
+#define BCM281XX_PIN_DIGMIC2_CLK	19
+#define BCM281XX_PIN_DIGMIC2_DQ		20
+#define BCM281XX_PIN_GPEN13		21
+#define BCM281XX_PIN_GPEN14		22
+#define BCM281XX_PIN_GPEN15		23
+#define BCM281XX_PIN_GPIO00		24
+#define BCM281XX_PIN_GPIO01		25
+#define BCM281XX_PIN_GPIO02		26
+#define BCM281XX_PIN_GPIO03		27
+#define BCM281XX_PIN_GPIO04		28
+#define BCM281XX_PIN_GPIO05		29
+#define BCM281XX_PIN_GPIO06		30
+#define BCM281XX_PIN_GPIO07		31
+#define BCM281XX_PIN_GPIO08		32
+#define BCM281XX_PIN_GPIO09		33
+#define BCM281XX_PIN_GPIO10		34
+#define BCM281XX_PIN_GPIO11		35
+#define BCM281XX_PIN_GPIO12		36
+#define BCM281XX_PIN_GPIO13		37
+#define BCM281XX_PIN_GPIO14		38
+#define BCM281XX_PIN_GPS_PABLANK	39
+#define BCM281XX_PIN_GPS_TMARK		40
+#define BCM281XX_PIN_HDMI_SCL		41
+#define BCM281XX_PIN_HDMI_SDA		42
+#define BCM281XX_PIN_IC_DM		43
+#define BCM281XX_PIN_IC_DP		44
+#define BCM281XX_PIN_KP_COL_IP_0	45
+#define BCM281XX_PIN_KP_COL_IP_1	46
+#define BCM281XX_PIN_KP_COL_IP_2	47
+#define BCM281XX_PIN_KP_COL_IP_3	48
+#define BCM281XX_PIN_KP_ROW_OP_0	49
+#define BCM281XX_PIN_KP_ROW_OP_1	50
+#define BCM281XX_PIN_KP_ROW_OP_2	51
+#define BCM281XX_PIN_KP_ROW_OP_3	52
+#define BCM281XX_PIN_LCD_B_0		53
+#define BCM281XX_PIN_LCD_B_1		54
+#define BCM281XX_PIN_LCD_B_2		55
+#define BCM281XX_PIN_LCD_B_3		56
+#define BCM281XX_PIN_LCD_B_4		57
+#define BCM281XX_PIN_LCD_B_5		58
+#define BCM281XX_PIN_LCD_B_6		59
+#define BCM281XX_PIN_LCD_B_7		60
+#define BCM281XX_PIN_LCD_G_0		61
+#define BCM281XX_PIN_LCD_G_1		62
+#define BCM281XX_PIN_LCD_G_2		63
+#define BCM281XX_PIN_LCD_G_3		64
+#define BCM281XX_PIN_LCD_G_4		65
+#define BCM281XX_PIN_LCD_G_5		66
+#define BCM281XX_PIN_LCD_G_6		67
+#define BCM281XX_PIN_LCD_G_7		68
+#define BCM281XX_PIN_LCD_HSYNC		69
+#define BCM281XX_PIN_LCD_OE		70
+#define BCM281XX_PIN_LCD_PCLK		71
+#define BCM281XX_PIN_LCD_R_0		72
+#define BCM281XX_PIN_LCD_R_1		73
+#define BCM281XX_PIN_LCD_R_2		74
+#define BCM281XX_PIN_LCD_R_3		75
+#define BCM281XX_PIN_LCD_R_4		76
+#define BCM281XX_PIN_LCD_R_5		77
+#define BCM281XX_PIN_LCD_R_6		78
+#define BCM281XX_PIN_LCD_R_7		79
+#define BCM281XX_PIN_LCD_VSYNC		80
+#define BCM281XX_PIN_MDMGPIO0		81
+#define BCM281XX_PIN_MDMGPIO1		82
+#define BCM281XX_PIN_MDMGPIO2		83
+#define BCM281XX_PIN_MDMGPIO3		84
+#define BCM281XX_PIN_MDMGPIO4		85
+#define BCM281XX_PIN_MDMGPIO5		86
+#define BCM281XX_PIN_MDMGPIO6		87
+#define BCM281XX_PIN_MDMGPIO7		88
+#define BCM281XX_PIN_MDMGPIO8		89
+#define BCM281XX_PIN_MPHI_DATA_0	90
+#define BCM281XX_PIN_MPHI_DATA_1	91
+#define BCM281XX_PIN_MPHI_DATA_2	92
+#define BCM281XX_PIN_MPHI_DATA_3	93
+#define BCM281XX_PIN_MPHI_DATA_4	94
+#define BCM281XX_PIN_MPHI_DATA_5	95
+#define BCM281XX_PIN_MPHI_DATA_6	96
+#define BCM281XX_PIN_MPHI_DATA_7	97
+#define BCM281XX_PIN_MPHI_DATA_8	98
+#define BCM281XX_PIN_MPHI_DATA_9	99
+#define BCM281XX_PIN_MPHI_DATA_10	100
+#define BCM281XX_PIN_MPHI_DATA_11	101
+#define BCM281XX_PIN_MPHI_DATA_12	102
+#define BCM281XX_PIN_MPHI_DATA_13	103
+#define BCM281XX_PIN_MPHI_DATA_14	104
+#define BCM281XX_PIN_MPHI_DATA_15	105
+#define BCM281XX_PIN_MPHI_HA0		106
+#define BCM281XX_PIN_MPHI_HAT0		107
+#define BCM281XX_PIN_MPHI_HAT1		108
+#define BCM281XX_PIN_MPHI_HCE0_N	109
+#define BCM281XX_PIN_MPHI_HCE1_N	110
+#define BCM281XX_PIN_MPHI_HRD_N		111
+#define BCM281XX_PIN_MPHI_HWR_N		112
+#define BCM281XX_PIN_MPHI_RUN0		113
+#define BCM281XX_PIN_MPHI_RUN1		114
+#define BCM281XX_PIN_MTX_SCAN_CLK	115
+#define BCM281XX_PIN_MTX_SCAN_DATA	116
+#define BCM281XX_PIN_NAND_AD_0		117
+#define BCM281XX_PIN_NAND_AD_1		118
+#define BCM281XX_PIN_NAND_AD_2		119
+#define BCM281XX_PIN_NAND_AD_3		120
+#define BCM281XX_PIN_NAND_AD_4		121
+#define BCM281XX_PIN_NAND_AD_5		122
+#define BCM281XX_PIN_NAND_AD_6		123
+#define BCM281XX_PIN_NAND_AD_7		124
+#define BCM281XX_PIN_NAND_ALE		125
+#define BCM281XX_PIN_NAND_CEN_0		126
+#define BCM281XX_PIN_NAND_CEN_1		127
+#define BCM281XX_PIN_NAND_CLE		128
+#define BCM281XX_PIN_NAND_OEN		129
+#define BCM281XX_PIN_NAND_RDY_0		130
+#define BCM281XX_PIN_NAND_RDY_1		131
+#define BCM281XX_PIN_NAND_WEN		132
+#define BCM281XX_PIN_NAND_WP		133
+#define BCM281XX_PIN_PC1		134
+#define BCM281XX_PIN_PC2		135
+#define BCM281XX_PIN_PMU_INT		136
+#define BCM281XX_PIN_PMU_SCL		137
+#define BCM281XX_PIN_PMU_SDA		138
+#define BCM281XX_PIN_RFST2G_MTSLOTEN3G	139
+#define BCM281XX_PIN_RGMII_0_RX_CTL	140
+#define BCM281XX_PIN_RGMII_0_RXC	141
+#define BCM281XX_PIN_RGMII_0_RXD_0	142
+#define BCM281XX_PIN_RGMII_0_RXD_1	143
+#define BCM281XX_PIN_RGMII_0_RXD_2	144
+#define BCM281XX_PIN_RGMII_0_RXD_3	145
+#define BCM281XX_PIN_RGMII_0_TX_CTL	146
+#define BCM281XX_PIN_RGMII_0_TXC	147
+#define BCM281XX_PIN_RGMII_0_TXD_0	148
+#define BCM281XX_PIN_RGMII_0_TXD_1	149
+#define BCM281XX_PIN_RGMII_0_TXD_2	150
+#define BCM281XX_PIN_RGMII_0_TXD_3	151
+#define BCM281XX_PIN_RGMII_1_RX_CTL	152
+#define BCM281XX_PIN_RGMII_1_RXC	153
+#define BCM281XX_PIN_RGMII_1_RXD_0	154
+#define BCM281XX_PIN_RGMII_1_RXD_1	155
+#define BCM281XX_PIN_RGMII_1_RXD_2	156
+#define BCM281XX_PIN_RGMII_1_RXD_3	157
+#define BCM281XX_PIN_RGMII_1_TX_CTL	158
+#define BCM281XX_PIN_RGMII_1_TXC	159
+#define BCM281XX_PIN_RGMII_1_TXD_0	160
+#define BCM281XX_PIN_RGMII_1_TXD_1	161
+#define BCM281XX_PIN_RGMII_1_TXD_2	162
+#define BCM281XX_PIN_RGMII_1_TXD_3	163
+#define BCM281XX_PIN_RGMII_GPIO_0	164
+#define BCM281XX_PIN_RGMII_GPIO_1	165
+#define BCM281XX_PIN_RGMII_GPIO_2	166
+#define BCM281XX_PIN_RGMII_GPIO_3	167
+#define BCM281XX_PIN_RTXDATA2G_TXDATA3G1	168
+#define BCM281XX_PIN_RTXEN2G_TXDATA3G2	169
+#define BCM281XX_PIN_RXDATA3G0		170
+#define BCM281XX_PIN_RXDATA3G1		171
+#define BCM281XX_PIN_RXDATA3G2		172
+#define BCM281XX_PIN_SDIO1_CLK		173
+#define BCM281XX_PIN_SDIO1_CMD		174
+#define BCM281XX_PIN_SDIO1_DATA_0	175
+#define BCM281XX_PIN_SDIO1_DATA_1	176
+#define BCM281XX_PIN_SDIO1_DATA_2	177
+#define BCM281XX_PIN_SDIO1_DATA_3	178
+#define BCM281XX_PIN_SDIO4_CLK		179
+#define BCM281XX_PIN_SDIO4_CMD		180
+#define BCM281XX_PIN_SDIO4_DATA_0	181
+#define BCM281XX_PIN_SDIO4_DATA_1	182
+#define BCM281XX_PIN_SDIO4_DATA_2	183
+#define BCM281XX_PIN_SDIO4_DATA_3	184
+#define BCM281XX_PIN_SIM_CLK		185
+#define BCM281XX_PIN_SIM_DATA		186
+#define BCM281XX_PIN_SIM_DET		187
+#define BCM281XX_PIN_SIM_RESETN		188
+#define BCM281XX_PIN_SIM2_CLK		189
+#define BCM281XX_PIN_SIM2_DATA		190
+#define BCM281XX_PIN_SIM2_DET		191
+#define BCM281XX_PIN_SIM2_RESETN	192
+#define BCM281XX_PIN_SRI_C		193
+#define BCM281XX_PIN_SRI_D		194
+#define BCM281XX_PIN_SRI_E		195
+#define BCM281XX_PIN_SSP_EXTCLK		196
+#define BCM281XX_PIN_SSP0_CLK		197
+#define BCM281XX_PIN_SSP0_FS		198
+#define BCM281XX_PIN_SSP0_RXD		199
+#define BCM281XX_PIN_SSP0_TXD		200
+#define BCM281XX_PIN_SSP2_CLK		201
+#define BCM281XX_PIN_SSP2_FS_0		202
+#define BCM281XX_PIN_SSP2_FS_1		203
+#define BCM281XX_PIN_SSP2_FS_2		204
+#define BCM281XX_PIN_SSP2_FS_3		205
+#define BCM281XX_PIN_SSP2_RXD_0		206
+#define BCM281XX_PIN_SSP2_RXD_1		207
+#define BCM281XX_PIN_SSP2_TXD_0		208
+#define BCM281XX_PIN_SSP2_TXD_1		209
+#define BCM281XX_PIN_SSP3_CLK		210
+#define BCM281XX_PIN_SSP3_FS		211
+#define BCM281XX_PIN_SSP3_RXD		212
+#define BCM281XX_PIN_SSP3_TXD		213
+#define BCM281XX_PIN_SSP4_CLK		214
+#define BCM281XX_PIN_SSP4_FS		215
+#define BCM281XX_PIN_SSP4_RXD		216
+#define BCM281XX_PIN_SSP4_TXD		217
+#define BCM281XX_PIN_SSP5_CLK		218
+#define BCM281XX_PIN_SSP5_FS		219
+#define BCM281XX_PIN_SSP5_RXD		220
+#define BCM281XX_PIN_SSP5_TXD		221
+#define BCM281XX_PIN_SSP6_CLK		222
+#define BCM281XX_PIN_SSP6_FS		223
+#define BCM281XX_PIN_SSP6_RXD		224
+#define BCM281XX_PIN_SSP6_TXD		225
+#define BCM281XX_PIN_STAT_1		226
+#define BCM281XX_PIN_STAT_2		227
+#define BCM281XX_PIN_SYSCLKEN		228
+#define BCM281XX_PIN_TRACECLK		229
+#define BCM281XX_PIN_TRACEDT00		230
+#define BCM281XX_PIN_TRACEDT01		231
+#define BCM281XX_PIN_TRACEDT02		232
+#define BCM281XX_PIN_TRACEDT03		233
+#define BCM281XX_PIN_TRACEDT04		234
+#define BCM281XX_PIN_TRACEDT05		235
+#define BCM281XX_PIN_TRACEDT06		236
+#define BCM281XX_PIN_TRACEDT07		237
+#define BCM281XX_PIN_TRACEDT08		238
+#define BCM281XX_PIN_TRACEDT09		239
+#define BCM281XX_PIN_TRACEDT10		240
+#define BCM281XX_PIN_TRACEDT11		241
+#define BCM281XX_PIN_TRACEDT12		242
+#define BCM281XX_PIN_TRACEDT13		243
+#define BCM281XX_PIN_TRACEDT14		244
+#define BCM281XX_PIN_TRACEDT15		245
+#define BCM281XX_PIN_TXDATA3G0		246
+#define BCM281XX_PIN_TXPWRIND		247
+#define BCM281XX_PIN_UARTB1_UCTS	248
+#define BCM281XX_PIN_UARTB1_URTS	249
+#define BCM281XX_PIN_UARTB1_URXD	250
+#define BCM281XX_PIN_UARTB1_UTXD	251
+#define BCM281XX_PIN_UARTB2_URXD	252
+#define BCM281XX_PIN_UARTB2_UTXD	253
+#define BCM281XX_PIN_UARTB3_UCTS	254
+#define BCM281XX_PIN_UARTB3_URTS	255
+#define BCM281XX_PIN_UARTB3_URXD	256
+#define BCM281XX_PIN_UARTB3_UTXD	257
+#define BCM281XX_PIN_UARTB4_UCTS	258
+#define BCM281XX_PIN_UARTB4_URTS	259
+#define BCM281XX_PIN_UARTB4_URXD	260
+#define BCM281XX_PIN_UARTB4_UTXD	261
+#define BCM281XX_PIN_VC_CAM1_SCL	262
+#define BCM281XX_PIN_VC_CAM1_SDA	263
+#define BCM281XX_PIN_VC_CAM2_SCL	264
+#define BCM281XX_PIN_VC_CAM2_SDA	265
+#define BCM281XX_PIN_VC_CAM3_SCL	266
+#define BCM281XX_PIN_VC_CAM3_SDA	267
+
+#define BCM281XX_PIN_DESC(a, b, c) \
+	{ .number = a, .name = b, .drv_data = &c##_pin }
+
+/*
+ * Pin description definition.  The order here must be the same as defined in
+ * the PADCTRLREG block in the RDB, since the pin number is used as an index
+ * into this array.
+ */
+static const struct pinctrl_pin_desc bcm281xx_pinctrl_pins[] = {
+	BCM281XX_PIN_DESC(BCM281XX_PIN_ADCSYNC, "adcsync", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_BAT_RM, "bat_rm", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SCL, "bsc1_scl", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SDA, "bsc1_sda", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SCL, "bsc2_scl", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SDA, "bsc2_sda", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLASSGPWR, "classgpwr", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLK_CX8, "clk_cx8", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_0, "clkout_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_1, "clkout_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_2, "clkout_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_3, "clkout_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_0, "clkreq_in_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_1, "clkreq_in_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ1, "cws_sys_req1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ2, "cws_sys_req2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ3, "cws_sys_req3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_CLK, "digmic1_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_DQ, "digmic1_dq", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_CLK, "digmic2_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_DQ, "digmic2_dq", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN13, "gpen13", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN14, "gpen14", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN15, "gpen15", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO00, "gpio00", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO01, "gpio01", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO02, "gpio02", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO03, "gpio03", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO04, "gpio04", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO05, "gpio05", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO06, "gpio06", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO07, "gpio07", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO08, "gpio08", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO09, "gpio09", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO10, "gpio10", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO11, "gpio11", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO12, "gpio12", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO13, "gpio13", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO14, "gpio14", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_PABLANK, "gps_pablank", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_TMARK, "gps_tmark", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SCL, "hdmi_scl", hdmi),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SDA, "hdmi_sda", hdmi),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DM, "ic_dm", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DP, "ic_dp", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_0, "kp_col_ip_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_1, "kp_col_ip_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_2, "kp_col_ip_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_3, "kp_col_ip_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_0, "kp_row_op_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_1, "kp_row_op_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_2, "kp_row_op_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_3, "kp_row_op_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_0, "lcd_b_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_1, "lcd_b_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_2, "lcd_b_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_3, "lcd_b_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_4, "lcd_b_4", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_5, "lcd_b_5", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_6, "lcd_b_6", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_7, "lcd_b_7", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_0, "lcd_g_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_1, "lcd_g_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_2, "lcd_g_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_3, "lcd_g_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_4, "lcd_g_4", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_5, "lcd_g_5", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_6, "lcd_g_6", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_7, "lcd_g_7", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_HSYNC, "lcd_hsync", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_OE, "lcd_oe", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_PCLK, "lcd_pclk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_0, "lcd_r_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_1, "lcd_r_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_2, "lcd_r_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_3, "lcd_r_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_4, "lcd_r_4", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_5, "lcd_r_5", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_6, "lcd_r_6", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_7, "lcd_r_7", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_VSYNC, "lcd_vsync", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO0, "mdmgpio0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO1, "mdmgpio1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO2, "mdmgpio2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO3, "mdmgpio3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO4, "mdmgpio4", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO5, "mdmgpio5", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO6, "mdmgpio6", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO7, "mdmgpio7", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO8, "mdmgpio8", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_0, "mphi_data_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_1, "mphi_data_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_2, "mphi_data_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_3, "mphi_data_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_4, "mphi_data_4", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_5, "mphi_data_5", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_6, "mphi_data_6", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_7, "mphi_data_7", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_8, "mphi_data_8", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_9, "mphi_data_9", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_10, "mphi_data_10", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_11, "mphi_data_11", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_12, "mphi_data_12", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_13, "mphi_data_13", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_14, "mphi_data_14", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_15, "mphi_data_15", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HA0, "mphi_ha0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT0, "mphi_hat0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT1, "mphi_hat1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE0_N, "mphi_hce0_n", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE1_N, "mphi_hce1_n", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HRD_N, "mphi_hrd_n", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HWR_N, "mphi_hwr_n", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN0, "mphi_run0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN1, "mphi_run1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_DATA, "mtx_scan_data", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_0, "nand_ad_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_1, "nand_ad_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_2, "nand_ad_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_3, "nand_ad_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_4, "nand_ad_4", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_5, "nand_ad_5", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_6, "nand_ad_6", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_7, "nand_ad_7", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_ALE, "nand_ale", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_0, "nand_cen_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_1, "nand_cen_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CLE, "nand_cle", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_OEN, "nand_oen", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_0, "nand_rdy_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_1, "nand_rdy_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WEN, "nand_wen", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WP, "nand_wp", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_PC1, "pc1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_PC2, "pc2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_INT, "pmu_int", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SCL, "pmu_scl", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SDA, "pmu_sda", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g",
+		std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXC, "rgmii_0_rxc", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXC, "rgmii_0_txc", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXC, "rgmii_1_rxc", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXC, "rgmii_1_txc", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RTXDATA2G_TXDATA3G1,
+		"rtxdata2g_txdata3g1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2",
+		std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G0, "rxdata3g0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G1, "rxdata3g1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G2, "rxdata3g2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CLK, "sdio1_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CMD, "sdio1_cmd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_0, "sdio1_data_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_1, "sdio1_data_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_2, "sdio1_data_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_3, "sdio1_data_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CLK, "sdio4_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CMD, "sdio4_cmd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_0, "sdio4_data_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_1, "sdio4_data_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_2, "sdio4_data_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_3, "sdio4_data_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_CLK, "sim_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DATA, "sim_data", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DET, "sim_det", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_RESETN, "sim_resetn", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_CLK, "sim2_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DATA, "sim2_data", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DET, "sim2_det", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_RESETN, "sim2_resetn", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_C, "sri_c", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_D, "sri_d", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_E, "sri_e", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP_EXTCLK, "ssp_extclk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_CLK, "ssp0_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_FS, "ssp0_fs", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_RXD, "ssp0_rxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_TXD, "ssp0_txd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_CLK, "ssp2_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_0, "ssp2_fs_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_1, "ssp2_fs_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_2, "ssp2_fs_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_3, "ssp2_fs_3", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_0, "ssp2_rxd_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_1, "ssp2_rxd_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_0, "ssp2_txd_0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_1, "ssp2_txd_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_CLK, "ssp3_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_FS, "ssp3_fs", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_RXD, "ssp3_rxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_TXD, "ssp3_txd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_CLK, "ssp4_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_FS, "ssp4_fs", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_RXD, "ssp4_rxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_TXD, "ssp4_txd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_CLK, "ssp5_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_FS, "ssp5_fs", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_RXD, "ssp5_rxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_TXD, "ssp5_txd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_CLK, "ssp6_clk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_FS, "ssp6_fs", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_RXD, "ssp6_rxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_TXD, "ssp6_txd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_1, "stat_1", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_2, "stat_2", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_SYSCLKEN, "sysclken", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACECLK, "traceclk", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT00, "tracedt00", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT01, "tracedt01", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT02, "tracedt02", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT03, "tracedt03", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT04, "tracedt04", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT05, "tracedt05", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT06, "tracedt06", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT07, "tracedt07", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT08, "tracedt08", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT09, "tracedt09", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT10, "tracedt10", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT11, "tracedt11", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT12, "tracedt12", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT13, "tracedt13", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT14, "tracedt14", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT15, "tracedt15", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TXDATA3G0, "txdata3g0", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_TXPWRIND, "txpwrind", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UCTS, "uartb1_ucts", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URTS, "uartb1_urts", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URXD, "uartb1_urxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UTXD, "uartb1_utxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_URXD, "uartb2_urxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_UTXD, "uartb2_utxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UCTS, "uartb3_ucts", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URTS, "uartb3_urts", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URXD, "uartb3_urxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UTXD, "uartb3_utxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UCTS, "uartb4_ucts", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URTS, "uartb4_urts", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URXD, "uartb4_urxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UTXD, "uartb4_utxd", std),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c),
+	BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c),
+};
+
+static const char * const bcm281xx_alt_groups[] = {
+	"adcsync",
+	"bat_rm",
+	"bsc1_scl",
+	"bsc1_sda",
+	"bsc2_scl",
+	"bsc2_sda",
+	"classgpwr",
+	"clk_cx8",
+	"clkout_0",
+	"clkout_1",
+	"clkout_2",
+	"clkout_3",
+	"clkreq_in_0",
+	"clkreq_in_1",
+	"cws_sys_req1",
+	"cws_sys_req2",
+	"cws_sys_req3",
+	"digmic1_clk",
+	"digmic1_dq",
+	"digmic2_clk",
+	"digmic2_dq",
+	"gpen13",
+	"gpen14",
+	"gpen15",
+	"gpio00",
+	"gpio01",
+	"gpio02",
+	"gpio03",
+	"gpio04",
+	"gpio05",
+	"gpio06",
+	"gpio07",
+	"gpio08",
+	"gpio09",
+	"gpio10",
+	"gpio11",
+	"gpio12",
+	"gpio13",
+	"gpio14",
+	"gps_pablank",
+	"gps_tmark",
+	"hdmi_scl",
+	"hdmi_sda",
+	"ic_dm",
+	"ic_dp",
+	"kp_col_ip_0",
+	"kp_col_ip_1",
+	"kp_col_ip_2",
+	"kp_col_ip_3",
+	"kp_row_op_0",
+	"kp_row_op_1",
+	"kp_row_op_2",
+	"kp_row_op_3",
+	"lcd_b_0",
+	"lcd_b_1",
+	"lcd_b_2",
+	"lcd_b_3",
+	"lcd_b_4",
+	"lcd_b_5",
+	"lcd_b_6",
+	"lcd_b_7",
+	"lcd_g_0",
+	"lcd_g_1",
+	"lcd_g_2",
+	"lcd_g_3",
+	"lcd_g_4",
+	"lcd_g_5",
+	"lcd_g_6",
+	"lcd_g_7",
+	"lcd_hsync",
+	"lcd_oe",
+	"lcd_pclk",
+	"lcd_r_0",
+	"lcd_r_1",
+	"lcd_r_2",
+	"lcd_r_3",
+	"lcd_r_4",
+	"lcd_r_5",
+	"lcd_r_6",
+	"lcd_r_7",
+	"lcd_vsync",
+	"mdmgpio0",
+	"mdmgpio1",
+	"mdmgpio2",
+	"mdmgpio3",
+	"mdmgpio4",
+	"mdmgpio5",
+	"mdmgpio6",
+	"mdmgpio7",
+	"mdmgpio8",
+	"mphi_data_0",
+	"mphi_data_1",
+	"mphi_data_2",
+	"mphi_data_3",
+	"mphi_data_4",
+	"mphi_data_5",
+	"mphi_data_6",
+	"mphi_data_7",
+	"mphi_data_8",
+	"mphi_data_9",
+	"mphi_data_10",
+	"mphi_data_11",
+	"mphi_data_12",
+	"mphi_data_13",
+	"mphi_data_14",
+	"mphi_data_15",
+	"mphi_ha0",
+	"mphi_hat0",
+	"mphi_hat1",
+	"mphi_hce0_n",
+	"mphi_hce1_n",
+	"mphi_hrd_n",
+	"mphi_hwr_n",
+	"mphi_run0",
+	"mphi_run1",
+	"mtx_scan_clk",
+	"mtx_scan_data",
+	"nand_ad_0",
+	"nand_ad_1",
+	"nand_ad_2",
+	"nand_ad_3",
+	"nand_ad_4",
+	"nand_ad_5",
+	"nand_ad_6",
+	"nand_ad_7",
+	"nand_ale",
+	"nand_cen_0",
+	"nand_cen_1",
+	"nand_cle",
+	"nand_oen",
+	"nand_rdy_0",
+	"nand_rdy_1",
+	"nand_wen",
+	"nand_wp",
+	"pc1",
+	"pc2",
+	"pmu_int",
+	"pmu_scl",
+	"pmu_sda",
+	"rfst2g_mtsloten3g",
+	"rgmii_0_rx_ctl",
+	"rgmii_0_rxc",
+	"rgmii_0_rxd_0",
+	"rgmii_0_rxd_1",
+	"rgmii_0_rxd_2",
+	"rgmii_0_rxd_3",
+	"rgmii_0_tx_ctl",
+	"rgmii_0_txc",
+	"rgmii_0_txd_0",
+	"rgmii_0_txd_1",
+	"rgmii_0_txd_2",
+	"rgmii_0_txd_3",
+	"rgmii_1_rx_ctl",
+	"rgmii_1_rxc",
+	"rgmii_1_rxd_0",
+	"rgmii_1_rxd_1",
+	"rgmii_1_rxd_2",
+	"rgmii_1_rxd_3",
+	"rgmii_1_tx_ctl",
+	"rgmii_1_txc",
+	"rgmii_1_txd_0",
+	"rgmii_1_txd_1",
+	"rgmii_1_txd_2",
+	"rgmii_1_txd_3",
+	"rgmii_gpio_0",
+	"rgmii_gpio_1",
+	"rgmii_gpio_2",
+	"rgmii_gpio_3",
+	"rtxdata2g_txdata3g1",
+	"rtxen2g_txdata3g2",
+	"rxdata3g0",
+	"rxdata3g1",
+	"rxdata3g2",
+	"sdio1_clk",
+	"sdio1_cmd",
+	"sdio1_data_0",
+	"sdio1_data_1",
+	"sdio1_data_2",
+	"sdio1_data_3",
+	"sdio4_clk",
+	"sdio4_cmd",
+	"sdio4_data_0",
+	"sdio4_data_1",
+	"sdio4_data_2",
+	"sdio4_data_3",
+	"sim_clk",
+	"sim_data",
+	"sim_det",
+	"sim_resetn",
+	"sim2_clk",
+	"sim2_data",
+	"sim2_det",
+	"sim2_resetn",
+	"sri_c",
+	"sri_d",
+	"sri_e",
+	"ssp_extclk",
+	"ssp0_clk",
+	"ssp0_fs",
+	"ssp0_rxd",
+	"ssp0_txd",
+	"ssp2_clk",
+	"ssp2_fs_0",
+	"ssp2_fs_1",
+	"ssp2_fs_2",
+	"ssp2_fs_3",
+	"ssp2_rxd_0",
+	"ssp2_rxd_1",
+	"ssp2_txd_0",
+	"ssp2_txd_1",
+	"ssp3_clk",
+	"ssp3_fs",
+	"ssp3_rxd",
+	"ssp3_txd",
+	"ssp4_clk",
+	"ssp4_fs",
+	"ssp4_rxd",
+	"ssp4_txd",
+	"ssp5_clk",
+	"ssp5_fs",
+	"ssp5_rxd",
+	"ssp5_txd",
+	"ssp6_clk",
+	"ssp6_fs",
+	"ssp6_rxd",
+	"ssp6_txd",
+	"stat_1",
+	"stat_2",
+	"sysclken",
+	"traceclk",
+	"tracedt00",
+	"tracedt01",
+	"tracedt02",
+	"tracedt03",
+	"tracedt04",
+	"tracedt05",
+	"tracedt06",
+	"tracedt07",
+	"tracedt08",
+	"tracedt09",
+	"tracedt10",
+	"tracedt11",
+	"tracedt12",
+	"tracedt13",
+	"tracedt14",
+	"tracedt15",
+	"txdata3g0",
+	"txpwrind",
+	"uartb1_ucts",
+	"uartb1_urts",
+	"uartb1_urxd",
+	"uartb1_utxd",
+	"uartb2_urxd",
+	"uartb2_utxd",
+	"uartb3_ucts",
+	"uartb3_urts",
+	"uartb3_urxd",
+	"uartb3_utxd",
+	"uartb4_ucts",
+	"uartb4_urts",
+	"uartb4_urxd",
+	"uartb4_utxd",
+	"vc_cam1_scl",
+	"vc_cam1_sda",
+	"vc_cam2_scl",
+	"vc_cam2_sda",
+	"vc_cam3_scl",
+	"vc_cam3_sda",
+};
+
+/* Every pin can implement all ALT1-ALT4 functions */
+#define BCM281XX_PIN_FUNCTION(fcn_name)			\
+{							\
+	.name = #fcn_name,				\
+	.groups = bcm281xx_alt_groups,			\
+	.ngroups = ARRAY_SIZE(bcm281xx_alt_groups),	\
+}
+
+static const struct bcm281xx_pin_function bcm281xx_functions[] = {
+	BCM281XX_PIN_FUNCTION(alt1),
+	BCM281XX_PIN_FUNCTION(alt2),
+	BCM281XX_PIN_FUNCTION(alt3),
+	BCM281XX_PIN_FUNCTION(alt4),
+};
+
+static struct bcm281xx_pinctrl_data bcm281xx_pinctrl = {
+	.pins = bcm281xx_pinctrl_pins,
+	.npins = ARRAY_SIZE(bcm281xx_pinctrl_pins),
+	.functions = bcm281xx_functions,
+	.nfunctions = ARRAY_SIZE(bcm281xx_functions),
+};
+
+static inline enum bcm281xx_pin_type pin_type_get(struct pinctrl_dev *pctldev,
+						  unsigned pin)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+	if (pin >= pdata->npins)
+		return BCM281XX_PIN_TYPE_UNKNOWN;
+
+	return *(enum bcm281xx_pin_type *)(pdata->pins[pin].drv_data);
+}
+
+#define BCM281XX_PIN_SHIFT(type, param) \
+	(BCM281XX_ ## type ## _PIN_REG_ ## param ## _SHIFT)
+
+#define BCM281XX_PIN_MASK(type, param) \
+	(BCM281XX_ ## type ## _PIN_REG_ ## param ## _MASK)
+
+/*
+ * This helper function is used to build up the value and mask used to write to
+ * a pin register, but does not actually write to the register.
+ */
+static inline void bcm281xx_pin_update(u32 *reg_val, u32 *reg_mask,
+				       u32 param_val, u32 param_shift,
+				       u32 param_mask)
+{
+	*reg_val &= ~param_mask;
+	*reg_val |= (param_val << param_shift) & param_mask;
+	*reg_mask |= param_mask;
+}
+
+static struct regmap_config bcm281xx_pinctrl_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = BCM281XX_PIN_VC_CAM3_SDA,
+};
+
+static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+	return pdata->npins;
+}
+
+static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						   unsigned group)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+	return pdata->pins[group].name;
+}
+
+static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					   unsigned group,
+					   const unsigned **pins,
+					   unsigned *num_pins)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = &pdata->pins[group].number;
+	*num_pins = 1;
+
+	return 0;
+}
+
+static void bcm281xx_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+					  struct seq_file *s,
+					  unsigned offset)
+{
+	seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+
+static struct pinctrl_ops bcm281xx_pinctrl_ops = {
+	.get_groups_count = bcm281xx_pinctrl_get_groups_count,
+	.get_group_name = bcm281xx_pinctrl_get_group_name,
+	.get_group_pins = bcm281xx_pinctrl_get_group_pins,
+	.pin_dbg_show = bcm281xx_pinctrl_pin_dbg_show,
+	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+	.dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+	return pdata->nfunctions;
+}
+
+static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
+						 unsigned function)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+	return pdata->functions[function].name;
+}
+
+static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
+					   unsigned function,
+					   const char * const **groups,
+					   unsigned * const num_groups)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = pdata->functions[function].groups;
+	*num_groups = pdata->functions[function].ngroups;
+
+	return 0;
+}
+
+static int bcm281xx_pinmux_enable(struct pinctrl_dev *pctldev,
+				  unsigned function,
+				  unsigned group)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+	const struct bcm281xx_pin_function *f = &pdata->functions[function];
+	u32 offset = 4 * pdata->pins[group].number;
+	int rc = 0;
+
+	dev_dbg(pctldev->dev,
+		"%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n",
+		__func__, f->name, function, pdata->pins[group].name,
+		pdata->pins[group].number, offset);
+
+	rc = regmap_update_bits(pdata->regmap, offset,
+		BCM281XX_PIN_REG_F_SEL_MASK,
+		function << BCM281XX_PIN_REG_F_SEL_SHIFT);
+	if (rc)
+		dev_err(pctldev->dev,
+			"Error updating register for pin %s (%d).\n",
+			pdata->pins[group].name, pdata->pins[group].number);
+
+	return rc;
+}
+
+static struct pinmux_ops bcm281xx_pinctrl_pinmux_ops = {
+	.get_functions_count = bcm281xx_pinctrl_get_fcns_count,
+	.get_function_name = bcm281xx_pinctrl_get_fcn_name,
+	.get_function_groups = bcm281xx_pinctrl_get_fcn_groups,
+	.enable = bcm281xx_pinmux_enable,
+};
+
+static int bcm281xx_pinctrl_pin_config_get(struct pinctrl_dev *pctldev,
+					   unsigned pin,
+					   unsigned long *config)
+{
+	return -ENOTSUPP;
+}
+
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_std_pin_update(struct pinctrl_dev *pctldev,
+				   unsigned pin,
+				   unsigned long *configs,
+				   unsigned num_configs,
+				   u32 *val,
+				   u32 *mask)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+	int i;
+	enum pin_config_param param;
+	u16 arg;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			arg = (arg >= 1 ? 1 : 0);
+			bcm281xx_pin_update(val, mask, arg,
+				BCM281XX_PIN_SHIFT(STD, HYST),
+				BCM281XX_PIN_MASK(STD, HYST));
+			break;
+		/*
+		 * The pin bias can only be one of pull-up, pull-down, or
+		 * disable.  The user does not need to specify a value for the
+		 * property, and the default value from pinconf-generic is
+		 * ignored.
+		 */
+		case PIN_CONFIG_BIAS_DISABLE:
+			bcm281xx_pin_update(val, mask, 0,
+				BCM281XX_PIN_SHIFT(STD, PULL_UP),
+				BCM281XX_PIN_MASK(STD, PULL_UP));
+			bcm281xx_pin_update(val, mask, 0,
+				BCM281XX_PIN_SHIFT(STD, PULL_DN),
+				BCM281XX_PIN_MASK(STD, PULL_DN));
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_UP:
+			bcm281xx_pin_update(val, mask, 1,
+				BCM281XX_PIN_SHIFT(STD, PULL_UP),
+				BCM281XX_PIN_MASK(STD, PULL_UP));
+			bcm281xx_pin_update(val, mask, 0,
+				BCM281XX_PIN_SHIFT(STD, PULL_DN),
+				BCM281XX_PIN_MASK(STD, PULL_DN));
+			break;
+
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			bcm281xx_pin_update(val, mask, 0,
+				BCM281XX_PIN_SHIFT(STD, PULL_UP),
+				BCM281XX_PIN_MASK(STD, PULL_UP));
+			bcm281xx_pin_update(val, mask, 1,
+				BCM281XX_PIN_SHIFT(STD, PULL_DN),
+				BCM281XX_PIN_MASK(STD, PULL_DN));
+			break;
+
+		case PIN_CONFIG_SLEW_RATE:
+			arg = (arg >= 1 ? 1 : 0);
+			bcm281xx_pin_update(val, mask, arg,
+				BCM281XX_PIN_SHIFT(STD, SLEW),
+				BCM281XX_PIN_MASK(STD, SLEW));
+			break;
+
+		case PIN_CONFIG_INPUT_ENABLE:
+			/* inversed since register is for input _disable_ */
+			arg = (arg >= 1 ? 0 : 1);
+			bcm281xx_pin_update(val, mask, arg,
+				BCM281XX_PIN_SHIFT(STD, INPUT_DIS),
+				BCM281XX_PIN_MASK(STD, INPUT_DIS));
+			break;
+
+		case PIN_CONFIG_DRIVE_STRENGTH:
+			/* Valid range is 2-16 mA, even numbers only */
+			if ((arg < 2) || (arg > 16) || (arg % 2)) {
+				dev_err(pctldev->dev,
+					"Invalid Drive Strength value (%d) for "
+					"pin %s (%d). Valid values are "
+					"(2..16) mA, even numbers only.\n",
+					arg, pdata->pins[pin].name, pin);
+				return -EINVAL;
+			}
+			bcm281xx_pin_update(val, mask, (arg/2)-1,
+				BCM281XX_PIN_SHIFT(STD, DRV_STR),
+				BCM281XX_PIN_MASK(STD, DRV_STR));
+			break;
+
+		default:
+			dev_err(pctldev->dev,
+				"Unrecognized pin config %d for pin %s (%d).\n",
+				param, pdata->pins[pin].name, pin);
+			return -EINVAL;
+
+		} /* switch config */
+	} /* for each config */
+
+	return 0;
+}
+
+/*
+ * The pull-up strength for an I2C pin is represented by bits 4-6 in the
+ * register with the following mapping:
+ *   0b000: No pull-up
+ *   0b001: 1200 Ohm
+ *   0b010: 1800 Ohm
+ *   0b011: 720 Ohm
+ *   0b100: 2700 Ohm
+ *   0b101: 831 Ohm
+ *   0b110: 1080 Ohm
+ *   0b111: 568 Ohm
+ * This array maps pull-up strength in Ohms to register values (1+index).
+ */
+static const u16 bcm281xx_pullup_map[] = {
+	1200, 1800, 720, 2700, 831, 1080, 568
+};
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev,
+				   unsigned pin,
+				   unsigned long *configs,
+				   unsigned num_configs,
+				   u32 *val,
+				   u32 *mask)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+	int i, j;
+	enum pin_config_param param;
+	u16 arg;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_PULL_UP:
+			for (j = 0; j < ARRAY_SIZE(bcm281xx_pullup_map); j++)
+				if (bcm281xx_pullup_map[j] == arg)
+					break;
+
+			if (j == ARRAY_SIZE(bcm281xx_pullup_map)) {
+				dev_err(pctldev->dev,
+					"Invalid pull-up value (%d) for pin %s "
+					"(%d). Valid values are 568, 720, 831, "
+					"1080, 1200, 1800, 2700 Ohms.\n",
+					arg, pdata->pins[pin].name, pin);
+				return -EINVAL;
+			}
+
+			bcm281xx_pin_update(val, mask, j+1,
+				BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR),
+				BCM281XX_PIN_MASK(I2C, PULL_UP_STR));
+			break;
+
+		case PIN_CONFIG_BIAS_DISABLE:
+			bcm281xx_pin_update(val, mask, 0,
+				BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR),
+				BCM281XX_PIN_MASK(I2C, PULL_UP_STR));
+			break;
+
+		case PIN_CONFIG_SLEW_RATE:
+			arg = (arg >= 1 ? 1 : 0);
+			bcm281xx_pin_update(val, mask, arg,
+				BCM281XX_PIN_SHIFT(I2C, SLEW),
+				BCM281XX_PIN_MASK(I2C, SLEW));
+			break;
+
+		case PIN_CONFIG_INPUT_ENABLE:
+			/* inversed since register is for input _disable_ */
+			arg = (arg >= 1 ? 0 : 1);
+			bcm281xx_pin_update(val, mask, arg,
+				BCM281XX_PIN_SHIFT(I2C, INPUT_DIS),
+				BCM281XX_PIN_MASK(I2C, INPUT_DIS));
+			break;
+
+		default:
+			dev_err(pctldev->dev,
+				"Unrecognized pin config %d for pin %s (%d).\n",
+				param, pdata->pins[pin].name, pin);
+			return -EINVAL;
+
+		} /* switch config */
+	} /* for each config */
+
+	return 0;
+}
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_hdmi_pin_update(struct pinctrl_dev *pctldev,
+				    unsigned pin,
+				    unsigned long *configs,
+				    unsigned num_configs,
+				    u32 *val,
+				    u32 *mask)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+	int i;
+	enum pin_config_param param;
+	u16 arg;
+
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
+		arg = pinconf_to_config_argument(configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_SLEW_RATE:
+			arg = (arg >= 1 ? 1 : 0);
+			bcm281xx_pin_update(val, mask, arg,
+				BCM281XX_PIN_SHIFT(HDMI, MODE),
+				BCM281XX_PIN_MASK(HDMI, MODE));
+			break;
+
+		case PIN_CONFIG_INPUT_ENABLE:
+			/* inversed since register is for input _disable_ */
+			arg = (arg >= 1 ? 0 : 1);
+			bcm281xx_pin_update(val, mask, arg,
+				BCM281XX_PIN_SHIFT(HDMI, INPUT_DIS),
+				BCM281XX_PIN_MASK(HDMI, INPUT_DIS));
+			break;
+
+		default:
+			dev_err(pctldev->dev,
+				"Unrecognized pin config %d for pin %s (%d).\n",
+				param, pdata->pins[pin].name, pin);
+			return -EINVAL;
+
+		} /* switch config */
+	} /* for each config */
+
+	return 0;
+}
+
+static int bcm281xx_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
+					   unsigned pin,
+					   unsigned long *configs,
+					   unsigned num_configs)
+{
+	struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+	enum bcm281xx_pin_type pin_type;
+	u32 offset = 4 * pin;
+	u32 cfg_val, cfg_mask;
+	int rc;
+
+	cfg_val = 0;
+	cfg_mask = 0;
+	pin_type = pin_type_get(pctldev, pin);
+
+	/* Different pins have different configuration options */
+	switch (pin_type) {
+	case BCM281XX_PIN_TYPE_STD:
+		rc = bcm281xx_std_pin_update(pctldev, pin, configs,
+			num_configs, &cfg_val, &cfg_mask);
+		break;
+
+	case BCM281XX_PIN_TYPE_I2C:
+		rc = bcm281xx_i2c_pin_update(pctldev, pin, configs,
+			num_configs, &cfg_val, &cfg_mask);
+		break;
+
+	case BCM281XX_PIN_TYPE_HDMI:
+		rc = bcm281xx_hdmi_pin_update(pctldev, pin, configs,
+			num_configs, &cfg_val, &cfg_mask);
+		break;
+
+	default:
+		dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n",
+			pdata->pins[pin].name, pin);
+		return -EINVAL;
+
+	} /* switch pin type */
+
+	if (rc)
+		return rc;
+
+	dev_dbg(pctldev->dev,
+		"%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n",
+		__func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask);
+
+	rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val);
+	if (rc) {
+		dev_err(pctldev->dev,
+			"Error updating register for pin %s (%d).\n",
+			pdata->pins[pin].name, pin);
+		return rc;
+	}
+
+	return 0;
+}
+
+static struct pinconf_ops bcm281xx_pinctrl_pinconf_ops = {
+	.pin_config_get = bcm281xx_pinctrl_pin_config_get,
+	.pin_config_set = bcm281xx_pinctrl_pin_config_set,
+};
+
+static struct pinctrl_desc bcm281xx_pinctrl_desc = {
+	/* name, pins, npins members initialized in probe function */
+	.pctlops = &bcm281xx_pinctrl_ops,
+	.pmxops = &bcm281xx_pinctrl_pinmux_ops,
+	.confops = &bcm281xx_pinctrl_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
+{
+	struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
+	struct resource *res;
+	struct pinctrl_dev *pctl;
+
+	/* So far We can assume there is only 1 bank of registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Missing MEM resource\n");
+		return -ENODEV;
+	}
+
+	pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pdata->reg_base)) {
+		dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
+		return -ENODEV;
+	}
+
+	/* Initialize the dynamic part of pinctrl_desc */
+	pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base,
+		&bcm281xx_pinctrl_regmap_config);
+	if (IS_ERR(pdata->regmap)) {
+		dev_err(&pdev->dev, "Regmap MMIO init failed.\n");
+		return -ENODEV;
+	}
+
+	bcm281xx_pinctrl_desc.name = dev_name(&pdev->dev);
+	bcm281xx_pinctrl_desc.pins = bcm281xx_pinctrl.pins;
+	bcm281xx_pinctrl_desc.npins = bcm281xx_pinctrl.npins;
+
+	pctl = pinctrl_register(&bcm281xx_pinctrl_desc,
+				&pdev->dev,
+				pdata);
+	if (!pctl) {
+		dev_err(&pdev->dev, "Failed to register pinctrl\n");
+		return -ENODEV;
+	}
+
+	platform_set_drvdata(pdev, pdata);
+
+	return 0;
+}
+
+static struct of_device_id bcm281xx_pinctrl_of_match[] = {
+	{ .compatible = "brcm,bcm11351-pinctrl", },
+	{ },
+};
+
+static struct platform_driver bcm281xx_pinctrl_driver = {
+	.driver = {
+		.name = "bcm281xx-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = bcm281xx_pinctrl_of_match,
+	},
+};
+
+module_platform_driver_probe(bcm281xx_pinctrl_driver, bcm281xx_pinctrl_probe);
+
+MODULE_AUTHOR("Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>");
+MODULE_AUTHOR("Sherman Yin <syin@broadcom.com>");
+MODULE_DESCRIPTION("Broadcom BCM281xx pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-capri.c b/drivers/pinctrl/pinctrl-capri.c
deleted file mode 100644
index eb25002..0000000
--- a/drivers/pinctrl/pinctrl-capri.c
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * Copyright (C) 2013 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinconf-generic.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include "core.h"
-#include "pinctrl-utils.h"
-
-/* Capri Pin Control Registers Definitions */
-
-/* Function Select bits are the same for all pin control registers */
-#define CAPRI_PIN_REG_F_SEL_MASK		0x0700
-#define CAPRI_PIN_REG_F_SEL_SHIFT		8
-
-/* Standard pin register */
-#define CAPRI_STD_PIN_REG_DRV_STR_MASK		0x0007
-#define CAPRI_STD_PIN_REG_DRV_STR_SHIFT		0
-#define CAPRI_STD_PIN_REG_INPUT_DIS_MASK	0x0008
-#define CAPRI_STD_PIN_REG_INPUT_DIS_SHIFT	3
-#define CAPRI_STD_PIN_REG_SLEW_MASK		0x0010
-#define CAPRI_STD_PIN_REG_SLEW_SHIFT		4
-#define CAPRI_STD_PIN_REG_PULL_UP_MASK		0x0020
-#define CAPRI_STD_PIN_REG_PULL_UP_SHIFT		5
-#define CAPRI_STD_PIN_REG_PULL_DN_MASK		0x0040
-#define CAPRI_STD_PIN_REG_PULL_DN_SHIFT		6
-#define CAPRI_STD_PIN_REG_HYST_MASK		0x0080
-#define CAPRI_STD_PIN_REG_HYST_SHIFT		7
-
-/* I2C pin register */
-#define CAPRI_I2C_PIN_REG_INPUT_DIS_MASK	0x0004
-#define CAPRI_I2C_PIN_REG_INPUT_DIS_SHIFT	2
-#define CAPRI_I2C_PIN_REG_SLEW_MASK		0x0008
-#define CAPRI_I2C_PIN_REG_SLEW_SHIFT		3
-#define CAPRI_I2C_PIN_REG_PULL_UP_STR_MASK	0x0070
-#define CAPRI_I2C_PIN_REG_PULL_UP_STR_SHIFT	4
-
-/* HDMI pin register */
-#define CAPRI_HDMI_PIN_REG_INPUT_DIS_MASK	0x0008
-#define CAPRI_HDMI_PIN_REG_INPUT_DIS_SHIFT	3
-#define CAPRI_HDMI_PIN_REG_MODE_MASK		0x0010
-#define CAPRI_HDMI_PIN_REG_MODE_SHIFT		4
-
-/**
- * capri_pin_type - types of pin register
- */
-enum capri_pin_type {
-	CAPRI_PIN_TYPE_UNKNOWN = 0,
-	CAPRI_PIN_TYPE_STD,
-	CAPRI_PIN_TYPE_I2C,
-	CAPRI_PIN_TYPE_HDMI,
-};
-
-static enum capri_pin_type std_pin = CAPRI_PIN_TYPE_STD;
-static enum capri_pin_type i2c_pin = CAPRI_PIN_TYPE_I2C;
-static enum capri_pin_type hdmi_pin = CAPRI_PIN_TYPE_HDMI;
-
-/**
- * capri_pin_function- define pin function
- */
-struct capri_pin_function {
-	const char *name;
-	const char * const *groups;
-	const unsigned ngroups;
-};
-
-/**
- * capri_pinctrl_data - Broadcom-specific pinctrl data
- * @reg_base - base of pinctrl registers
- */
-struct capri_pinctrl_data {
-	void __iomem *reg_base;
-
-	/* List of all pins */
-	const struct pinctrl_pin_desc *pins;
-	const unsigned npins;
-
-	const struct capri_pin_function *functions;
-	const unsigned nfunctions;
-
-	struct regmap *regmap;
-};
-
-/*
- * Pin number definition.  The order here must be the same as defined in the
- * PADCTRLREG block in the RDB.
- */
-#define CAPRI_PIN_ADCSYNC		0
-#define CAPRI_PIN_BAT_RM		1
-#define CAPRI_PIN_BSC1_SCL		2
-#define CAPRI_PIN_BSC1_SDA		3
-#define CAPRI_PIN_BSC2_SCL		4
-#define CAPRI_PIN_BSC2_SDA		5
-#define CAPRI_PIN_CLASSGPWR		6
-#define CAPRI_PIN_CLK_CX8		7
-#define CAPRI_PIN_CLKOUT_0		8
-#define CAPRI_PIN_CLKOUT_1		9
-#define CAPRI_PIN_CLKOUT_2		10
-#define CAPRI_PIN_CLKOUT_3		11
-#define CAPRI_PIN_CLKREQ_IN_0		12
-#define CAPRI_PIN_CLKREQ_IN_1		13
-#define CAPRI_PIN_CWS_SYS_REQ1		14
-#define CAPRI_PIN_CWS_SYS_REQ2		15
-#define CAPRI_PIN_CWS_SYS_REQ3		16
-#define CAPRI_PIN_DIGMIC1_CLK		17
-#define CAPRI_PIN_DIGMIC1_DQ		18
-#define CAPRI_PIN_DIGMIC2_CLK		19
-#define CAPRI_PIN_DIGMIC2_DQ		20
-#define CAPRI_PIN_GPEN13		21
-#define CAPRI_PIN_GPEN14		22
-#define CAPRI_PIN_GPEN15		23
-#define CAPRI_PIN_GPIO00		24
-#define CAPRI_PIN_GPIO01		25
-#define CAPRI_PIN_GPIO02		26
-#define CAPRI_PIN_GPIO03		27
-#define CAPRI_PIN_GPIO04		28
-#define CAPRI_PIN_GPIO05		29
-#define CAPRI_PIN_GPIO06		30
-#define CAPRI_PIN_GPIO07		31
-#define CAPRI_PIN_GPIO08		32
-#define CAPRI_PIN_GPIO09		33
-#define CAPRI_PIN_GPIO10		34
-#define CAPRI_PIN_GPIO11		35
-#define CAPRI_PIN_GPIO12		36
-#define CAPRI_PIN_GPIO13		37
-#define CAPRI_PIN_GPIO14		38
-#define CAPRI_PIN_GPS_PABLANK		39
-#define CAPRI_PIN_GPS_TMARK		40
-#define CAPRI_PIN_HDMI_SCL		41
-#define CAPRI_PIN_HDMI_SDA		42
-#define CAPRI_PIN_IC_DM			43
-#define CAPRI_PIN_IC_DP			44
-#define CAPRI_PIN_KP_COL_IP_0		45
-#define CAPRI_PIN_KP_COL_IP_1		46
-#define CAPRI_PIN_KP_COL_IP_2		47
-#define CAPRI_PIN_KP_COL_IP_3		48
-#define CAPRI_PIN_KP_ROW_OP_0		49
-#define CAPRI_PIN_KP_ROW_OP_1		50
-#define CAPRI_PIN_KP_ROW_OP_2		51
-#define CAPRI_PIN_KP_ROW_OP_3		52
-#define CAPRI_PIN_LCD_B_0		53
-#define CAPRI_PIN_LCD_B_1		54
-#define CAPRI_PIN_LCD_B_2		55
-#define CAPRI_PIN_LCD_B_3		56
-#define CAPRI_PIN_LCD_B_4		57
-#define CAPRI_PIN_LCD_B_5		58
-#define CAPRI_PIN_LCD_B_6		59
-#define CAPRI_PIN_LCD_B_7		60
-#define CAPRI_PIN_LCD_G_0		61
-#define CAPRI_PIN_LCD_G_1		62
-#define CAPRI_PIN_LCD_G_2		63
-#define CAPRI_PIN_LCD_G_3		64
-#define CAPRI_PIN_LCD_G_4		65
-#define CAPRI_PIN_LCD_G_5		66
-#define CAPRI_PIN_LCD_G_6		67
-#define CAPRI_PIN_LCD_G_7		68
-#define CAPRI_PIN_LCD_HSYNC		69
-#define CAPRI_PIN_LCD_OE		70
-#define CAPRI_PIN_LCD_PCLK		71
-#define CAPRI_PIN_LCD_R_0		72
-#define CAPRI_PIN_LCD_R_1		73
-#define CAPRI_PIN_LCD_R_2		74
-#define CAPRI_PIN_LCD_R_3		75
-#define CAPRI_PIN_LCD_R_4		76
-#define CAPRI_PIN_LCD_R_5		77
-#define CAPRI_PIN_LCD_R_6		78
-#define CAPRI_PIN_LCD_R_7		79
-#define CAPRI_PIN_LCD_VSYNC		80
-#define CAPRI_PIN_MDMGPIO0		81
-#define CAPRI_PIN_MDMGPIO1		82
-#define CAPRI_PIN_MDMGPIO2		83
-#define CAPRI_PIN_MDMGPIO3		84
-#define CAPRI_PIN_MDMGPIO4		85
-#define CAPRI_PIN_MDMGPIO5		86
-#define CAPRI_PIN_MDMGPIO6		87
-#define CAPRI_PIN_MDMGPIO7		88
-#define CAPRI_PIN_MDMGPIO8		89
-#define CAPRI_PIN_MPHI_DATA_0		90
-#define CAPRI_PIN_MPHI_DATA_1		91
-#define CAPRI_PIN_MPHI_DATA_2		92
-#define CAPRI_PIN_MPHI_DATA_3		93
-#define CAPRI_PIN_MPHI_DATA_4		94
-#define CAPRI_PIN_MPHI_DATA_5		95
-#define CAPRI_PIN_MPHI_DATA_6		96
-#define CAPRI_PIN_MPHI_DATA_7		97
-#define CAPRI_PIN_MPHI_DATA_8		98
-#define CAPRI_PIN_MPHI_DATA_9		99
-#define CAPRI_PIN_MPHI_DATA_10		100
-#define CAPRI_PIN_MPHI_DATA_11		101
-#define CAPRI_PIN_MPHI_DATA_12		102
-#define CAPRI_PIN_MPHI_DATA_13		103
-#define CAPRI_PIN_MPHI_DATA_14		104
-#define CAPRI_PIN_MPHI_DATA_15		105
-#define CAPRI_PIN_MPHI_HA0		106
-#define CAPRI_PIN_MPHI_HAT0		107
-#define CAPRI_PIN_MPHI_HAT1		108
-#define CAPRI_PIN_MPHI_HCE0_N		109
-#define CAPRI_PIN_MPHI_HCE1_N		110
-#define CAPRI_PIN_MPHI_HRD_N		111
-#define CAPRI_PIN_MPHI_HWR_N		112
-#define CAPRI_PIN_MPHI_RUN0		113
-#define CAPRI_PIN_MPHI_RUN1		114
-#define CAPRI_PIN_MTX_SCAN_CLK		115
-#define CAPRI_PIN_MTX_SCAN_DATA		116
-#define CAPRI_PIN_NAND_AD_0		117
-#define CAPRI_PIN_NAND_AD_1		118
-#define CAPRI_PIN_NAND_AD_2		119
-#define CAPRI_PIN_NAND_AD_3		120
-#define CAPRI_PIN_NAND_AD_4		121
-#define CAPRI_PIN_NAND_AD_5		122
-#define CAPRI_PIN_NAND_AD_6		123
-#define CAPRI_PIN_NAND_AD_7		124
-#define CAPRI_PIN_NAND_ALE		125
-#define CAPRI_PIN_NAND_CEN_0		126
-#define CAPRI_PIN_NAND_CEN_1		127
-#define CAPRI_PIN_NAND_CLE		128
-#define CAPRI_PIN_NAND_OEN		129
-#define CAPRI_PIN_NAND_RDY_0		130
-#define CAPRI_PIN_NAND_RDY_1		131
-#define CAPRI_PIN_NAND_WEN		132
-#define CAPRI_PIN_NAND_WP		133
-#define CAPRI_PIN_PC1			134
-#define CAPRI_PIN_PC2			135
-#define CAPRI_PIN_PMU_INT		136
-#define CAPRI_PIN_PMU_SCL		137
-#define CAPRI_PIN_PMU_SDA		138
-#define CAPRI_PIN_RFST2G_MTSLOTEN3G	139
-#define CAPRI_PIN_RGMII_0_RX_CTL	140
-#define CAPRI_PIN_RGMII_0_RXC		141
-#define CAPRI_PIN_RGMII_0_RXD_0		142
-#define CAPRI_PIN_RGMII_0_RXD_1		143
-#define CAPRI_PIN_RGMII_0_RXD_2		144
-#define CAPRI_PIN_RGMII_0_RXD_3		145
-#define CAPRI_PIN_RGMII_0_TX_CTL	146
-#define CAPRI_PIN_RGMII_0_TXC		147
-#define CAPRI_PIN_RGMII_0_TXD_0		148
-#define CAPRI_PIN_RGMII_0_TXD_1		149
-#define CAPRI_PIN_RGMII_0_TXD_2		150
-#define CAPRI_PIN_RGMII_0_TXD_3		151
-#define CAPRI_PIN_RGMII_1_RX_CTL	152
-#define CAPRI_PIN_RGMII_1_RXC		153
-#define CAPRI_PIN_RGMII_1_RXD_0		154
-#define CAPRI_PIN_RGMII_1_RXD_1		155
-#define CAPRI_PIN_RGMII_1_RXD_2		156
-#define CAPRI_PIN_RGMII_1_RXD_3		157
-#define CAPRI_PIN_RGMII_1_TX_CTL	158
-#define CAPRI_PIN_RGMII_1_TXC		159
-#define CAPRI_PIN_RGMII_1_TXD_0		160
-#define CAPRI_PIN_RGMII_1_TXD_1		161
-#define CAPRI_PIN_RGMII_1_TXD_2		162
-#define CAPRI_PIN_RGMII_1_TXD_3		163
-#define CAPRI_PIN_RGMII_GPIO_0		164
-#define CAPRI_PIN_RGMII_GPIO_1		165
-#define CAPRI_PIN_RGMII_GPIO_2		166
-#define CAPRI_PIN_RGMII_GPIO_3		167
-#define CAPRI_PIN_RTXDATA2G_TXDATA3G1	168
-#define CAPRI_PIN_RTXEN2G_TXDATA3G2	169
-#define CAPRI_PIN_RXDATA3G0		170
-#define CAPRI_PIN_RXDATA3G1		171
-#define CAPRI_PIN_RXDATA3G2		172
-#define CAPRI_PIN_SDIO1_CLK		173
-#define CAPRI_PIN_SDIO1_CMD		174
-#define CAPRI_PIN_SDIO1_DATA_0		175
-#define CAPRI_PIN_SDIO1_DATA_1		176
-#define CAPRI_PIN_SDIO1_DATA_2		177
-#define CAPRI_PIN_SDIO1_DATA_3		178
-#define CAPRI_PIN_SDIO4_CLK		179
-#define CAPRI_PIN_SDIO4_CMD		180
-#define CAPRI_PIN_SDIO4_DATA_0		181
-#define CAPRI_PIN_SDIO4_DATA_1		182
-#define CAPRI_PIN_SDIO4_DATA_2		183
-#define CAPRI_PIN_SDIO4_DATA_3		184
-#define CAPRI_PIN_SIM_CLK		185
-#define CAPRI_PIN_SIM_DATA		186
-#define CAPRI_PIN_SIM_DET		187
-#define CAPRI_PIN_SIM_RESETN		188
-#define CAPRI_PIN_SIM2_CLK		189
-#define CAPRI_PIN_SIM2_DATA		190
-#define CAPRI_PIN_SIM2_DET		191
-#define CAPRI_PIN_SIM2_RESETN		192
-#define CAPRI_PIN_SRI_C			193
-#define CAPRI_PIN_SRI_D			194
-#define CAPRI_PIN_SRI_E			195
-#define CAPRI_PIN_SSP_EXTCLK		196
-#define CAPRI_PIN_SSP0_CLK		197
-#define CAPRI_PIN_SSP0_FS		198
-#define CAPRI_PIN_SSP0_RXD		199
-#define CAPRI_PIN_SSP0_TXD		200
-#define CAPRI_PIN_SSP2_CLK		201
-#define CAPRI_PIN_SSP2_FS_0		202
-#define CAPRI_PIN_SSP2_FS_1		203
-#define CAPRI_PIN_SSP2_FS_2		204
-#define CAPRI_PIN_SSP2_FS_3		205
-#define CAPRI_PIN_SSP2_RXD_0		206
-#define CAPRI_PIN_SSP2_RXD_1		207
-#define CAPRI_PIN_SSP2_TXD_0		208
-#define CAPRI_PIN_SSP2_TXD_1		209
-#define CAPRI_PIN_SSP3_CLK		210
-#define CAPRI_PIN_SSP3_FS		211
-#define CAPRI_PIN_SSP3_RXD		212
-#define CAPRI_PIN_SSP3_TXD		213
-#define CAPRI_PIN_SSP4_CLK		214
-#define CAPRI_PIN_SSP4_FS		215
-#define CAPRI_PIN_SSP4_RXD		216
-#define CAPRI_PIN_SSP4_TXD		217
-#define CAPRI_PIN_SSP5_CLK		218
-#define CAPRI_PIN_SSP5_FS		219
-#define CAPRI_PIN_SSP5_RXD		220
-#define CAPRI_PIN_SSP5_TXD		221
-#define CAPRI_PIN_SSP6_CLK		222
-#define CAPRI_PIN_SSP6_FS		223
-#define CAPRI_PIN_SSP6_RXD		224
-#define CAPRI_PIN_SSP6_TXD		225
-#define CAPRI_PIN_STAT_1		226
-#define CAPRI_PIN_STAT_2		227
-#define CAPRI_PIN_SYSCLKEN		228
-#define CAPRI_PIN_TRACECLK		229
-#define CAPRI_PIN_TRACEDT00		230
-#define CAPRI_PIN_TRACEDT01		231
-#define CAPRI_PIN_TRACEDT02		232
-#define CAPRI_PIN_TRACEDT03		233
-#define CAPRI_PIN_TRACEDT04		234
-#define CAPRI_PIN_TRACEDT05		235
-#define CAPRI_PIN_TRACEDT06		236
-#define CAPRI_PIN_TRACEDT07		237
-#define CAPRI_PIN_TRACEDT08		238
-#define CAPRI_PIN_TRACEDT09		239
-#define CAPRI_PIN_TRACEDT10		240
-#define CAPRI_PIN_TRACEDT11		241
-#define CAPRI_PIN_TRACEDT12		242
-#define CAPRI_PIN_TRACEDT13		243
-#define CAPRI_PIN_TRACEDT14		244
-#define CAPRI_PIN_TRACEDT15		245
-#define CAPRI_PIN_TXDATA3G0		246
-#define CAPRI_PIN_TXPWRIND		247
-#define CAPRI_PIN_UARTB1_UCTS		248
-#define CAPRI_PIN_UARTB1_URTS		249
-#define CAPRI_PIN_UARTB1_URXD		250
-#define CAPRI_PIN_UARTB1_UTXD		251
-#define CAPRI_PIN_UARTB2_URXD		252
-#define CAPRI_PIN_UARTB2_UTXD		253
-#define CAPRI_PIN_UARTB3_UCTS		254
-#define CAPRI_PIN_UARTB3_URTS		255
-#define CAPRI_PIN_UARTB3_URXD		256
-#define CAPRI_PIN_UARTB3_UTXD		257
-#define CAPRI_PIN_UARTB4_UCTS		258
-#define CAPRI_PIN_UARTB4_URTS		259
-#define CAPRI_PIN_UARTB4_URXD		260
-#define CAPRI_PIN_UARTB4_UTXD		261
-#define CAPRI_PIN_VC_CAM1_SCL		262
-#define CAPRI_PIN_VC_CAM1_SDA		263
-#define CAPRI_PIN_VC_CAM2_SCL		264
-#define CAPRI_PIN_VC_CAM2_SDA		265
-#define CAPRI_PIN_VC_CAM3_SCL		266
-#define CAPRI_PIN_VC_CAM3_SDA		267
-
-#define CAPRI_PIN_DESC(a, b, c) \
-	{ .number = a, .name = b, .drv_data = &c##_pin }
-
-/*
- * Pin description definition.  The order here must be the same as defined in
- * the PADCTRLREG block in the RDB, since the pin number is used as an index
- * into this array.
- */
-static const struct pinctrl_pin_desc capri_pinctrl_pins[] = {
-	CAPRI_PIN_DESC(CAPRI_PIN_ADCSYNC, "adcsync", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_BAT_RM, "bat_rm", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SCL, "bsc1_scl", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SDA, "bsc1_sda", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SCL, "bsc2_scl", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SDA, "bsc2_sda", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLASSGPWR, "classgpwr", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLK_CX8, "clk_cx8", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_0, "clkout_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_1, "clkout_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_2, "clkout_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_3, "clkout_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_0, "clkreq_in_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_1, "clkreq_in_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ1, "cws_sys_req1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ2, "cws_sys_req2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ3, "cws_sys_req3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_CLK, "digmic1_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_DQ, "digmic1_dq", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_CLK, "digmic2_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_DQ, "digmic2_dq", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPEN13, "gpen13", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPEN14, "gpen14", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPEN15, "gpen15", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO00, "gpio00", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO01, "gpio01", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO02, "gpio02", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO03, "gpio03", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO04, "gpio04", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO05, "gpio05", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO06, "gpio06", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO07, "gpio07", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO08, "gpio08", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO09, "gpio09", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO10, "gpio10", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO11, "gpio11", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO12, "gpio12", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO13, "gpio13", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPIO14, "gpio14", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPS_PABLANK, "gps_pablank", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_GPS_TMARK, "gps_tmark", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SCL, "hdmi_scl", hdmi),
-	CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SDA, "hdmi_sda", hdmi),
-	CAPRI_PIN_DESC(CAPRI_PIN_IC_DM, "ic_dm", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_IC_DP, "ic_dp", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_0, "kp_col_ip_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_1, "kp_col_ip_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_2, "kp_col_ip_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_3, "kp_col_ip_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_0, "kp_row_op_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_1, "kp_row_op_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_2, "kp_row_op_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_3, "kp_row_op_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_0, "lcd_b_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_1, "lcd_b_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_2, "lcd_b_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_3, "lcd_b_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_4, "lcd_b_4", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_5, "lcd_b_5", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_6, "lcd_b_6", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_7, "lcd_b_7", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_0, "lcd_g_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_1, "lcd_g_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_2, "lcd_g_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_3, "lcd_g_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_4, "lcd_g_4", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_5, "lcd_g_5", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_6, "lcd_g_6", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_7, "lcd_g_7", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_HSYNC, "lcd_hsync", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_OE, "lcd_oe", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_PCLK, "lcd_pclk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_0, "lcd_r_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_1, "lcd_r_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_2, "lcd_r_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_3, "lcd_r_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_4, "lcd_r_4", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_5, "lcd_r_5", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_6, "lcd_r_6", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_7, "lcd_r_7", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_LCD_VSYNC, "lcd_vsync", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO0, "mdmgpio0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO1, "mdmgpio1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO2, "mdmgpio2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO3, "mdmgpio3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO4, "mdmgpio4", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO5, "mdmgpio5", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO6, "mdmgpio6", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO7, "mdmgpio7", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO8, "mdmgpio8", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_0, "mphi_data_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_1, "mphi_data_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_2, "mphi_data_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_3, "mphi_data_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_4, "mphi_data_4", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_5, "mphi_data_5", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_6, "mphi_data_6", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_7, "mphi_data_7", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_8, "mphi_data_8", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_9, "mphi_data_9", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_10, "mphi_data_10", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_11, "mphi_data_11", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_12, "mphi_data_12", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_13, "mphi_data_13", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_14, "mphi_data_14", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_15, "mphi_data_15", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HA0, "mphi_ha0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT0, "mphi_hat0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT1, "mphi_hat1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE0_N, "mphi_hce0_n", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE1_N, "mphi_hce1_n", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HRD_N, "mphi_hrd_n", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HWR_N, "mphi_hwr_n", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN0, "mphi_run0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN1, "mphi_run1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_DATA, "mtx_scan_data", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_0, "nand_ad_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_1, "nand_ad_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_2, "nand_ad_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_3, "nand_ad_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_4, "nand_ad_4", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_5, "nand_ad_5", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_6, "nand_ad_6", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_7, "nand_ad_7", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_ALE, "nand_ale", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_0, "nand_cen_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_1, "nand_cen_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_CLE, "nand_cle", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_OEN, "nand_oen", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_0, "nand_rdy_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_1, "nand_rdy_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_WEN, "nand_wen", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_NAND_WP, "nand_wp", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_PC1, "pc1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_PC2, "pc2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_PMU_INT, "pmu_int", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_PMU_SCL, "pmu_scl", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_PMU_SDA, "pmu_sda", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXC, "rgmii_0_rxc", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXC, "rgmii_0_txc", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXC, "rgmii_1_rxc", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXC, "rgmii_1_txc", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RTXDATA2G_TXDATA3G1, "rtxdata2g_txdata3g1",
-		std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G0, "rxdata3g0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G1, "rxdata3g1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G2, "rxdata3g2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CLK, "sdio1_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CMD, "sdio1_cmd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_0, "sdio1_data_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_1, "sdio1_data_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_2, "sdio1_data_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_3, "sdio1_data_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CLK, "sdio4_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CMD, "sdio4_cmd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_0, "sdio4_data_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_1, "sdio4_data_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_2, "sdio4_data_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_3, "sdio4_data_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM_CLK, "sim_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM_DATA, "sim_data", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM_DET, "sim_det", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM_RESETN, "sim_resetn", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM2_CLK, "sim2_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DATA, "sim2_data", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DET, "sim2_det", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SIM2_RESETN, "sim2_resetn", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SRI_C, "sri_c", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SRI_D, "sri_d", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SRI_E, "sri_e", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP_EXTCLK, "ssp_extclk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP0_CLK, "ssp0_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP0_FS, "ssp0_fs", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP0_RXD, "ssp0_rxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP0_TXD, "ssp0_txd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_CLK, "ssp2_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_0, "ssp2_fs_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_1, "ssp2_fs_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_2, "ssp2_fs_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_3, "ssp2_fs_3", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_0, "ssp2_rxd_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_1, "ssp2_rxd_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_0, "ssp2_txd_0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_1, "ssp2_txd_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP3_CLK, "ssp3_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP3_FS, "ssp3_fs", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP3_RXD, "ssp3_rxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP3_TXD, "ssp3_txd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP4_CLK, "ssp4_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP4_FS, "ssp4_fs", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP4_RXD, "ssp4_rxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP4_TXD, "ssp4_txd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP5_CLK, "ssp5_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP5_FS, "ssp5_fs", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP5_RXD, "ssp5_rxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP5_TXD, "ssp5_txd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP6_CLK, "ssp6_clk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP6_FS, "ssp6_fs", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP6_RXD, "ssp6_rxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SSP6_TXD, "ssp6_txd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_STAT_1, "stat_1", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_STAT_2, "stat_2", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_SYSCLKEN, "sysclken", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACECLK, "traceclk", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT00, "tracedt00", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT01, "tracedt01", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT02, "tracedt02", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT03, "tracedt03", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT04, "tracedt04", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT05, "tracedt05", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT06, "tracedt06", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT07, "tracedt07", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT08, "tracedt08", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT09, "tracedt09", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT10, "tracedt10", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT11, "tracedt11", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT12, "tracedt12", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT13, "tracedt13", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT14, "tracedt14", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT15, "tracedt15", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TXDATA3G0, "txdata3g0", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_TXPWRIND, "txpwrind", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UCTS, "uartb1_ucts", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URTS, "uartb1_urts", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URXD, "uartb1_urxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UTXD, "uartb1_utxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_URXD, "uartb2_urxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_UTXD, "uartb2_utxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UCTS, "uartb3_ucts", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URTS, "uartb3_urts", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URXD, "uartb3_urxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UTXD, "uartb3_utxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UCTS, "uartb4_ucts", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URTS, "uartb4_urts", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URXD, "uartb4_urxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UTXD, "uartb4_utxd", std),
-	CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c),
-	CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c),
-};
-
-static const char * const capri_alt_groups[] = {
-	"adcsync",
-	"bat_rm",
-	"bsc1_scl",
-	"bsc1_sda",
-	"bsc2_scl",
-	"bsc2_sda",
-	"classgpwr",
-	"clk_cx8",
-	"clkout_0",
-	"clkout_1",
-	"clkout_2",
-	"clkout_3",
-	"clkreq_in_0",
-	"clkreq_in_1",
-	"cws_sys_req1",
-	"cws_sys_req2",
-	"cws_sys_req3",
-	"digmic1_clk",
-	"digmic1_dq",
-	"digmic2_clk",
-	"digmic2_dq",
-	"gpen13",
-	"gpen14",
-	"gpen15",
-	"gpio00",
-	"gpio01",
-	"gpio02",
-	"gpio03",
-	"gpio04",
-	"gpio05",
-	"gpio06",
-	"gpio07",
-	"gpio08",
-	"gpio09",
-	"gpio10",
-	"gpio11",
-	"gpio12",
-	"gpio13",
-	"gpio14",
-	"gps_pablank",
-	"gps_tmark",
-	"hdmi_scl",
-	"hdmi_sda",
-	"ic_dm",
-	"ic_dp",
-	"kp_col_ip_0",
-	"kp_col_ip_1",
-	"kp_col_ip_2",
-	"kp_col_ip_3",
-	"kp_row_op_0",
-	"kp_row_op_1",
-	"kp_row_op_2",
-	"kp_row_op_3",
-	"lcd_b_0",
-	"lcd_b_1",
-	"lcd_b_2",
-	"lcd_b_3",
-	"lcd_b_4",
-	"lcd_b_5",
-	"lcd_b_6",
-	"lcd_b_7",
-	"lcd_g_0",
-	"lcd_g_1",
-	"lcd_g_2",
-	"lcd_g_3",
-	"lcd_g_4",
-	"lcd_g_5",
-	"lcd_g_6",
-	"lcd_g_7",
-	"lcd_hsync",
-	"lcd_oe",
-	"lcd_pclk",
-	"lcd_r_0",
-	"lcd_r_1",
-	"lcd_r_2",
-	"lcd_r_3",
-	"lcd_r_4",
-	"lcd_r_5",
-	"lcd_r_6",
-	"lcd_r_7",
-	"lcd_vsync",
-	"mdmgpio0",
-	"mdmgpio1",
-	"mdmgpio2",
-	"mdmgpio3",
-	"mdmgpio4",
-	"mdmgpio5",
-	"mdmgpio6",
-	"mdmgpio7",
-	"mdmgpio8",
-	"mphi_data_0",
-	"mphi_data_1",
-	"mphi_data_2",
-	"mphi_data_3",
-	"mphi_data_4",
-	"mphi_data_5",
-	"mphi_data_6",
-	"mphi_data_7",
-	"mphi_data_8",
-	"mphi_data_9",
-	"mphi_data_10",
-	"mphi_data_11",
-	"mphi_data_12",
-	"mphi_data_13",
-	"mphi_data_14",
-	"mphi_data_15",
-	"mphi_ha0",
-	"mphi_hat0",
-	"mphi_hat1",
-	"mphi_hce0_n",
-	"mphi_hce1_n",
-	"mphi_hrd_n",
-	"mphi_hwr_n",
-	"mphi_run0",
-	"mphi_run1",
-	"mtx_scan_clk",
-	"mtx_scan_data",
-	"nand_ad_0",
-	"nand_ad_1",
-	"nand_ad_2",
-	"nand_ad_3",
-	"nand_ad_4",
-	"nand_ad_5",
-	"nand_ad_6",
-	"nand_ad_7",
-	"nand_ale",
-	"nand_cen_0",
-	"nand_cen_1",
-	"nand_cle",
-	"nand_oen",
-	"nand_rdy_0",
-	"nand_rdy_1",
-	"nand_wen",
-	"nand_wp",
-	"pc1",
-	"pc2",
-	"pmu_int",
-	"pmu_scl",
-	"pmu_sda",
-	"rfst2g_mtsloten3g",
-	"rgmii_0_rx_ctl",
-	"rgmii_0_rxc",
-	"rgmii_0_rxd_0",
-	"rgmii_0_rxd_1",
-	"rgmii_0_rxd_2",
-	"rgmii_0_rxd_3",
-	"rgmii_0_tx_ctl",
-	"rgmii_0_txc",
-	"rgmii_0_txd_0",
-	"rgmii_0_txd_1",
-	"rgmii_0_txd_2",
-	"rgmii_0_txd_3",
-	"rgmii_1_rx_ctl",
-	"rgmii_1_rxc",
-	"rgmii_1_rxd_0",
-	"rgmii_1_rxd_1",
-	"rgmii_1_rxd_2",
-	"rgmii_1_rxd_3",
-	"rgmii_1_tx_ctl",
-	"rgmii_1_txc",
-	"rgmii_1_txd_0",
-	"rgmii_1_txd_1",
-	"rgmii_1_txd_2",
-	"rgmii_1_txd_3",
-	"rgmii_gpio_0",
-	"rgmii_gpio_1",
-	"rgmii_gpio_2",
-	"rgmii_gpio_3",
-	"rtxdata2g_txdata3g1",
-	"rtxen2g_txdata3g2",
-	"rxdata3g0",
-	"rxdata3g1",
-	"rxdata3g2",
-	"sdio1_clk",
-	"sdio1_cmd",
-	"sdio1_data_0",
-	"sdio1_data_1",
-	"sdio1_data_2",
-	"sdio1_data_3",
-	"sdio4_clk",
-	"sdio4_cmd",
-	"sdio4_data_0",
-	"sdio4_data_1",
-	"sdio4_data_2",
-	"sdio4_data_3",
-	"sim_clk",
-	"sim_data",
-	"sim_det",
-	"sim_resetn",
-	"sim2_clk",
-	"sim2_data",
-	"sim2_det",
-	"sim2_resetn",
-	"sri_c",
-	"sri_d",
-	"sri_e",
-	"ssp_extclk",
-	"ssp0_clk",
-	"ssp0_fs",
-	"ssp0_rxd",
-	"ssp0_txd",
-	"ssp2_clk",
-	"ssp2_fs_0",
-	"ssp2_fs_1",
-	"ssp2_fs_2",
-	"ssp2_fs_3",
-	"ssp2_rxd_0",
-	"ssp2_rxd_1",
-	"ssp2_txd_0",
-	"ssp2_txd_1",
-	"ssp3_clk",
-	"ssp3_fs",
-	"ssp3_rxd",
-	"ssp3_txd",
-	"ssp4_clk",
-	"ssp4_fs",
-	"ssp4_rxd",
-	"ssp4_txd",
-	"ssp5_clk",
-	"ssp5_fs",
-	"ssp5_rxd",
-	"ssp5_txd",
-	"ssp6_clk",
-	"ssp6_fs",
-	"ssp6_rxd",
-	"ssp6_txd",
-	"stat_1",
-	"stat_2",
-	"sysclken",
-	"traceclk",
-	"tracedt00",
-	"tracedt01",
-	"tracedt02",
-	"tracedt03",
-	"tracedt04",
-	"tracedt05",
-	"tracedt06",
-	"tracedt07",
-	"tracedt08",
-	"tracedt09",
-	"tracedt10",
-	"tracedt11",
-	"tracedt12",
-	"tracedt13",
-	"tracedt14",
-	"tracedt15",
-	"txdata3g0",
-	"txpwrind",
-	"uartb1_ucts",
-	"uartb1_urts",
-	"uartb1_urxd",
-	"uartb1_utxd",
-	"uartb2_urxd",
-	"uartb2_utxd",
-	"uartb3_ucts",
-	"uartb3_urts",
-	"uartb3_urxd",
-	"uartb3_utxd",
-	"uartb4_ucts",
-	"uartb4_urts",
-	"uartb4_urxd",
-	"uartb4_utxd",
-	"vc_cam1_scl",
-	"vc_cam1_sda",
-	"vc_cam2_scl",
-	"vc_cam2_sda",
-	"vc_cam3_scl",
-	"vc_cam3_sda",
-};
-
-/* Every pin can implement all ALT1-ALT4 functions */
-#define CAPRI_PIN_FUNCTION(fcn_name)			\
-{							\
-	.name = #fcn_name,				\
-	.groups = capri_alt_groups,			\
-	.ngroups = ARRAY_SIZE(capri_alt_groups),	\
-}
-
-static const struct capri_pin_function capri_functions[] = {
-	CAPRI_PIN_FUNCTION(alt1),
-	CAPRI_PIN_FUNCTION(alt2),
-	CAPRI_PIN_FUNCTION(alt3),
-	CAPRI_PIN_FUNCTION(alt4),
-};
-
-static struct capri_pinctrl_data capri_pinctrl = {
-	.pins = capri_pinctrl_pins,
-	.npins = ARRAY_SIZE(capri_pinctrl_pins),
-	.functions = capri_functions,
-	.nfunctions = ARRAY_SIZE(capri_functions),
-};
-
-static inline enum capri_pin_type pin_type_get(struct pinctrl_dev *pctldev,
-					       unsigned pin)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
-	if (pin >= pdata->npins)
-		return CAPRI_PIN_TYPE_UNKNOWN;
-
-	return *(enum capri_pin_type *)(pdata->pins[pin].drv_data);
-}
-
-#define CAPRI_PIN_SHIFT(type, param) \
-	(CAPRI_ ## type ## _PIN_REG_ ## param ## _SHIFT)
-
-#define CAPRI_PIN_MASK(type, param) \
-	(CAPRI_ ## type ## _PIN_REG_ ## param ## _MASK)
-
-/*
- * This helper function is used to build up the value and mask used to write to
- * a pin register, but does not actually write to the register.
- */
-static inline void capri_pin_update(u32 *reg_val, u32 *reg_mask, u32 param_val,
-				    u32 param_shift, u32 param_mask)
-{
-	*reg_val &= ~param_mask;
-	*reg_val |= (param_val << param_shift) & param_mask;
-	*reg_mask |= param_mask;
-}
-
-static struct regmap_config capri_pinctrl_regmap_config = {
-	.reg_bits = 32,
-	.reg_stride = 4,
-	.val_bits = 32,
-	.max_register = CAPRI_PIN_VC_CAM3_SDA,
-};
-
-static int capri_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
-	return pdata->npins;
-}
-
-static const char *capri_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
-						unsigned group)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
-	return pdata->pins[group].name;
-}
-
-static int capri_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
-					unsigned group,
-					const unsigned **pins,
-					unsigned *num_pins)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
-	*pins = &pdata->pins[group].number;
-	*num_pins = 1;
-
-	return 0;
-}
-
-static void capri_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
-				       struct seq_file *s,
-				       unsigned offset)
-{
-	seq_printf(s, " %s", dev_name(pctldev->dev));
-}
-
-static struct pinctrl_ops capri_pinctrl_ops = {
-	.get_groups_count = capri_pinctrl_get_groups_count,
-	.get_group_name = capri_pinctrl_get_group_name,
-	.get_group_pins = capri_pinctrl_get_group_pins,
-	.pin_dbg_show = capri_pinctrl_pin_dbg_show,
-	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
-	.dt_free_map = pinctrl_utils_dt_free_map,
-};
-
-static int capri_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
-	return pdata->nfunctions;
-}
-
-static const char *capri_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
-					      unsigned function)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
-	return pdata->functions[function].name;
-}
-
-static int capri_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
-					unsigned function,
-					const char * const **groups,
-					unsigned * const num_groups)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
-	*groups = pdata->functions[function].groups;
-	*num_groups = pdata->functions[function].ngroups;
-
-	return 0;
-}
-
-static int capri_pinmux_enable(struct pinctrl_dev *pctldev,
-			       unsigned function,
-			       unsigned group)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-	const struct capri_pin_function *f = &pdata->functions[function];
-	u32 offset = 4 * pdata->pins[group].number;
-	int rc = 0;
-
-	dev_dbg(pctldev->dev,
-		"%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n",
-		__func__, f->name, function, pdata->pins[group].name,
-		pdata->pins[group].number, offset);
-
-	rc = regmap_update_bits(pdata->regmap, offset, CAPRI_PIN_REG_F_SEL_MASK,
-			function << CAPRI_PIN_REG_F_SEL_SHIFT);
-	if (rc)
-		dev_err(pctldev->dev,
-			"Error updating register for pin %s (%d).\n",
-			pdata->pins[group].name, pdata->pins[group].number);
-
-	return rc;
-}
-
-static struct pinmux_ops capri_pinctrl_pinmux_ops = {
-	.get_functions_count = capri_pinctrl_get_fcns_count,
-	.get_function_name = capri_pinctrl_get_fcn_name,
-	.get_function_groups = capri_pinctrl_get_fcn_groups,
-	.enable = capri_pinmux_enable,
-};
-
-static int capri_pinctrl_pin_config_get(struct pinctrl_dev *pctldev,
-					unsigned pin,
-					unsigned long *config)
-{
-	return -ENOTSUPP;
-}
-
-
-/* Goes through the configs and update register val/mask */
-static int capri_std_pin_update(struct pinctrl_dev *pctldev,
-				unsigned pin,
-				unsigned long *configs,
-				unsigned num_configs,
-				u32 *val,
-				u32 *mask)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-	int i;
-	enum pin_config_param param;
-	u16 arg;
-
-	for (i = 0; i < num_configs; i++) {
-		param = pinconf_to_config_param(configs[i]);
-		arg = pinconf_to_config_argument(configs[i]);
-
-		switch (param) {
-		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-			arg = (arg >= 1 ? 1 : 0);
-			capri_pin_update(val, mask, arg,
-					CAPRI_PIN_SHIFT(STD, HYST),
-					CAPRI_PIN_MASK(STD, HYST));
-			break;
-		/*
-		 * The pin bias can only be one of pull-up, pull-down, or
-		 * disable.  The user does not need to specify a value for the
-		 * property, and the default value from pinconf-generic is
-		 * ignored.
-		 */
-		case PIN_CONFIG_BIAS_DISABLE:
-			capri_pin_update(val, mask, 0,
-					CAPRI_PIN_SHIFT(STD, PULL_UP),
-					CAPRI_PIN_MASK(STD, PULL_UP));
-			capri_pin_update(val, mask, 0,
-					CAPRI_PIN_SHIFT(STD, PULL_DN),
-					CAPRI_PIN_MASK(STD, PULL_DN));
-			break;
-
-		case PIN_CONFIG_BIAS_PULL_UP:
-			capri_pin_update(val, mask, 1,
-					CAPRI_PIN_SHIFT(STD, PULL_UP),
-					CAPRI_PIN_MASK(STD, PULL_UP));
-			capri_pin_update(val, mask, 0,
-					CAPRI_PIN_SHIFT(STD, PULL_DN),
-					CAPRI_PIN_MASK(STD, PULL_DN));
-			break;
-
-		case PIN_CONFIG_BIAS_PULL_DOWN:
-			capri_pin_update(val, mask, 0,
-					CAPRI_PIN_SHIFT(STD, PULL_UP),
-					CAPRI_PIN_MASK(STD, PULL_UP));
-			capri_pin_update(val, mask, 1,
-					CAPRI_PIN_SHIFT(STD, PULL_DN),
-					CAPRI_PIN_MASK(STD, PULL_DN));
-			break;
-
-		case PIN_CONFIG_SLEW_RATE:
-			arg = (arg >= 1 ? 1 : 0);
-			capri_pin_update(val, mask, arg,
-					CAPRI_PIN_SHIFT(STD, SLEW),
-					CAPRI_PIN_MASK(STD, SLEW));
-			break;
-
-		case PIN_CONFIG_INPUT_ENABLE:
-			/* inversed since register is for input _disable_ */
-			arg = (arg >= 1 ? 0 : 1);
-			capri_pin_update(val, mask, arg,
-					CAPRI_PIN_SHIFT(STD, INPUT_DIS),
-					CAPRI_PIN_MASK(STD, INPUT_DIS));
-			break;
-
-		case PIN_CONFIG_DRIVE_STRENGTH:
-			/* Valid range is 2-16 mA, even numbers only */
-			if ((arg < 2) || (arg > 16) || (arg % 2)) {
-				dev_err(pctldev->dev,
-					"Invalid Drive Strength value (%d) for "
-					"pin %s (%d). Valid values are "
-					"(2..16) mA, even numbers only.\n",
-					arg, pdata->pins[pin].name, pin);
-				return -EINVAL;
-			}
-			capri_pin_update(val, mask, (arg/2)-1,
-					CAPRI_PIN_SHIFT(STD, DRV_STR),
-					CAPRI_PIN_MASK(STD, DRV_STR));
-			break;
-
-		default:
-			dev_err(pctldev->dev,
-				"Unrecognized pin config %d for pin %s (%d).\n",
-				param, pdata->pins[pin].name, pin);
-			return -EINVAL;
-
-		} /* switch config */
-	} /* for each config */
-
-	return 0;
-}
-
-/*
- * The pull-up strength for an I2C pin is represented by bits 4-6 in the
- * register with the following mapping:
- *   0b000: No pull-up
- *   0b001: 1200 Ohm
- *   0b010: 1800 Ohm
- *   0b011: 720 Ohm
- *   0b100: 2700 Ohm
- *   0b101: 831 Ohm
- *   0b110: 1080 Ohm
- *   0b111: 568 Ohm
- * This array maps pull-up strength in Ohms to register values (1+index).
- */
-static const u16 capri_pullup_map[] = {1200, 1800, 720, 2700, 831, 1080, 568};
-
-/* Goes through the configs and update register val/mask */
-static int capri_i2c_pin_update(struct pinctrl_dev *pctldev,
-				unsigned pin,
-				unsigned long *configs,
-				unsigned num_configs,
-				u32 *val,
-				u32 *mask)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-	int i, j;
-	enum pin_config_param param;
-	u16 arg;
-
-	for (i = 0; i < num_configs; i++) {
-		param = pinconf_to_config_param(configs[i]);
-		arg = pinconf_to_config_argument(configs[i]);
-
-		switch (param) {
-		case PIN_CONFIG_BIAS_PULL_UP:
-			for (j = 0; j < ARRAY_SIZE(capri_pullup_map); j++)
-				if (capri_pullup_map[j] == arg)
-					break;
-
-			if (j == ARRAY_SIZE(capri_pullup_map)) {
-				dev_err(pctldev->dev,
-					"Invalid pull-up value (%d) for pin %s "
-					"(%d). Valid values are 568, 720, 831, "
-					"1080, 1200, 1800, 2700 Ohms.\n",
-					arg, pdata->pins[pin].name, pin);
-				return -EINVAL;
-			}
-
-			capri_pin_update(val, mask, j+1,
-					CAPRI_PIN_SHIFT(I2C, PULL_UP_STR),
-					CAPRI_PIN_MASK(I2C, PULL_UP_STR));
-			break;
-
-		case PIN_CONFIG_BIAS_DISABLE:
-			capri_pin_update(val, mask, 0,
-					CAPRI_PIN_SHIFT(I2C, PULL_UP_STR),
-					CAPRI_PIN_MASK(I2C, PULL_UP_STR));
-			break;
-
-		case PIN_CONFIG_SLEW_RATE:
-			arg = (arg >= 1 ? 1 : 0);
-			capri_pin_update(val, mask, arg,
-					CAPRI_PIN_SHIFT(I2C, SLEW),
-					CAPRI_PIN_MASK(I2C, SLEW));
-			break;
-
-		case PIN_CONFIG_INPUT_ENABLE:
-			/* inversed since register is for input _disable_ */
-			arg = (arg >= 1 ? 0 : 1);
-			capri_pin_update(val, mask, arg,
-					CAPRI_PIN_SHIFT(I2C, INPUT_DIS),
-					CAPRI_PIN_MASK(I2C, INPUT_DIS));
-			break;
-
-		default:
-			dev_err(pctldev->dev,
-				"Unrecognized pin config %d for pin %s (%d).\n",
-				param, pdata->pins[pin].name, pin);
-			return -EINVAL;
-
-		} /* switch config */
-	} /* for each config */
-
-	return 0;
-}
-
-/* Goes through the configs and update register val/mask */
-static int capri_hdmi_pin_update(struct pinctrl_dev *pctldev,
-				 unsigned pin,
-				 unsigned long *configs,
-				 unsigned num_configs,
-				 u32 *val,
-				 u32 *mask)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-	int i;
-	enum pin_config_param param;
-	u16 arg;
-
-	for (i = 0; i < num_configs; i++) {
-		param = pinconf_to_config_param(configs[i]);
-		arg = pinconf_to_config_argument(configs[i]);
-
-		switch (param) {
-		case PIN_CONFIG_SLEW_RATE:
-			arg = (arg >= 1 ? 1 : 0);
-			capri_pin_update(val, mask, arg,
-					CAPRI_PIN_SHIFT(HDMI, MODE),
-					CAPRI_PIN_MASK(HDMI, MODE));
-			break;
-
-		case PIN_CONFIG_INPUT_ENABLE:
-			/* inversed since register is for input _disable_ */
-			arg = (arg >= 1 ? 0 : 1);
-			capri_pin_update(val, mask, arg,
-					CAPRI_PIN_SHIFT(HDMI, INPUT_DIS),
-					CAPRI_PIN_MASK(HDMI, INPUT_DIS));
-			break;
-
-		default:
-			dev_err(pctldev->dev,
-				"Unrecognized pin config %d for pin %s (%d).\n",
-				param, pdata->pins[pin].name, pin);
-			return -EINVAL;
-
-		} /* switch config */
-	} /* for each config */
-
-	return 0;
-}
-
-static int capri_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
-					unsigned pin,
-					unsigned long *configs,
-					unsigned num_configs)
-{
-	struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-	enum capri_pin_type pin_type;
-	u32 offset = 4 * pin;
-	u32 cfg_val, cfg_mask;
-	int rc;
-
-	cfg_val = 0;
-	cfg_mask = 0;
-	pin_type = pin_type_get(pctldev, pin);
-
-	/* Different pins have different configuration options */
-	switch (pin_type) {
-	case CAPRI_PIN_TYPE_STD:
-		rc = capri_std_pin_update(pctldev, pin, configs, num_configs,
-			&cfg_val, &cfg_mask);
-		break;
-
-	case CAPRI_PIN_TYPE_I2C:
-		rc = capri_i2c_pin_update(pctldev, pin, configs, num_configs,
-			&cfg_val, &cfg_mask);
-		break;
-
-	case CAPRI_PIN_TYPE_HDMI:
-		rc = capri_hdmi_pin_update(pctldev, pin, configs, num_configs,
-			&cfg_val, &cfg_mask);
-		break;
-
-	default:
-		dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n",
-			pdata->pins[pin].name, pin);
-		return -EINVAL;
-
-	} /* switch pin type */
-
-	if (rc)
-		return rc;
-
-	dev_dbg(pctldev->dev,
-		"%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n",
-		__func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask);
-
-	rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val);
-	if (rc) {
-		dev_err(pctldev->dev,
-			"Error updating register for pin %s (%d).\n",
-			pdata->pins[pin].name, pin);
-		return rc;
-	}
-
-	return 0;
-}
-
-static struct pinconf_ops capri_pinctrl_pinconf_ops = {
-	.pin_config_get = capri_pinctrl_pin_config_get,
-	.pin_config_set = capri_pinctrl_pin_config_set,
-};
-
-static struct pinctrl_desc capri_pinctrl_desc = {
-	/* name, pins, npins members initialized in probe function */
-	.pctlops = &capri_pinctrl_ops,
-	.pmxops = &capri_pinctrl_pinmux_ops,
-	.confops = &capri_pinctrl_pinconf_ops,
-	.owner = THIS_MODULE,
-};
-
-int __init capri_pinctrl_probe(struct platform_device *pdev)
-{
-	struct capri_pinctrl_data *pdata = &capri_pinctrl;
-	struct resource *res;
-	struct pinctrl_dev *pctl;
-
-	/* So far We can assume there is only 1 bank of registers */
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "Missing MEM resource\n");
-		return -ENODEV;
-	}
-
-	pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(pdata->reg_base)) {
-		dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
-		return -ENODEV;
-	}
-
-	/* Initialize the dynamic part of pinctrl_desc */
-	pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base,
-		&capri_pinctrl_regmap_config);
-	if (IS_ERR(pdata->regmap)) {
-		dev_err(&pdev->dev, "Regmap MMIO init failed.\n");
-		return -ENODEV;
-	}
-
-	capri_pinctrl_desc.name = dev_name(&pdev->dev);
-	capri_pinctrl_desc.pins = capri_pinctrl.pins;
-	capri_pinctrl_desc.npins = capri_pinctrl.npins;
-
-	pctl = pinctrl_register(&capri_pinctrl_desc,
-				&pdev->dev,
-				pdata);
-	if (!pctl) {
-		dev_err(&pdev->dev, "Failed to register pinctrl\n");
-		return -ENODEV;
-	}
-
-	platform_set_drvdata(pdev, pdata);
-
-	return 0;
-}
-
-static struct of_device_id capri_pinctrl_of_match[] = {
-	{ .compatible = "brcm,bcm11351-pinctrl", },
-	{ },
-};
-
-static struct platform_driver capri_pinctrl_driver = {
-	.driver = {
-		.name = "bcm-capri-pinctrl",
-		.owner = THIS_MODULE,
-		.of_match_table = capri_pinctrl_of_match,
-	},
-};
-
-module_platform_driver_probe(capri_pinctrl_driver, capri_pinctrl_probe);
-
-MODULE_AUTHOR("Sherman Yin <syin@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom Capri pinctrl driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
index 38d579b..e43fbce 100644
--- a/drivers/pinctrl/pinctrl-msm.c
+++ b/drivers/pinctrl/pinctrl-msm.c
@@ -665,7 +665,10 @@
 	spin_lock_irqsave(&pctrl->lock, flags);
 
 	val = readl(pctrl->regs + g->intr_status_reg);
-	val &= ~BIT(g->intr_status_bit);
+	if (g->intr_ack_high)
+		val |= BIT(g->intr_status_bit);
+	else
+		val &= ~BIT(g->intr_status_bit);
 	writel(val, pctrl->regs + g->intr_status_reg);
 
 	if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
@@ -744,6 +747,7 @@
 			break;
 		case IRQ_TYPE_EDGE_BOTH:
 			val |= BIT(g->intr_detection_bit);
+			val |= BIT(g->intr_polarity_bit);
 			break;
 		case IRQ_TYPE_LEVEL_LOW:
 			break;
diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/pinctrl-msm.h
index 8fbe9fb..6e26f1b 100644
--- a/drivers/pinctrl/pinctrl-msm.h
+++ b/drivers/pinctrl/pinctrl-msm.h
@@ -84,6 +84,7 @@
 
 	unsigned intr_enable_bit:5;
 	unsigned intr_status_bit:5;
+	unsigned intr_ack_high:1;
 
 	unsigned intr_target_bit:5;
 	unsigned intr_raw_status_bit:5;
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 208341f..8f6f16e 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -877,7 +877,6 @@
 	struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
 	u32 status;
 
-	pr_err("PLONK IRQ %d\n", irq);
 	clk_enable(nmk_chip->clk);
 	status = readl(nmk_chip->addr + NMK_GPIO_IS);
 	clk_disable(nmk_chip->clk);
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 46dddc1..96c60d2 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -342,7 +342,7 @@
  * @pin: pin to change
  * @mux: new mux function to set
  */
-static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 {
 	struct rockchip_pinctrl *info = bank->drvdata;
 	void __iomem *reg = info->reg_base + info->ctrl->mux_offset;
@@ -350,6 +350,20 @@
 	u8 bit;
 	u32 data;
 
+	/*
+	 * The first 16 pins of rk3188_bank0 are always gpios and do not have
+	 * a mux register at all.
+	 */
+	if (bank->bank_type == RK3188_BANK0 && pin < 16) {
+		if (mux != RK_FUNC_GPIO) {
+			dev_err(info->dev,
+				"pin %d only supports a gpio mux\n", pin);
+			return -ENOTSUPP;
+		} else {
+			return 0;
+		}
+	}
+
 	dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
 						bank->bank_num, pin, mux);
 
@@ -365,6 +379,8 @@
 	writel(data, reg);
 
 	spin_unlock_irqrestore(&bank->slock, flags);
+
+	return 0;
 }
 
 #define RK2928_PULL_OFFSET		0x118
@@ -560,7 +576,7 @@
 	const unsigned int *pins = info->groups[group].pins;
 	const struct rockchip_pin_config *data = info->groups[group].data;
 	struct rockchip_pin_bank *bank;
-	int cnt;
+	int cnt, ret = 0;
 
 	dev_dbg(info->dev, "enable function %s group %s\n",
 		info->functions[selector].name, info->groups[group].name);
@@ -571,8 +587,18 @@
 	 */
 	for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
 		bank = pin_to_bank(info, pins[cnt]);
-		rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
-				 data[cnt].func);
+		ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
+				       data[cnt].func);
+		if (ret)
+			break;
+	}
+
+	if (ret) {
+		/* revert the already done pin settings */
+		for (cnt--; cnt >= 0; cnt--)
+			rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
+
+		return ret;
 	}
 
 	return 0;
@@ -607,7 +633,7 @@
 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 	struct rockchip_pin_bank *bank;
 	struct gpio_chip *chip;
-	int pin;
+	int pin, ret;
 	u32 data;
 
 	chip = range->gc;
@@ -617,7 +643,9 @@
 	dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
 		 offset, range->name, pin, input ? "input" : "output");
 
-	rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+	ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+	if (ret < 0)
+		return ret;
 
 	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
 	/* set bit to 1 for output, 0 for input */
@@ -1144,9 +1172,13 @@
 	u32 polarity;
 	u32 level;
 	u32 data;
+	int ret;
 
 	/* make sure the pin is configured as gpio input */
-	rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+	ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+	if (ret < 0)
+		return ret;
+
 	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
 	data &= ~mask;
 	writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
@@ -1534,7 +1566,7 @@
 		.nr_banks		= ARRAY_SIZE(rk3188_pin_banks),
 		.label			= "RK3188-GPIO",
 		.type			= RK3188,
-		.mux_offset		= 0x68,
+		.mux_offset		= 0x60,
 		.pull_calc_reg		= rk3188_calc_pull_reg_and_bit,
 };
 
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index e25d2bc..296b0ec 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -142,7 +142,10 @@
 		delta = ktime_to_ns(kt);
 		err = ops->adjtime(ops, delta);
 	} else if (tx->modes & ADJ_FREQUENCY) {
-		err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq));
+		s32 ppb = scaled_ppm_to_ppb(tx->freq);
+		if (ppb > ops->max_adj || ppb < -ops->max_adj)
+			return -ERANGE;
+		err = ops->adjfreq(ops, ppb);
 		ptp->dialed_frequency = tx->freq;
 	} else if (tx->modes == 0) {
 		tx->freq = ptp->dialed_frequency;
diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c
index 8ad26b8..cb2d4f0 100644
--- a/drivers/pwm/pwm-spear.c
+++ b/drivers/pwm/pwm-spear.c
@@ -2,7 +2,7 @@
  * ST Microelectronics SPEAr Pulse Width Modulator driver
  *
  * Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
@@ -264,6 +264,6 @@
 module_platform_driver(spear_pwm_driver);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
 MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.com>");
 MODULE_ALIAS("platform:spear-pwm");
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 1990285..c316051 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -1252,7 +1252,7 @@
 		return rc;
 
 	sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
-	rc = PTR_RET(sclp_pdev);
+	rc = PTR_ERR_OR_ZERO(sclp_pdev);
 	if (rc)
 		goto fail_platform_driver_unregister;
 
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 6e8f90f..6e14999 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -515,7 +515,7 @@
 	if (rc)
 		goto out;
 	sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
-	rc = PTR_RET(sclp_pdev);
+	rc = PTR_ERR_OR_ZERO(sclp_pdev);
 	if (rc)
 		goto out_driver;
 	sclp_add_standby_memory();
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 4eed38c..cd9c919 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -97,15 +97,18 @@
 static int __sclp_vt220_emit(struct sclp_vt220_request *request);
 static void sclp_vt220_emit_current(void);
 
-/* Registration structure for our interest in SCLP event buffers */
+/* Registration structure for SCLP output event buffers */
 static struct sclp_register sclp_vt220_register = {
 	.send_mask		= EVTYP_VT220MSG_MASK,
-	.receive_mask		= EVTYP_VT220MSG_MASK,
-	.state_change_fn	= NULL,
-	.receiver_fn		= sclp_vt220_receiver_fn,
 	.pm_event_fn		= sclp_vt220_pm_event_fn,
 };
 
+/* Registration structure for SCLP input event buffers */
+static struct sclp_register sclp_vt220_register_input = {
+	.receive_mask		= EVTYP_VT220MSG_MASK,
+	.receiver_fn		= sclp_vt220_receiver_fn,
+};
+
 
 /*
  * Put provided request buffer back into queue and check emit pending
@@ -715,9 +718,14 @@
 	rc = tty_register_driver(driver);
 	if (rc)
 		goto out_init;
+	rc = sclp_register(&sclp_vt220_register_input);
+	if (rc)
+		goto out_reg;
 	sclp_vt220_driver = driver;
 	return 0;
 
+out_reg:
+	tty_unregister_driver(driver);
 out_init:
 	__sclp_vt220_cleanup();
 out_driver:
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index fd7b3bd..d837c3c 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -3348,7 +3348,7 @@
 	}
 	CLAW_DBF_TEXT(2, setup, "init_mod");
 	claw_root_dev = root_device_register("claw");
-	ret = PTR_RET(claw_root_dev);
+	ret = PTR_ERR_OR_ZERO(claw_root_dev);
 	if (ret)
 		goto register_err;
 	ret = ccw_driver_register(&claw_ccw_driver);
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 70b3a02..03b6ad0 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1837,7 +1837,7 @@
 	if (ret)
 		goto out_err;
 	ctcm_root_dev = root_device_register("ctcm");
-	ret = PTR_RET(ctcm_root_dev);
+	ret = PTR_ERR_OR_ZERO(ctcm_root_dev);
 	if (ret)
 		goto register_err;
 	ret = ccw_driver_register(&ctcm_ccw_driver);
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index c461f2a..8d5d969 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -2442,7 +2442,7 @@
 	if (rc)
 		goto out_err;
 	lcs_root_dev = root_device_register("lcs");
-	rc = PTR_RET(lcs_root_dev);
+	rc = PTR_ERR_OR_ZERO(lcs_root_dev);
 	if (rc)
 		goto register_err;
 	rc = ccw_driver_register(&lcs_ccw_driver);
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 5333b2c..a2088af 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -268,10 +268,8 @@
 #define QETH_NO_PRIO_QUEUEING 0
 #define QETH_PRIO_Q_ING_PREC  1
 #define QETH_PRIO_Q_ING_TOS   2
-#define IP_TOS_LOWDELAY 0x10
-#define IP_TOS_HIGHTHROUGHPUT 0x08
-#define IP_TOS_HIGHRELIABILITY 0x04
-#define IP_TOS_NOTIMPORTANT 0x02
+#define QETH_PRIO_Q_ING_SKB   3
+#define QETH_PRIO_Q_ING_VLAN  4
 
 /* Packing */
 #define QETH_LOW_WATERMARK_PACK  2
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 22470a3..34993009 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -20,6 +20,7 @@
 #include <linux/kthread.h>
 #include <linux/slab.h>
 #include <net/iucv/af_iucv.h>
+#include <net/dsfield.h>
 
 #include <asm/ebcdic.h>
 #include <asm/io.h>
@@ -3670,42 +3671,56 @@
 }
 EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);
 
+/**
+ * Note: Function assumes that we have 4 outbound queues.
+ */
 int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
 			int ipv, int cast_type)
 {
-	if (!ipv && (card->info.type == QETH_CARD_TYPE_OSD ||
-		     card->info.type == QETH_CARD_TYPE_OSX))
-		return card->qdio.default_out_queue;
-	switch (card->qdio.no_out_queues) {
-	case 4:
-		if (cast_type && card->info.is_multicast_different)
-			return card->info.is_multicast_different &
-				(card->qdio.no_out_queues - 1);
-		if (card->qdio.do_prio_queueing && (ipv == 4)) {
-			const u8 tos = ip_hdr(skb)->tos;
+	__be16 *tci;
+	u8 tos;
 
-			if (card->qdio.do_prio_queueing ==
-				QETH_PRIO_Q_ING_TOS) {
-				if (tos & IP_TOS_NOTIMPORTANT)
-					return 3;
-				if (tos & IP_TOS_HIGHRELIABILITY)
-					return 2;
-				if (tos & IP_TOS_HIGHTHROUGHPUT)
-					return 1;
-				if (tos & IP_TOS_LOWDELAY)
-					return 0;
-			}
-			if (card->qdio.do_prio_queueing ==
-				QETH_PRIO_Q_ING_PREC)
-				return 3 - (tos >> 6);
-		} else if (card->qdio.do_prio_queueing && (ipv == 6)) {
-			/* TODO: IPv6!!! */
+	if (cast_type && card->info.is_multicast_different)
+		return card->info.is_multicast_different &
+			(card->qdio.no_out_queues - 1);
+
+	switch (card->qdio.do_prio_queueing) {
+	case QETH_PRIO_Q_ING_TOS:
+	case QETH_PRIO_Q_ING_PREC:
+		switch (ipv) {
+		case 4:
+			tos = ipv4_get_dsfield(ip_hdr(skb));
+			break;
+		case 6:
+			tos = ipv6_get_dsfield(ipv6_hdr(skb));
+			break;
+		default:
+			return card->qdio.default_out_queue;
 		}
-		return card->qdio.default_out_queue;
-	case 1: /* fallthrough for single-out-queue 1920-device */
+		if (card->qdio.do_prio_queueing == QETH_PRIO_Q_ING_PREC)
+			return ~tos >> 6 & 3;
+		if (tos & IPTOS_MINCOST)
+			return 3;
+		if (tos & IPTOS_RELIABILITY)
+			return 2;
+		if (tos & IPTOS_THROUGHPUT)
+			return 1;
+		if (tos & IPTOS_LOWDELAY)
+			return 0;
+		break;
+	case QETH_PRIO_Q_ING_SKB:
+		if (skb->priority > 5)
+			return 0;
+		return ~skb->priority >> 1 & 3;
+	case QETH_PRIO_Q_ING_VLAN:
+		tci = &((struct ethhdr *)skb->data)->h_proto;
+		if (*tci == ETH_P_8021Q)
+			return ~*(tci + 1) >> (VLAN_PRIO_SHIFT + 1) & 3;
+		break;
 	default:
-		return card->qdio.default_out_queue;
+		break;
 	}
+	return card->qdio.default_out_queue;
 }
 EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
 
@@ -5824,7 +5839,7 @@
 	if (rc)
 		goto out_err;
 	qeth_core_root_dev = root_device_register("qeth");
-	rc = PTR_RET(qeth_core_root_dev);
+	rc = PTR_ERR_OR_ZERO(qeth_core_root_dev);
 	if (rc)
 		goto register_err;
 	qeth_core_header_cache = kmem_cache_create("qeth_hdr",
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 425c0ec..8a25a2b 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -217,6 +217,10 @@
 		return sprintf(buf, "%s\n", "by precedence");
 	case QETH_PRIO_Q_ING_TOS:
 		return sprintf(buf, "%s\n", "by type of service");
+	case QETH_PRIO_Q_ING_SKB:
+		return sprintf(buf, "%s\n", "by skb-priority");
+	case QETH_PRIO_Q_ING_VLAN:
+		return sprintf(buf, "%s\n", "by VLAN headers");
 	default:
 		return sprintf(buf, "always queue %i\n",
 			       card->qdio.default_out_queue);
@@ -250,11 +254,23 @@
 	}
 
 	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "prio_queueing_prec"))
+	if (!strcmp(tmp, "prio_queueing_prec")) {
 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
-	else if (!strcmp(tmp, "prio_queueing_tos"))
+		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+	} else if (!strcmp(tmp, "prio_queueing_skb")) {
+		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_SKB;
+		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+	} else if (!strcmp(tmp, "prio_queueing_tos")) {
 		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
-	else if (!strcmp(tmp, "no_prio_queueing:0")) {
+		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+	} else if (!strcmp(tmp, "prio_queueing_vlan")) {
+		if (!card->options.layer2) {
+			rc = -ENOTSUPP;
+			goto out;
+		}
+		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_VLAN;
+		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+	} else if (!strcmp(tmp, "no_prio_queueing:0")) {
 		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
 		card->qdio.default_out_queue = 0;
 	} else if (!strcmp(tmp, "no_prio_queueing:1")) {
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8dea3f1..e232cec 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -725,15 +725,20 @@
 	int elements = 0;
 	struct qeth_card *card = dev->ml_priv;
 	struct sk_buff *new_skb = skb;
-	int ipv = qeth_get_ip_version(skb);
 	int cast_type = qeth_l2_get_cast_type(card, skb);
-	struct qeth_qdio_out_q *queue = card->qdio.out_qs
-		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
+	struct qeth_qdio_out_q *queue;
 	int tx_bytes = skb->len;
 	int data_offset = -1;
 	int elements_needed = 0;
 	int hd_len = 0;
 
+	if (card->qdio.do_prio_queueing || (cast_type &&
+					card->info.is_multicast_different))
+		queue = card->qdio.out_qs[qeth_get_priority_queue(card, skb,
+					qeth_get_ip_version(skb), cast_type)];
+	else
+		queue = card->qdio.out_qs[card->qdio.default_out_queue];
+
 	if ((card->state != CARD_STATE_UP) || !card->lan_online) {
 		card->stats.tx_carrier_errors++;
 		goto tx_drop;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3524d34..c8d91d7 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2926,8 +2926,11 @@
 	struct sk_buff *new_skb = NULL;
 	int ipv = qeth_get_ip_version(skb);
 	int cast_type = qeth_l3_get_cast_type(card, skb);
-	struct qeth_qdio_out_q *queue = card->qdio.out_qs
-		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
+	struct qeth_qdio_out_q *queue =
+		card->qdio.out_qs[card->qdio.do_prio_queueing
+			|| (cast_type && card->info.is_multicast_different) ?
+			qeth_get_priority_queue(card, skb, ipv, cast_type) :
+			card->qdio.default_out_queue];
 	int tx_bytes = skb->len;
 	bool large_send;
 	int data_offset = -1;
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ea5efb4..22365f1 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -40,8 +40,6 @@
 
 source "drivers/staging/panel/Kconfig"
 
-source "drivers/staging/rtl8187se/Kconfig"
-
 source "drivers/staging/rtl8192u/Kconfig"
 
 source "drivers/staging/rtl8192e/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 86e020c..fbe84ed 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -12,7 +12,6 @@
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_FB_OLPC_DCON)	+= olpc_dcon/
 obj-$(CONFIG_PANEL)		+= panel/
-obj-$(CONFIG_R8187SE)		+= rtl8187se/
 obj-$(CONFIG_RTL8192U)		+= rtl8192u/
 obj-$(CONFIG_RTL8192E)		+= rtl8192e/
 obj-$(CONFIG_R8712U)		+= rtl8712/
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c
index 924fce9..2575950 100644
--- a/drivers/staging/comedi/comedi_buf.c
+++ b/drivers/staging/comedi/comedi_buf.c
@@ -61,6 +61,8 @@
 			      struct comedi_subdevice *s)
 {
 	struct comedi_async *async = s->async;
+	struct comedi_buf_map *bm;
+	unsigned long flags;
 
 	if (async->prealloc_buf) {
 		vunmap(async->prealloc_buf);
@@ -68,8 +70,11 @@
 		async->prealloc_bufsz = 0;
 	}
 
-	comedi_buf_map_put(async->buf_map);
+	spin_lock_irqsave(&s->spin_lock, flags);
+	bm = async->buf_map;
 	async->buf_map = NULL;
+	spin_unlock_irqrestore(&s->spin_lock, flags);
+	comedi_buf_map_put(bm);
 }
 
 static void __comedi_buf_alloc(struct comedi_device *dev,
@@ -80,6 +85,7 @@
 	struct page **pages = NULL;
 	struct comedi_buf_map *bm;
 	struct comedi_buf_page *buf;
+	unsigned long flags;
 	unsigned i;
 
 	if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
@@ -92,8 +98,10 @@
 	if (!bm)
 		return;
 
-	async->buf_map = bm;
 	kref_init(&bm->refcount);
+	spin_lock_irqsave(&s->spin_lock, flags);
+	async->buf_map = bm;
+	spin_unlock_irqrestore(&s->spin_lock, flags);
 	bm->dma_dir = s->async_dma_dir;
 	if (bm->dma_dir != DMA_NONE)
 		/* Need ref to hardware device to free buffer later. */
@@ -127,7 +135,9 @@
 
 		pages[i] = virt_to_page(buf->virt_addr);
 	}
+	spin_lock_irqsave(&s->spin_lock, flags);
 	bm->n_pages = i;
+	spin_unlock_irqrestore(&s->spin_lock, flags);
 
 	/* vmap the prealloc_buf if all the pages were allocated */
 	if (i == n_pages)
@@ -150,6 +160,29 @@
 	return 1;
 }
 
+/* returns s->async->buf_map and increments its kref refcount */
+struct comedi_buf_map *
+comedi_buf_map_from_subdev_get(struct comedi_subdevice *s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_buf_map *bm = NULL;
+	unsigned long flags;
+
+	if (!async)
+		return NULL;
+
+	spin_lock_irqsave(&s->spin_lock, flags);
+	bm = async->buf_map;
+	/* only want it if buffer pages allocated */
+	if (bm && bm->n_pages)
+		comedi_buf_map_get(bm);
+	else
+		bm = NULL;
+	spin_unlock_irqrestore(&s->spin_lock, flags);
+
+	return bm;
+}
+
 bool comedi_buf_is_mmapped(struct comedi_async *async)
 {
 	struct comedi_buf_map *bm = async->buf_map;
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index ea6dc36..acc8019 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1926,14 +1926,21 @@
 	struct comedi_device *dev = file->private_data;
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
-	struct comedi_buf_map *bm;
+	struct comedi_buf_map *bm = NULL;
 	unsigned long start = vma->vm_start;
 	unsigned long size;
 	int n_pages;
 	int i;
 	int retval;
 
-	mutex_lock(&dev->mutex);
+	/*
+	 * 'trylock' avoids circular dependency with current->mm->mmap_sem
+	 * and down-reading &dev->attach_lock should normally succeed without
+	 * contention unless the device is in the process of being attached
+	 * or detached.
+	 */
+	if (!down_read_trylock(&dev->attach_lock))
+		return -EAGAIN;
 
 	if (!dev->attached) {
 		dev_dbg(dev->class_dev, "no driver attached\n");
@@ -1973,7 +1980,9 @@
 	}
 
 	n_pages = size >> PAGE_SHIFT;
-	bm = async->buf_map;
+
+	/* get reference to current buf map (if any) */
+	bm = comedi_buf_map_from_subdev_get(s);
 	if (!bm || n_pages > bm->n_pages) {
 		retval = -EINVAL;
 		goto done;
@@ -1997,7 +2006,8 @@
 
 	retval = 0;
 done:
-	mutex_unlock(&dev->mutex);
+	up_read(&dev->attach_lock);
+	comedi_buf_map_put(bm);	/* put reference to buf map - okay if NULL */
 	return retval;
 }
 
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
index 9a74657..a492f2d 100644
--- a/drivers/staging/comedi/comedi_internal.h
+++ b/drivers/staging/comedi/comedi_internal.h
@@ -19,6 +19,8 @@
 bool comedi_buf_is_mmapped(struct comedi_async *async);
 void comedi_buf_map_get(struct comedi_buf_map *bm);
 int comedi_buf_map_put(struct comedi_buf_map *bm);
+struct comedi_buf_map *comedi_buf_map_from_subdev_get(
+		struct comedi_subdevice *s);
 unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
 void comedi_device_cancel_all(struct comedi_device *dev);
 
diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c
index f96dcec..7ac2602 100644
--- a/drivers/staging/goldfish/goldfish_audio.c
+++ b/drivers/staging/goldfish/goldfish_audio.c
@@ -334,6 +334,7 @@
 	return 0;
 
 err_misc_register_failed:
+	free_irq(data->irq, data);
 err_request_irq_failed:
 	dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE,
 					data->buffer_virt, data->buffer_phys);
diff --git a/drivers/staging/gs_fpgaboot/Makefile b/drivers/staging/gs_fpgaboot/Makefile
index 34cb606..d2f0211 100644
--- a/drivers/staging/gs_fpgaboot/Makefile
+++ b/drivers/staging/gs_fpgaboot/Makefile
@@ -1,4 +1,2 @@
 gs_fpga-y	+= gs_fpgaboot.o io.o
 obj-$(CONFIG_GS_FPGABOOT)	+= gs_fpga.o
-
-ccflags-$(CONFIG_GS_FPGA_DEBUG)	:= -DDEBUG
diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
index 89bc84d..7506900 100644
--- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
+++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
@@ -373,7 +373,6 @@
 	r = -1;
 
 	pr_info("FPGA DOWNLOAD --->\n");
-	pr_info("built at %s UTC\n", __TIMESTAMP__);
 
 	pr_info("FPGA image file name: %s\n", file);
 
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
deleted file mode 100644
index ff8d41e..0000000
--- a/drivers/staging/rtl8187se/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config R8187SE
-	tristate "RealTek RTL8187SE Wireless LAN NIC driver"
-	depends on PCI && WLAN
-	depends on m
-	select WIRELESS_EXT
-	select WEXT_PRIV
-	select EEPROM_93CX6
-	select CRYPTO
-	---help---
-	  If built as a module, it will be called r8187se.ko.
diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile
deleted file mode 100644
index 91d1aa2..0000000
--- a/drivers/staging/rtl8187se/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y
-#ccflags-y += -std=gnu89
-#ccflags-y += -O2
-#CC            = gcc
-
-ccflags-y := -DSW_ANTE
-ccflags-y += -DTX_TRACK
-ccflags-y += -DHIGH_POWER
-ccflags-y += -DSW_DIG
-ccflags-y += -DRATE_ADAPT
-
-#enable it for legacy power save, disable it for leisure power save
-ccflags-y += -DENABLE_LPS
-
-
-#ccflags-y := -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
-
-r8187se-y :=			\
-		r8180_core.o		\
-		r8180_wx.o		\
-		r8180_rtl8225z2.o	\
-		r8185b_init.o		\
-		r8180_dm.o		\
-		ieee80211/dot11d.o			\
-		ieee80211/ieee80211_softmac.o		\
-		ieee80211/ieee80211_rx.o		\
-		ieee80211/ieee80211_tx.o		\
-		ieee80211/ieee80211_wx.o		\
-		ieee80211/ieee80211_module.o		\
-		ieee80211/ieee80211_softmac_wx.o	\
-		ieee80211/ieee80211_crypt.o		\
-		ieee80211/ieee80211_crypt_tkip.o	\
-		ieee80211/ieee80211_crypt_ccmp.o	\
-		ieee80211/ieee80211_crypt_wep.o
-
-obj-$(CONFIG_R8187SE)	+= r8187se.o
-
diff --git a/drivers/staging/rtl8187se/Module.symvers b/drivers/staging/rtl8187se/Module.symvers
deleted file mode 100644
index e69de29..0000000
--- a/drivers/staging/rtl8187se/Module.symvers
+++ /dev/null
diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO
deleted file mode 100644
index 704949a..0000000
--- a/drivers/staging/rtl8187se/TODO
+++ /dev/null
@@ -1,13 +0,0 @@
-TODO:
-- prepare private ieee80211 stack for merge with rtl8192su's version:
-  - add hwsec_active flag to struct ieee80211_device
-  - add bHwSec flag to cb_desc structure
-- switch to use shared "librtl" instead of private ieee80211 stack
-- switch to use LIB80211
-- switch to use MAC80211
-- use kernel coding style
-- checkpatch.pl fixes
-- sparse fixes
-- integrate with drivers/net/wireless/rtl818x
-
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c
deleted file mode 100644
index 4483c2c..0000000
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.c
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "dot11d.h"
-
-void Dot11d_Init(struct ieee80211_device *ieee)
-{
-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
-	pDot11dInfo->bEnabled = 0;
-
-	pDot11dInfo->State = DOT11D_STATE_NONE;
-	pDot11dInfo->CountryIeLen = 0;
-	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
-	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
-	RESET_CIE_WATCHDOG(ieee);
-
-	netdev_info(ieee->dev, "Dot11d_Init()\n");
-}
-
-/* Reset to the state as we are just entering a regulatory domain. */
-void Dot11d_Reset(struct ieee80211_device *ieee)
-{
-	u32 i;
-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
-	/* Clear old channel map */
-	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
-	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
-	/* Set new channel map */
-	for (i = 1; i <= 11; i++)
-		(pDot11dInfo->channel_map)[i] = 1;
-
-	for (i = 12; i <= 14; i++)
-		(pDot11dInfo->channel_map)[i] = 2;
-
-	pDot11dInfo->State = DOT11D_STATE_NONE;
-	pDot11dInfo->CountryIeLen = 0;
-	RESET_CIE_WATCHDOG(ieee);
-}
-
-/*
- * Description:
- *	Update country IE from Beacon or Probe Response and configure PHY for
- *	operation in the regulatory domain.
- *
- * TODO:
- *	Configure Tx power.
- *
- * Assumption:
- *	1. IS_DOT11D_ENABLE() is TRUE.
- *	2. Input IE is an valid one.
- */
-void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
-			    u16 CoutryIeLen, u8 *pCoutryIe)
-{
-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-	u8 i, j, NumTriples, MaxChnlNum;
-	u8 index, MaxTxPowerInDbm;
-	PCHNL_TXPOWER_TRIPLE pTriple;
-
-	if ((CoutryIeLen - 3)%3 != 0) {
-		netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
-		Dot11d_Reset(dev);
-		return;
-	}
-
-	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
-	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
-	MaxChnlNum = 0;
-	NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
-	pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
-	for (i = 0; i < NumTriples; i++) {
-		if (MaxChnlNum >= pTriple->FirstChnl) {
-			/*
-			 * It is not in a monotonically increasing order,
-			 * so stop processing.
-			 */
-			netdev_info(dev->dev,
-				    "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
-			Dot11d_Reset(dev);
-			return;
-		}
-		if (MAX_CHANNEL_NUMBER <
-		    (pTriple->FirstChnl + pTriple->NumChnls)) {
-			/*
-			 * It is not a valid set of channel id,
-			 * so stop processing
-			 */
-			netdev_info(dev->dev,
-				    "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
-			Dot11d_Reset(dev);
-			return;
-		}
-
-		for (j = 0; j < pTriple->NumChnls; j++) {
-			index = pTriple->FirstChnl + j;
-			pDot11dInfo->channel_map[index] = 1;
-			MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm;
-			pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm;
-			MaxChnlNum = pTriple->FirstChnl + j;
-		}
-
-		pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3);
-	}
-#if 1
-	netdev_info(dev->dev, "Channel List:");
-	for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
-		if (pDot11dInfo->channel_map[i] > 0)
-			netdev_info(dev->dev, " %d", i);
-	netdev_info(dev->dev, "\n");
-#endif
-
-	UPDATE_CIE_SRC(dev, pTaddr);
-
-	pDot11dInfo->CountryIeLen = CoutryIeLen;
-	memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
-	pDot11dInfo->State = DOT11D_STATE_LEARNED;
-}
-
-u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
-{
-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-	u8 MaxTxPwrInDbm = 255;
-
-	if (MAX_CHANNEL_NUMBER < Channel) {
-		netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
-		return MaxTxPwrInDbm;
-	}
-	if (pDot11dInfo->channel_map[Channel])
-		MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
-
-	return MaxTxPwrInDbm;
-}
-
-
-void DOT11D_ScanComplete(struct ieee80211_device *dev)
-{
-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
-	switch (pDot11dInfo->State) {
-	case DOT11D_STATE_LEARNED:
-		pDot11dInfo->State = DOT11D_STATE_DONE;
-		break;
-
-	case DOT11D_STATE_DONE:
-		if (GET_CIE_WATCHDOG(dev) == 0) {
-			/* Reset country IE if previous one is gone. */
-			Dot11d_Reset(dev);
-		}
-		break;
-	case DOT11D_STATE_NONE:
-		break;
-	}
-}
-
-int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
-{
-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
-	if (MAX_CHANNEL_NUMBER < channel) {
-		netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
-		return 0;
-	}
-	if (pDot11dInfo->channel_map[channel] > 0)
-		return 1;
-	return 0;
-}
-
-int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
-{
-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-	u8 default_chn = 0;
-	u32 i = 0;
-
-	for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
-		if (pDot11dInfo->channel_map[i] > 0) {
-			default_chn = i;
-			break;
-		}
-	}
-
-	if (MAX_CHANNEL_NUMBER < channel) {
-		netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
-		return default_chn;
-	}
-
-	if (pDot11dInfo->channel_map[channel] > 0)
-		return channel;
-
-	return default_chn;
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h
deleted file mode 100644
index f996691..0000000
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-/* #define ENABLE_DOT11D */
-
-/* #define DOT11D_MAX_CHNL_NUM 83 */
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
-	u8 FirstChnl;
-	u8  NumChnls;
-	u8  MaxTxPowerInDbm;
-} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
-	DOT11D_STATE_NONE = 0,
-	DOT11D_STATE_LEARNED,
-	DOT11D_STATE_DONE,
-} DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
-	/* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */
-
-	bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
-
-	u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
-	u8  CountryIeBuf[MAX_IE_LEN];
-	u8  CountryIeSrcAddr[6]; /* Source AP of the country IE. */
-	u8  CountryIeWatchdog;
-
-	u8  channel_map[MAX_CHANNEL_NUMBER+1];  /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
-	/* u8  ChnlListLen; // #Bytes valid in ChnlList[]. */
-	/* u8  ChnlList[DOT11D_MAX_CHNL_NUM]; */
-	u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
-	DOT11D_STATE State;
-} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-
-#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1:0)
-#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
-	(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
-	FALSE : \
-	(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-void Dot11d_Init(struct ieee80211_device *dev);
-void Dot11d_Reset(struct ieee80211_device *dev);
-void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
-			    u16 CoutryIeLen, u8 *pCoutryIe);
-u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel);
-void DOT11D_ScanComplete(struct ieee80211_device *dev);
-int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
-int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
-
-#endif /*  #ifndef __INC_DOT11D_H */
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
deleted file mode 100644
index d1763b7..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ /dev/null
@@ -1,1496 +0,0 @@
-/*
- * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andrea.merello@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h>   /* ARRAY_SIZE */
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/semaphore.h>
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-#include <linux/interrupt.h>
-
-#define KEY_TYPE_NA		0x0
-#define KEY_TYPE_WEP40 		0x1
-#define KEY_TYPE_TKIP		0x2
-#define KEY_TYPE_CCMP		0x4
-#define KEY_TYPE_WEP104		0x5
-
-#define aSifsTime					10
-
-#define MGMT_QUEUE_NUM 5
-
-
-#define IEEE_CMD_SET_WPA_PARAM			1
-#define	IEEE_CMD_SET_WPA_IE			2
-#define IEEE_CMD_SET_ENCRYPTION			3
-#define IEEE_CMD_MLME				4
-
-#define IEEE_PARAM_WPA_ENABLED			1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES		2
-#define IEEE_PARAM_DROP_UNENCRYPTED		3
-#define IEEE_PARAM_PRIVACY_INVOKED		4
-#define IEEE_PARAM_AUTH_ALGS			5
-#define IEEE_PARAM_IEEE_802_1X			6
-//It should consistent with the driver_XXX.c
-//   David, 2006.9.26
-#define IEEE_PARAM_WPAX_SELECT			7
-//Added for notify the encryption type selection
-//   David, 2006.9.26
-#define IEEE_PROTO_WPA				1
-#define IEEE_PROTO_RSN				2
-//Added for notify the encryption type selection
-//   David, 2006.9.26
-#define IEEE_WPAX_USEGROUP			0
-#define IEEE_WPAX_WEP40				1
-#define IEEE_WPAX_TKIP				2
-#define IEEE_WPAX_WRAP   			3
-#define IEEE_WPAX_CCMP				4
-#define IEEE_WPAX_WEP104			5
-
-#define IEEE_KEY_MGMT_IEEE8021X			1
-#define IEEE_KEY_MGMT_PSK			2
-
-
-
-#define IEEE_MLME_STA_DEAUTH			1
-#define IEEE_MLME_STA_DISASSOC			2
-
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG		2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR		3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED		4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED		5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED		6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED		7
-
-
-#define	IEEE_CRYPT_ALG_NAME_LEN			16
-
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-
-//by amy for ps
-typedef struct ieee_param {
-	u32 cmd;
-	u8 sta_addr[ETH_ALEN];
-        union {
-		struct {
-			u8 name;
-			u32 value;
-		} wpa_param;
-		struct {
-			u32 len;
-			u8 reserved[32];
-			u8 data[0];
-		} wpa_ie;
-	        struct{
-			int command;
-    			int reason_code;
-		} mlme;
-		struct {
-			u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
-			u8 set_tx;
-			u32 err;
-			u8 idx;
-			u8 seq[8]; /* sequence counter (set: RX, get: TX) */
-			u16 key_len;
-			u8 key[0];
-		} crypt;
-
-	} u;
-}ieee_param;
-
-
-#define MSECS(t) msecs_to_jiffies(t)
-#define msleep_interruptible_rtl  msleep_interruptible
-
-#define IEEE80211_DATA_LEN		2304
-/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
-   6.2.1.1.2.
-
-   The figure in section 7.1.2 suggests a body size of up to 2312
-   bytes is allowed, which is a bit confusing, I suspect this
-   represents the 2304 bytes of real data, plus a possible 8 bytes of
-   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-
-#define IEEE80211_3ADDR_LEN 24
-#define IEEE80211_4ADDR_LEN 30
-#define IEEE80211_FCS_LEN    4
-#define IEEE80211_HLEN			IEEE80211_4ADDR_LEN
-#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-#define MIN_FRAG_THRESHOLD     256U
-#define	MAX_FRAG_THRESHOLD     2346U
-
-/* Frame control field constants */
-#define IEEE80211_FCTL_DSTODS		0x0300 //added by david
-#define IEEE80211_FCTL_WEP		0x4000
-
-/* debug macros */
-
-#ifdef CONFIG_IEEE80211_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
-  printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
-         in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#endif	/* CONFIG_IEEE80211_DEBUG */
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IEEE80211_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/ipw/debug_level
- *
- * you simply need to add your entry to the ipw_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
- *
- */
-
-#define IEEE80211_DL_INFO          (1<<0)
-#define IEEE80211_DL_WX            (1<<1)
-#define IEEE80211_DL_SCAN          (1<<2)
-#define IEEE80211_DL_STATE         (1<<3)
-#define IEEE80211_DL_MGMT          (1<<4)
-#define IEEE80211_DL_FRAG          (1<<5)
-#define IEEE80211_DL_EAP           (1<<6)
-#define IEEE80211_DL_DROP          (1<<7)
-
-#define IEEE80211_DL_TX            (1<<8)
-#define IEEE80211_DL_RX            (1<<9)
-
-#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
-#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
-#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
-
-#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
-#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
-//#define IEEE_DEBUG_SCAN  IEEE80211_WARNING
-#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
-#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
-#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
-#define IEEE80211_DEBUG_EAP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
-#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
-#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
-#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
-#include <linux/netdevice.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY		// enable iwspy support
-#endif
-#include <net/iw_handler.h>	// new driver API
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
-
-        u8    dsap;   /* always 0xAA */
-        u8    ssap;   /* always 0xAA */
-        u8    ctrl;   /* always 0x03 */
-        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
-
-} __attribute__ ((packed));
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
-
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq)  ((seq) & IEEE80211_SCTL_SEQ)
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-
-#define IEEE80211_CCK_MODULATION    (1<<0)
-#define IEEE80211_OFDM_MODULATION   (1<<1)
-
-#define IEEE80211_24GHZ_BAND     (1<<0)
-#define IEEE80211_52GHZ_BAND     (1<<1)
-
-#define IEEE80211_CCK_RATE_LEN  		4
-#define IEEE80211_CCK_RATE_1MB		        0x02
-#define IEEE80211_CCK_RATE_2MB		        0x04
-#define IEEE80211_CCK_RATE_5MB		        0x0B
-#define IEEE80211_CCK_RATE_11MB		        0x16
-#define IEEE80211_OFDM_RATE_LEN 		8
-#define IEEE80211_OFDM_RATE_6MB		        0x0C
-#define IEEE80211_OFDM_RATE_9MB		        0x12
-#define IEEE80211_OFDM_RATE_12MB		0x18
-#define IEEE80211_OFDM_RATE_18MB		0x24
-#define IEEE80211_OFDM_RATE_24MB		0x30
-#define IEEE80211_OFDM_RATE_36MB		0x48
-#define IEEE80211_OFDM_RATE_48MB		0x60
-#define IEEE80211_OFDM_RATE_54MB		0x6C
-#define IEEE80211_BASIC_RATE_MASK		0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
-
-#define IEEE80211_CCK_RATES_MASK	        0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
-	IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
-        IEEE80211_CCK_RATE_5MB_MASK | \
-        IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
-	IEEE80211_OFDM_RATE_12MB_MASK | \
-	IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
-	IEEE80211_OFDM_RATE_9MB_MASK  | \
-	IEEE80211_OFDM_RATE_18MB_MASK | \
-	IEEE80211_OFDM_RATE_36MB_MASK | \
-	IEEE80211_OFDM_RATE_48MB_MASK | \
-	IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
-                                IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES	    8
-#define IEEE80211_NUM_CCK_RATES	            4
-#define IEEE80211_OFDM_SHIFT_MASK_A         4
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK		0x0c
-#define IEEE80211_FC0_TYPE_DATA		0x08
-#define IEEE80211_FC0_SUBTYPE_MASK	0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS	0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
-	(((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
-	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
-	u8 mac[ETH_ALEN];
-	u16 seq_num[17];
-	u16 frag_num[17];
-	unsigned long packet_time[17];
-	struct list_head list;
-};
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- *       information for frames received.  Not setting these will not cause
- *       any adverse affects. */
-struct ieee80211_rx_stats {
-	u32 mac_time[2];
-	u8 signalstrength;
-	s8 rssi;
-	u8 signal;
-	u8 noise;
-	u16 rate; /* in 100 kbps */
-	u8 received_channel;
-	u8 control;
-	u8 mask;
-	u8 freq;
-	u16 len;
-	u8 nic_type;
-};
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
-#define IEEE80211_FRAG_CACHE_LEN 4
-
-struct ieee80211_frag_entry {
-	unsigned long first_frag_time;
-	unsigned int seq;
-	unsigned int last_frag;
-	struct sk_buff *skb;
-	u8 src_addr[ETH_ALEN];
-	u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
-	unsigned int tx_unicast_frames;
-	unsigned int tx_multicast_frames;
-	unsigned int tx_fragments;
-	unsigned int tx_unicast_octets;
-	unsigned int tx_multicast_octets;
-	unsigned int tx_deferred_transmissions;
-	unsigned int tx_single_retry_frames;
-	unsigned int tx_multiple_retry_frames;
-	unsigned int tx_retry_limit_exceeded;
-	unsigned int tx_discards;
-	unsigned int rx_unicast_frames;
-	unsigned int rx_multicast_frames;
-	unsigned int rx_fragments;
-	unsigned int rx_unicast_octets;
-	unsigned int rx_multicast_octets;
-	unsigned int rx_fcs_errors;
-	unsigned int rx_discards_no_buffer;
-	unsigned int tx_discards_wrong_sa;
-	unsigned int rx_discards_undecryptable;
-	unsigned int rx_message_in_msg_fragments;
-	unsigned int rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_device;
-
-#include "ieee80211_crypt.h"
-
-#define SEC_KEY_1         (1<<0)
-#define SEC_KEY_2         (1<<1)
-#define SEC_KEY_3         (1<<2)
-#define SEC_KEY_4         (1<<3)
-#define SEC_ACTIVE_KEY    (1<<4)
-#define SEC_AUTH_MODE     (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL         (1<<7)
-#define SEC_ENABLED       (1<<8)
-
-#define SEC_LEVEL_0      0 /* None */
-#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
-
-#define WEP_KEY_LEN_MODIF 32
-
-struct ieee80211_security {
-	u16 active_key:2,
-            enabled:1,
-	    auth_mode:2,
-            auth_algo:4,
-            unicast_uses_group:1;
-	u8 key_sizes[WEP_KEYS];
-	u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
-	u8 level;
-	u16 flags;
-} __attribute__ ((packed));
-
-
-/*
-
- 802.11 data frame from AP
-
-      ,-------------------------------------------------------------------.
-Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
-      |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
-      |      | tion | (BSSID) |         |         | ence |  data   |      |
-      `-------------------------------------------------------------------'
-
-Total: 28-2340 bytes
-
-*/
-
-/* Management Frame Information Element Types */
-enum {
-	MFIE_TYPE_SSID = 0,
-	MFIE_TYPE_RATES = 1,
-	MFIE_TYPE_FH_SET = 2,
-	MFIE_TYPE_DS_SET = 3,
-	MFIE_TYPE_CF_SET = 4,
-	MFIE_TYPE_TIM = 5,
-	MFIE_TYPE_IBSS_SET = 6,
-	MFIE_TYPE_COUNTRY = 7,
-	MFIE_TYPE_CHALLENGE = 16,
-	MFIE_TYPE_ERP = 42,
-	MFIE_TYPE_RSN = 48,
-	MFIE_TYPE_RATES_EX = 50,
-	MFIE_TYPE_GENERIC = 221,
-};
-
-struct ieee80211_header_data {
-	__le16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[6];
-	u8 addr2[6];
-	u8 addr3[6];
-	u16 seq_ctrl;
-};
-
-struct ieee80211_hdr_4addr {
-	__le16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addrqos {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_4addrqos {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-	u16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element_hdr {
-	u8 id;
-	u8 len;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
-	u8 id;
-	u8 len;
-	u8 data[0];
-} __attribute__ ((packed));
-
-struct ieee80211_authentication {
-	struct ieee80211_header_data header;
-	u16 algorithm;
-	u16 transaction;
-	u16 status;
-	//struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc_frame {
-	struct ieee80211_hdr_3addr header;
-	u16    reasoncode;
-} __attribute__ ((packed));
-
-struct ieee80211_probe_request {
-	struct ieee80211_header_data header;
-	/* struct ieee80211_info_element info_element; */
-} __attribute__ ((packed));
-
-struct ieee80211_probe_response {
-	struct ieee80211_header_data header;
-	u32 time_stamp[2];
-	u16 beacon_interval;
-	u16 capability;
-	struct ieee80211_info_element info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_request_frame {
-	struct ieee80211_hdr_3addr header;
-	u16 capability;
-	u16 listen_interval;
-	//u8 current_ap[ETH_ALEN];
-	struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_response_frame {
-	struct ieee80211_hdr_3addr header;
-	u16 capability;
-	u16 status;
-	u16 aid;
-	struct ieee80211_info_element info_element; /* supported rates */
-} __attribute__ ((packed));
-
-struct ieee80211_txb {
-	u8 nr_frags;
-	u8 encrypted;
-	u16 reserved;
-	u16 frag_size;
-	u16 payload_size;
-	struct sk_buff *fragments[0];
-};
-
-/* SWEEP TABLE ENTRIES NUMBER */
-#define MAX_SWEEP_TAB_ENTRIES			42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET	7
-
-/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates.  Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH			((u8)12)
-#define MAX_RATES_EX_LENGTH			((u8)16)
-
-#define MAX_NETWORK_COUNT			128
-
-#define MAX_CHANNEL_NUMBER			165
-
-#define IEEE80211_SOFTMAC_SCAN_TIME		100 /* (HZ / 2) */
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME	(HZ * 2)
-
-#define CRC_LENGTH	4U
-
-#define MAX_WPA_IE_LEN	64
-
-#define NETWORK_EMPTY_ESSID	(1 << 0)
-#define NETWORK_HAS_OFDM	(1 << 1)
-#define NETWORK_HAS_CCK		(1 << 2)
-
-struct ieee80211_wmm_ac_param {
-	u8 ac_aci_acm_aifsn;
-	u8 ac_ecwmin_ecwmax;
-	u16 ac_txop_limit;
-};
-
-struct ieee80211_wmm_ts_info {
-	u8 ac_dir_tid;
-	u8 ac_up_psb;
-	u8 reserved;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_tspec_elem {
-	struct ieee80211_wmm_ts_info ts_info;
-	u16 norm_msdu_size;
-	u16 max_msdu_size;
-	u32 min_serv_inter;
-	u32 max_serv_inter;
-	u32 inact_inter;
-	u32 suspen_inter;
-	u32 serv_start_time;
-	u32 min_data_rate;
-	u32 mean_data_rate;
-	u32 peak_data_rate;
-	u32 max_burst_size;
-	u32 delay_bound;
-	u32 min_phy_rate;
-	u16 surp_band_allow;
-	u16 medium_time;
-}__attribute__((packed));
-
-enum eap_type {
-	EAP_PACKET = 0,
-	EAPOL_START,
-	EAPOL_LOGOFF,
-	EAPOL_KEY,
-	EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
-	[EAP_PACKET]		= "EAP-Packet",
-	[EAPOL_START]		= "EAPOL-Start",
-	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
-	[EAPOL_KEY]		= "EAPOL-Key",
-	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
-	return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-
-struct eapol {
-	u8 snap[6];
-	u16 ethertype;
-	u8 version;
-	u8 type;
-	u16 length;
-} __attribute__ ((packed));
-
-struct ieee80211_softmac_stats {
-	unsigned int rx_ass_ok;
-	unsigned int rx_ass_err;
-	unsigned int rx_probe_rq;
-	unsigned int tx_probe_rs;
-	unsigned int tx_beacons;
-	unsigned int rx_auth_rq;
-	unsigned int rx_auth_rs_ok;
-	unsigned int rx_auth_rs_err;
-	unsigned int tx_auth_rq;
-	unsigned int no_auth_rs;
-	unsigned int no_ass_rs;
-	unsigned int tx_ass_rq;
-	unsigned int rx_ass_rq;
-	unsigned int tx_probe_rq;
-	unsigned int reassoc;
-	unsigned int swtxstop;
-	unsigned int swtxawake;
-};
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-/*
- * These are the data types that can make up management packets
- *
-	u16 auth_algorithm;
-	u16 auth_sequence;
-	u16 beacon_interval;
-	u16 capability;
-	u8 current_ap[ETH_ALEN];
-	u16 listen_interval;
-	struct {
-		u16 association_id:14, reserved:2;
-	} __attribute__ ((packed));
-	u32 time_stamp[2];
-	u16 reason;
-	u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 10
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len  (WMM_all_frame << 4)
-#define IEEE80211_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-#define MAX_IE_LEN						0xFF //+YJ,080625
-
-struct rtl8187se_channel_list {
-	u8	channel[MAX_CHANNEL_NUMBER + 1];
-	u8	len;
-};
-
-//by amy for ps
-#define IEEE80211_WATCH_DOG_TIME    2000
-//by amy for ps
-//by amy for antenna
-#define ANTENNA_DIVERSITY_TIMER_PERIOD		1000 // 1000 m
-//by amy for antenna
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-#define IEEE80211_PS_ENABLE   IEEE80211_DTIM_VALID
-//added by David for QoS 2006/6/30
-//#define WMM_Hang_8187
-#ifdef WMM_Hang_8187
-#undef WMM_Hang_8187
-#endif
-
-#define WME_AC_BE   0x00
-#define WME_AC_BK   0x01
-#define WME_AC_VI   0x02
-#define WME_AC_VO   0x03
-#define WME_ACI_MASK 0x03
-#define WME_AIFSN_MASK 0x03
-#define WME_AC_PRAM_LEN 16
-
-//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
-//#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1))
-#define UP2AC(up) (		   \
-	((up) < 1) ? WME_AC_BE : \
-	((up) < 3) ? WME_AC_BK : \
-	((up) < 4) ? WME_AC_BE : \
-	((up) < 6) ? WME_AC_VI : \
-	WME_AC_VO)
-//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
-#define AC2UP(_ac)	(       \
-	((_ac) == WME_AC_VO) ? 6 : \
-	((_ac) == WME_AC_VI) ? 5 : \
-	((_ac) == WME_AC_BK) ? 1 : \
-	0)
-
-#define	ETHER_ADDR_LEN		6	/* length of an Ethernet address */
-struct	ether_header {
-	u8 ether_dhost[ETHER_ADDR_LEN];
-	u8 ether_shost[ETHER_ADDR_LEN];
-	u16 ether_type;
-} __attribute__((packed));
-
-#ifndef ETHERTYPE_PAE
-#define	ETHERTYPE_PAE	0x888e		/* EAPOL PAE/802.1x */
-#endif
-#ifndef ETHERTYPE_IP
-#define	ETHERTYPE_IP	0x0800		/* IP protocol */
-#endif
-
-struct ieee80211_network {
-	/* These entries are used to identify a unique network */
-	u8 bssid[ETH_ALEN];
-	u8 channel;
-	/* Ensure null-terminated for any debug msgs */
-	u8 ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 ssid_len;
-
-	/* These are network statistics */
-	struct ieee80211_rx_stats stats;
-	u16 capability;
-	u8 rates[MAX_RATES_LENGTH];
-	u8 rates_len;
-	u8 rates_ex[MAX_RATES_EX_LENGTH];
-	u8 rates_ex_len;
-	unsigned long last_scanned;
-	u8 mode;
-	u8 flags;
-	u32 last_associate;
-	u32 time_stamp[2];
-	u16 beacon_interval;
-	u16 listen_interval;
-	u16 atim_window;
-	u8 wpa_ie[MAX_WPA_IE_LEN];
-	size_t wpa_ie_len;
-	u8 rsn_ie[MAX_WPA_IE_LEN];
-	size_t rsn_ie_len;
-	u8 dtim_period;
-	u8 dtim_data;
-	u32 last_dtim_sta_time[2];
-	struct list_head list;
-	//appeded for QoS
-	u8 wmm_info;
-	struct ieee80211_wmm_ac_param wmm_param[4];
-	u8 QoS_Enable;
-	u8 SignalStrength;
-//by amy 080312
-	u8 HighestOperaRate;
-//by amy 080312
-	u8 Turbo_Enable;//enable turbo mode, added by thomas
-	u16 CountryIeLen;
-	u8 CountryIeBuf[MAX_IE_LEN];
-};
-
-enum ieee80211_state {
-
-	/* the card is not linked at all */
-	IEEE80211_NOLINK = 0,
-
-	/* IEEE80211_ASSOCIATING* are for BSS client mode
-	 * the driver shall not perform RX filtering unless
-	 * the state is LINKED.
-	 * The driver shall just check for the state LINKED and
-	 * defaults to NOLINK for ALL the other states (including
-	 * LINKED_SCANNING)
-	 */
-
-	/* the association procedure will start (wq scheduling)*/
-	IEEE80211_ASSOCIATING,
-	IEEE80211_ASSOCIATING_RETRY,
-
-	/* the association procedure is sending AUTH request*/
-	IEEE80211_ASSOCIATING_AUTHENTICATING,
-
-	/* the association procedure has successfully authenticated
-	 * and is sending association request
-	 */
-	IEEE80211_ASSOCIATING_AUTHENTICATED,
-
-	/* the link is ok. the card associated to a BSS or linked
-	 * to a ibss cell or acting as an AP and creating the bss
-	 */
-	IEEE80211_LINKED,
-
-	/* same as LINKED, but the driver shall apply RX filter
-	 * rules as we are in NO_LINK mode. As the card is still
-	 * logically linked, but it is doing a syncro site survey
-	 * then it will be back to LINKED state.
-	 */
-	IEEE80211_LINKED_SCANNING,
-
-};
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-
-typedef struct tx_pending_t{
-	int frag;
-	struct ieee80211_txb *txb;
-}tx_pending_t;
-
-enum {
-	COUNTRY_CODE_FCC = 0,
-	COUNTRY_CODE_IC = 1,
-	COUNTRY_CODE_ETSI = 2,
-	COUNTRY_CODE_SPAIN = 3,
-	COUNTRY_CODE_FRANCE = 4,
-	COUNTRY_CODE_MKK = 5,
-	COUNTRY_CODE_MKK1 = 6,
-	COUNTRY_CODE_ISRAEL = 7,
-	COUNTRY_CODE_TELEC = 8,
-	COUNTRY_CODE_GLOBAL_DOMAIN = 9,
-	COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
-};
-
-struct ieee80211_device {
-	struct net_device *dev;
-
-	/* Bookkeeping structures */
-	struct net_device_stats stats;
-	struct ieee80211_stats ieee_stats;
-	struct ieee80211_softmac_stats softmac_stats;
-
-	/* Probe / Beacon management */
-	struct list_head network_free_list;
-	struct list_head network_list;
-	struct ieee80211_network *networks;
-	int scans;
-	int scan_age;
-
-	int iw_mode; /* operating mode (IW_MODE_*) */
-
-	spinlock_t lock;
-	spinlock_t wpax_suitlist_lock;
-
-	int tx_headroom; /* Set to size of any additional room needed at front
-			  * of allocated Tx SKBs */
-	u32 config;
-
-	/* WEP and other encryption related settings at the device level */
-	int open_wep; /* Set to 1 to allow unencrypted frames */
-
-	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
-				 * WEP key changes */
-
-	/* If the host performs {en,de}cryption, then set to 1 */
-	int host_encrypt;
-	int host_decrypt;
-	int ieee802_1x; /* is IEEE 802.1X used */
-
-	/* WPA data */
-	int wpa_enabled;
-	int drop_unencrypted;
-	int tkip_countermeasures;
-	int privacy_invoked;
-	size_t wpa_ie_len;
-	u8 *wpa_ie;
-
-	u8 ap_mac_addr[6];
-	u16 pairwise_key_type;
-	u16 broadcast_key_type;
-
-	struct list_head crypt_deinit_list;
-	struct ieee80211_crypt_data *crypt[WEP_KEYS];
-	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
-	struct timer_list crypt_deinit_timer;
-
-	int bcrx_sta_key; /* use individual keys to override default keys even
-			   * with RX of broad/multicast frames */
-
-	/* Fragmentation structures */
-	/* each stream contains an entry */
-	struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
-	unsigned int frag_next_idx[17];
-	u16 fts; /* Fragmentation Threshold */
-
-	/* This stores infos for the current network.
-	 * Either the network we are associated in INFRASTRUCTURE
-	 * or the network that we are creating in MASTER mode.
-	 * ad-hoc is a mixture ;-).
-	 * Note that in infrastructure mode, even when not associated,
-	 * fields bssid and essid may be valid (if wpa_set and essid_set
-	 * are true) as thy carry the value set by the user via iwconfig
-	 */
-	struct ieee80211_network current_network;
-
-
-	enum ieee80211_state state;
-
-	int short_slot;
-	int mode;       /* A, B, G */
-	int modulation; /* CCK, OFDM */
-	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
-	int abg_true;   /* ABG flag              */
-
-	/* used for forcing the ibss workqueue to terminate
-	 * without wait for the syncro scan to terminate
-	 */
-	short sync_scan_hurryup;
-
-	void * pDot11dInfo;
-	bool bGlobalDomain;
-
-	// For Liteon Ch12~13 passive scan
-	u8	MinPassiveChnlNum;
-	u8	IbssStartChnl;
-
-	int rate;       /* current rate */
-	int basic_rate;
-	//FIXME: please callback, see if redundant with softmac_features
-	short active_scan;
-
-	/* this contains flags for selectively enable softmac support */
-	u16 softmac_features;
-
-	/* if the sequence control field is not filled by HW */
-	u16 seq_ctrl[5];
-
-	/* association procedure transaction sequence number */
-	u16 associate_seq;
-
-	/* AID for RTXed association responses */
-	u16 assoc_id;
-
-	/* power save mode related*/
-	short ps;
-	short sta_sleep;
-	int ps_timeout;
-	struct tasklet_struct ps_task;
-	u32 ps_th;
-	u32 ps_tl;
-
-	short raw_tx;
-	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
-	short queue_stop;
-	short scanning;
-	short proto_started;
-
-	struct semaphore wx_sem;
-	struct semaphore scan_sem;
-
-	spinlock_t mgmt_tx_lock;
-	spinlock_t beacon_lock;
-
-	short beacon_txing;
-
-	short wap_set;
-	short ssid_set;
-
-	u8  wpax_type_set;    //{added by David, 2006.9.28}
-	u32 wpax_type_notify; //{added by David, 2006.9.26}
-
-	/* QoS related flag */
-	char init_wmmparam_flag;
-
-	/* for discarding duplicated packets in IBSS */
-	struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
-	/* for discarding duplicated packets in BSS */
-	u16 last_rxseq_num[17]; /* rx seq previous per-tid */
-	u16 last_rxfrag_num[17];/* tx frag previous per-tid */
-	unsigned long last_packet_time[17];
-
-	/* for PS mode */
-	unsigned long last_rx_ps_time;
-
-	/* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
-	struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
-	int mgmt_queue_head;
-	int mgmt_queue_tail;
-
-
-	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
-	struct  tx_pending_t tx_pending;
-
-	/* used if IEEE_SOFTMAC_ASSOCIATE is set */
-	struct timer_list associate_timer;
-
-	/* used if IEEE_SOFTMAC_BEACONS is set */
-	struct timer_list beacon_timer;
-
-	struct work_struct associate_complete_wq;
-//	struct work_struct associate_retry_wq;
-	struct work_struct associate_procedure_wq;
-//	struct work_struct softmac_scan_wq;
-	struct work_struct wx_sync_scan_wq;
-	struct work_struct wmm_param_update_wq;
-	struct work_struct ps_request_tx_ack_wq;//for ps
-//	struct work_struct hw_wakeup_wq;
-//	struct work_struct hw_sleep_wq;
-//	struct work_struct watch_dog_wq;
-	bool bInactivePs;
-	bool actscanning;
-	bool beinretry;
-	u16 ListenInterval;
-	unsigned long NumRxDataInPeriod; //YJ,add,080828
-	unsigned long NumRxBcnInPeriod;  //YJ,add,080828
-	unsigned long NumRxOkTotal;
-	unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
-	bool bHwRadioOff;
-        struct delayed_work softmac_scan_wq;
-        struct delayed_work associate_retry_wq;
-	struct delayed_work hw_wakeup_wq;
-	struct delayed_work hw_sleep_wq;//+by amy 080324
-	struct delayed_work watch_dog_wq;
-	struct delayed_work sw_antenna_wq;
-	struct delayed_work  start_ibss_wq;
-//by amy for rate adaptive 080312
-    struct delayed_work rate_adapter_wq;
-//by amy for rate adaptive
-	struct delayed_work hw_dig_wq;
-	struct delayed_work tx_pw_wq;
-
-//Added for RF power on power off by lizhaoming 080512
-	struct delayed_work GPIOChangeRFWorkItem;
-
-	struct workqueue_struct *wq;
-
-	/* Callback functions */
-	void (*set_security)(struct net_device *dev,
-			     struct ieee80211_security *sec);
-
-	/* Used to TX data frame by using txb structs.
-	 * this is not used if in the softmac_features
-	 * is set the flag IEEE_SOFTMAC_TX_QUEUE
-	 */
-	int (*hard_start_xmit)(struct ieee80211_txb *txb,
-			       struct net_device *dev);
-
-	int (*reset_port)(struct net_device *dev);
-
-	/* Softmac-generated frames (management) are TXed via this
-	 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
-	 * not set. As some cards may have different HW queues that
-	 * one might want to use for data and management frames
-	 * the option to have two callbacks might be useful.
-	 * This function can't sleep.
-	 */
-	int (*softmac_hard_start_xmit)(struct sk_buff *skb,
-			       struct net_device *dev);
-
-	/* used instead of hard_start_xmit (not softmac_hard_start_xmit)
-	 * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
-	 * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
-	 * then also management frames are sent via this callback.
-	 * This function can't sleep.
-	 */
-	void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
-			       struct net_device *dev,int rate);
-
-	/* stops the HW queue for DATA frames. Useful to avoid
-	 * waste time to TX data frame when we are reassociating
-	 * This function can sleep.
-	 */
-	void (*data_hard_stop)(struct net_device *dev);
-
-	/* OK this is complementar to data_poll_hard_stop */
-	void (*data_hard_resume)(struct net_device *dev);
-
-	/* ask to the driver to retune the radio .
-	 * This function can sleep. the driver should ensure
-	 * the radio has been switched before return.
-	 */
-	void (*set_chan)(struct net_device *dev,short ch);
-
-	/* These are not used if the ieee stack takes care of
-	 * scanning (IEEE_SOFTMAC_SCAN feature set).
-	 * In this case only the set_chan is used.
-	 *
-	 * The syncro version is similar to the start_scan but
-	 * does not return until all channels has been scanned.
-	 * this is called in user context and should sleep,
-	 * it is called in a work_queue when switching to ad-hoc mode
-	 * or in behalf of iwlist scan when the card is associated
-	 * and root user ask for a scan.
-	 * the function stop_scan should stop both the syncro and
-	 * background scanning and can sleep.
-	 * The function start_scan should initiate the background
-	 * scanning and can't sleep.
-	 */
-	void (*scan_syncro)(struct net_device *dev);
-	void (*start_scan)(struct net_device *dev);
-	void (*stop_scan)(struct net_device *dev);
-
-	/* indicate the driver that the link state is changed
-	 * for example it may indicate the card is associated now.
-	 * Driver might be interested in this to apply RX filter
-	 * rules or simply light the LINK led
-	 */
-	void (*link_change)(struct net_device *dev);
-
-	/* these two function indicates to the HW when to start
-	 * and stop to send beacons. This is used when the
-	 * IEEE_SOFTMAC_BEACONS is not set. For now the
-	 * stop_send_bacons is NOT guaranteed to be called only
-	 * after start_send_beacons.
-	 */
-	void (*start_send_beacons) (struct net_device *dev);
-	void (*stop_send_beacons) (struct net_device *dev);
-
-	/* power save mode related */
-	void (*sta_wake_up) (struct net_device *dev);
-	void (*ps_request_tx_ack) (struct net_device *dev);
-	void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
-	short (*ps_is_queue_empty) (struct net_device *dev);
-
-	/* QoS related */
-	//void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
-	//void (*wmm_param_update) (struct ieee80211_device *ieee);
-
-	/* This must be the last item so that it points to the data
-	 * allocated beyond this structure by alloc_ieee80211 */
-	u8 priv[0];
-};
-
-#define IEEE_A            (1<<0)
-#define IEEE_B            (1<<1)
-#define IEEE_G            (1<<2)
-#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1<<2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1<<4)
-
-/* Generate response to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1<<5)
-
-/* The ieee802.11 stack will manages the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details. */
-#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
-
-/* Generate beacons.  The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1<<6)
-
-
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
-	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-}
-
-static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
-{
-	/* Single white space is for Linksys APs */
-	if (essid_len == 1 && essid[0] == ' ')
-		return 1;
-
-	/* Otherwise, if the entire essid is 0, we assume it is hidden */
-	while (essid_len) {
-		essid_len--;
-		if (essid[essid_len] != '\0')
-			return 0;
-	}
-
-	return 1;
-}
-
-static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
-					  int mode)
-{
-	/*
-	 * It is possible for both access points and our device to support
-	 * combinations of modes, so as long as there is one valid combination
-	 * of ap/device supported modes, then return success
-	 *
-	 */
-	if ((mode & IEEE_A) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_G) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_B) &&
-	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	return 0;
-}
-
-static inline int ieee80211_get_hdrlen(u16 fc)
-{
-	int hdrlen = 24;
-
-	switch (WLAN_FC_GET_TYPE(fc)) {
-	case IEEE80211_FTYPE_DATA:
-		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-			hdrlen = 30; /* Addr4 */
-		if(IEEE80211_QOS_HAS_SEQ(fc))
-			hdrlen += 2; /* QOS ctrl*/
-		break;
-	case IEEE80211_FTYPE_CTL:
-		switch (WLAN_FC_GET_STYPE(fc)) {
-		case IEEE80211_STYPE_CTS:
-		case IEEE80211_STYPE_ACK:
-			hdrlen = 10;
-			break;
-		default:
-			hdrlen = 16;
-			break;
-		}
-		break;
-	}
-
-	return hdrlen;
-}
-
-
-
-/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
-
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-
-extern int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
-				      struct sk_buff *frag, int hdr_len);
-
-extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-
-/* ieee80211_rx.c */
-extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-			    struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-			     struct ieee80211_hdr_4addr *header,
-			     struct ieee80211_rx_stats *stats);
-
-/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
-				       struct iw_request_info *info,
-				       union iwreq_data *wrqu, char *extra);
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
-			  struct iw_request_info *info,
-			  struct iw_param *data, char *extra);
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra);
-
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
-/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(const struct ieee80211_network *net);
-extern short ieee80211_is_shortslot(const struct ieee80211_network *net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
-				      struct sk_buff *skb,
-				      struct ieee80211_rx_stats *rx_stats,
-				      u16 type, u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
-				      struct ieee80211_network *net);
-
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
-				   struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
-					  struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
-			       u8 asRsn);
-extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee);
-
-//Add for RF power on power off by lizhaoming 080512
-extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
-			       u8 asRsn);
-
-/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
-/* ieee80211_softmac_wx.c */
-
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *ext);
-
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
-				struct iw_request_info *info,
-				union iwreq_data *awrq,
-				char *extra);
-
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
-				  struct iw_request_info *a,
-				  union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
-				 struct iw_request_info *a,
-				 union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
-				 struct iw_request_info *a,
-				 union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
-				  struct iw_request_info *a,
-				  union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
-				 struct iw_request_info *a,
-				 union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
-				 struct iw_request_info *a,
-				 union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
-				 struct iw_request_info *a,
-				 union iwreq_data *wrqu, char *b);
-
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra);
-
-extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
-
-extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
-					     short pwr);
-
-extern const long ieee80211_wlan_frequencies[];
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
-	ieee->scans++;
-}
-
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
-	return ieee->scans;
-}
-
-static inline const char *escape_essid(const char *essid, u8 essid_len) {
-	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-	const char *s = essid;
-	char *d = escaped;
-
-	if (ieee80211_is_empty_essid(essid, essid_len)) {
-		memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-		return escaped;
-	}
-
-	essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
-	while (essid_len--) {
-		if (*s == '\0') {
-			*d++ = '\\';
-			*d++ = '0';
-			s++;
-		} else {
-			*d++ = *s++;
-		}
-	}
-	*d = '\0';
-	return escaped;
-}
-#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
deleted file mode 100644
index 101f0c0..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Host AP crypto routines
- *
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-//#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include "ieee80211.h"
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("HostAP crypto");
-MODULE_LICENSE("GPL");
-
-struct ieee80211_crypto_alg {
-	struct list_head list;
-	struct ieee80211_crypto_ops *ops;
-};
-
-
-struct ieee80211_crypto {
-	struct list_head algs;
-	spinlock_t lock;
-};
-
-static struct ieee80211_crypto *hcrypt;
-
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
-{
-	struct list_head *ptr, *n;
-	struct ieee80211_crypt_data *entry;
-
-	for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
-	     ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
-		entry = list_entry(ptr, struct ieee80211_crypt_data, list);
-
-		if (atomic_read(&entry->refcnt) != 0 && !force)
-			continue;
-
-		list_del(ptr);
-
-		if (entry->ops)
-			entry->ops->deinit(entry->priv);
-		kfree(entry);
-	}
-}
-
-void ieee80211_crypt_deinit_handler(unsigned long data)
-{
-	struct ieee80211_device *ieee = (struct ieee80211_device *)data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	ieee80211_crypt_deinit_entries(ieee, 0);
-	if (!list_empty(&ieee->crypt_deinit_list)) {
-		pr_debug("entries remaining in delayed crypt deletion list\n");
-		ieee->crypt_deinit_timer.expires = jiffies + HZ;
-		add_timer(&ieee->crypt_deinit_timer);
-	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
-
-}
-
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
-				    struct ieee80211_crypt_data **crypt)
-{
-	struct ieee80211_crypt_data *tmp;
-	unsigned long flags;
-
-	if (*crypt == NULL)
-		return;
-
-	tmp = *crypt;
-	*crypt = NULL;
-
-	/* must not run ops->deinit() while there may be pending encrypt or
-	 * decrypt operations. Use a list of delayed deinits to avoid needing
-	 * locking. */
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	list_add(&tmp->list, &ieee->crypt_deinit_list);
-	if (!timer_pending(&ieee->crypt_deinit_timer)) {
-		ieee->crypt_deinit_timer.expires = jiffies + HZ;
-		add_timer(&ieee->crypt_deinit_timer);
-	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
-	unsigned long flags;
-	struct ieee80211_crypto_alg *alg;
-
-	if (hcrypt == NULL)
-		return -1;
-
-	alg = kzalloc(sizeof(*alg), GFP_KERNEL);
-	if (alg == NULL)
-		return -ENOMEM;
-
-	alg->ops = ops;
-
-	spin_lock_irqsave(&hcrypt->lock, flags);
-	list_add(&alg->list, &hcrypt->algs);
-	spin_unlock_irqrestore(&hcrypt->lock, flags);
-
-	pr_debug("registered algorithm '%s'\n", ops->name);
-
-	return 0;
-}
-
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
-	unsigned long flags;
-	struct list_head *ptr;
-	struct ieee80211_crypto_alg *del_alg = NULL;
-
-	if (hcrypt == NULL)
-		return -1;
-
-	spin_lock_irqsave(&hcrypt->lock, flags);
-	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
-		struct ieee80211_crypto_alg *alg =
-			(struct ieee80211_crypto_alg *) ptr;
-		if (alg->ops == ops) {
-			list_del(&alg->list);
-			del_alg = alg;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&hcrypt->lock, flags);
-
-	if (del_alg) {
-		pr_debug("unregistered algorithm '%s'\n", ops->name);
-		kfree(del_alg);
-	}
-
-	return del_alg ? 0 : -1;
-}
-
-
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
-{
-	unsigned long flags;
-	struct list_head *ptr;
-	struct ieee80211_crypto_alg *found_alg = NULL;
-
-	if (hcrypt == NULL)
-		return NULL;
-
-	spin_lock_irqsave(&hcrypt->lock, flags);
-	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
-		struct ieee80211_crypto_alg *alg =
-			(struct ieee80211_crypto_alg *) ptr;
-		if (strcmp(alg->ops->name, name) == 0) {
-			found_alg = alg;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&hcrypt->lock, flags);
-
-	if (found_alg)
-		return found_alg->ops;
-	else
-		return NULL;
-}
-
-
-static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
-static void ieee80211_crypt_null_deinit(void *priv) {}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_null = {
-	.name			= "NULL",
-	.init			= ieee80211_crypt_null_init,
-	.deinit			= ieee80211_crypt_null_deinit,
-	.encrypt_mpdu		= NULL,
-	.decrypt_mpdu		= NULL,
-	.encrypt_msdu		= NULL,
-	.decrypt_msdu		= NULL,
-	.set_key		= NULL,
-	.get_key		= NULL,
-	.extra_prefix_len	= 0,
-	.extra_postfix_len	= 0,
-	.owner			= THIS_MODULE,
-};
-
-
-int ieee80211_crypto_init(void)
-{
-	int ret = -ENOMEM;
-
-	hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
-	if (!hcrypt)
-		goto out;
-
-	INIT_LIST_HEAD(&hcrypt->algs);
-	spin_lock_init(&hcrypt->lock);
-
-	ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
-	if (ret < 0) {
-		kfree(hcrypt);
-		hcrypt = NULL;
-	}
-out:
-	return ret;
-}
-
-
-void ieee80211_crypto_deinit(void)
-{
-	struct list_head *ptr, *n;
-	struct ieee80211_crypto_alg *alg = NULL;
-
-	if (hcrypt == NULL)
-		return;
-
-	list_for_each_safe(ptr, n, &hcrypt->algs) {
-		alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
-		if (alg) {
-			list_del(ptr);
-			pr_debug("unregistered algorithm '%s' (deinit)\n",
-				 alg->ops->name);
-			kfree(alg);
-		}
-	}
-	kfree(hcrypt);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
deleted file mode 100644
index 0b4ea43..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
-	const char *name;
-
-	/* init new crypto context (e.g., allocate private data space,
-	 * select IV, etc.); returns NULL on failure or pointer to allocated
-	 * private data on success */
-	void * (*init)(int keyidx);
-
-	/* deinitialize crypto context and free allocated private data */
-	void (*deinit)(void *priv);
-
-	/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
-	 * value from decrypt_mpdu is passed as the keyidx value for
-	 * decrypt_msdu. skb must have enough head and tail room for the
-	 * encryption; if not, error will be returned; these functions are
-	 * called for all MPDUs (i.e., fragments).
-	 */
-	int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
-	/* These functions are called for full MSDUs, i.e. full frames.
-	 * These can be NULL if full MSDU operations are not needed. */
-	int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-			    void *priv);
-
-	int (*set_key)(void *key, int len, u8 *seq, void *priv);
-	int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
-	/* procfs handler for printing out key information and possible
-	 * statistics */
-	char * (*print_stats)(char *p, void *priv);
-
-	/* maximum number of bytes added by encryption; encrypt buf is
-	 * allocated with extra_prefix_len bytes, copy of in_buf, and
-	 * extra_postfix_len; encrypt need not use all this space, but
-	 * the result must start at the beginning of the buffer and correct
-	 * length must be returned */
-	int extra_prefix_len, extra_postfix_len;
-
-	struct module *owner;
-};
-
-struct ieee80211_crypt_data {
-	struct list_head list; /* delayed deletion list */
-	struct ieee80211_crypto_ops *ops;
-	void *priv;
-	atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
-				    struct ieee80211_crypt_data **crypt);
-
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
deleted file mode 100644
index 4fe2538..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/string.h>
-#include <linux/wireless.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: CCMP");
-MODULE_LICENSE("GPL");
-
-
-#define AES_BLOCK_LEN 16
-#define CCMP_HDR_LEN 8
-#define CCMP_MIC_LEN 8
-#define CCMP_TK_LEN 16
-#define CCMP_PN_LEN 6
-
-struct ieee80211_ccmp_data {
-	u8 key[CCMP_TK_LEN];
-	int key_set;
-
-	u8 tx_pn[CCMP_PN_LEN];
-	u8 rx_pn[CCMP_PN_LEN];
-
-	u32 dot11RSNAStatsCCMPFormatErrors;
-	u32 dot11RSNAStatsCCMPReplays;
-	u32 dot11RSNAStatsCCMPDecryptErrors;
-
-	int key_idx;
-
-	struct crypto_tfm *tfm;
-
-	/* scratch buffers for virt_to_page() (crypto API) */
-	u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
-		tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
-	u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
-};
-
-static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
-				const u8 pt[16], u8 ct[16])
-{
-	crypto_cipher_encrypt_one((void *)tfm, ct, pt);
-}
-
-static void *ieee80211_ccmp_init(int key_idx)
-{
-	struct ieee80211_ccmp_data *priv;
-
-	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
-	if (priv == NULL)
-		goto fail;
-	priv->key_idx = key_idx;
-
-	priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(priv->tfm)) {
-		pr_debug("could not allocate crypto API aes\n");
-		priv->tfm = NULL;
-		goto fail;
-	}
-
-	return priv;
-
-fail:
-	if (priv) {
-		if (priv->tfm)
-			crypto_free_cipher((void *)priv->tfm);
-		kfree(priv);
-	}
-
-	return NULL;
-}
-
-
-static void ieee80211_ccmp_deinit(void *priv)
-{
-	struct ieee80211_ccmp_data *_priv = priv;
-
-	if (_priv && _priv->tfm)
-		crypto_free_cipher((void *)_priv->tfm);
-	kfree(priv);
-}
-
-
-static inline void xor_block(u8 *b, u8 *a, size_t len)
-{
-	int i;
-	for (i = 0; i < len; i++)
-		b[i] ^= a[i];
-}
-
-static void ccmp_init_blocks(struct crypto_tfm *tfm,
-			     struct ieee80211_hdr_4addr *hdr,
-			     u8 *pn, size_t dlen, u8 *b0, u8 *auth,
-			     u8 *s0)
-{
-	u8 *pos, qc = 0;
-	size_t aad_len;
-	u16 fc;
-	int a4_included, qc_included;
-	u8 aad[2 * AES_BLOCK_LEN];
-
-	fc = le16_to_cpu(hdr->frame_ctl);
-	a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
-		       (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
-	/*
-	qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
-		       (WLAN_FC_GET_STYPE(fc) & 0x08));
-	*/
-	qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
-		       (WLAN_FC_GET_STYPE(fc) & 0x80));
-	aad_len = 22;
-	if (a4_included)
-		aad_len += 6;
-	if (qc_included) {
-		pos = (u8 *) &hdr->addr4;
-		if (a4_included)
-			pos += 6;
-		qc = *pos & 0x0f;
-		aad_len += 2;
-	}
-	/* CCM Initial Block:
-	 * Flag (Include authentication header, M=3 (8-octet MIC),
-	 *       L=1 (2-octet Dlen))
-	 * Nonce: 0x00 | A2 | PN
-	 * Dlen */
-	b0[0] = 0x59;
-	b0[1] = qc;
-	memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
-	memcpy(b0 + 8, pn, CCMP_PN_LEN);
-	b0[14] = (dlen >> 8) & 0xff;
-	b0[15] = dlen & 0xff;
-
-	/* AAD:
-	 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
-	 * A1 | A2 | A3
-	 * SC with bits 4..15 (seq#) masked to zero
-	 * A4 (if present)
-	 * QC (if present)
-	 */
-	pos = (u8 *) hdr;
-	aad[0] = 0; /* aad_len >> 8 */
-	aad[1] = aad_len & 0xff;
-	aad[2] = pos[0] & 0x8f;
-	aad[3] = pos[1] & 0xc7;
-	memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
-	pos = (u8 *) &hdr->seq_ctl;
-	aad[22] = pos[0] & 0x0f;
-	aad[23] = 0; /* all bits masked */
-	memset(aad + 24, 0, 8);
-	if (a4_included)
-		memcpy(aad + 24, hdr->addr4, ETH_ALEN);
-	if (qc_included) {
-		aad[a4_included ? 30 : 24] = qc;
-		/* rest of QC masked */
-	}
-
-	/* Start with the first block and AAD */
-	ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
-	xor_block(auth, aad, AES_BLOCK_LEN);
-	ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
-	xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
-	ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
-	b0[0] &= 0x07;
-	b0[14] = b0[15] = 0;
-	ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
-}
-
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
-	struct ieee80211_ccmp_data *key = priv;
-	int data_len, i;
-	u8 *pos;
-	struct ieee80211_hdr_4addr *hdr;
-	int blocks, last, len;
-	u8 *mic;
-	u8 *b0 = key->tx_b0;
-	u8 *b = key->tx_b;
-	u8 *e = key->tx_e;
-	u8 *s0 = key->tx_s0;
-
-	if (skb_headroom(skb) < CCMP_HDR_LEN ||
-	    skb_tailroom(skb) < CCMP_MIC_LEN ||
-	    skb->len < hdr_len)
-		return -1;
-
-	data_len = skb->len - hdr_len;
-	pos = skb_push(skb, CCMP_HDR_LEN);
-	memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
-	pos += hdr_len;
-
-	i = CCMP_PN_LEN - 1;
-	while (i >= 0) {
-		key->tx_pn[i]++;
-		if (key->tx_pn[i] != 0)
-			break;
-		i--;
-	}
-
-	*pos++ = key->tx_pn[5];
-	*pos++ = key->tx_pn[4];
-	*pos++ = 0;
-	*pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
-	*pos++ = key->tx_pn[3];
-	*pos++ = key->tx_pn[2];
-	*pos++ = key->tx_pn[1];
-	*pos++ = key->tx_pn[0];
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	mic = skb_put(skb, CCMP_MIC_LEN);
-
-	ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
-
-	blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
-	last = data_len % AES_BLOCK_LEN;
-
-	for (i = 1; i <= blocks; i++) {
-		len = (i == blocks && last) ? last : AES_BLOCK_LEN;
-		/* Authentication */
-		xor_block(b, pos, len);
-		ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
-		/* Encryption, with counter */
-		b0[14] = (i >> 8) & 0xff;
-		b0[15] = i & 0xff;
-		ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
-		xor_block(pos, e, len);
-		pos += len;
-	}
-
-	for (i = 0; i < CCMP_MIC_LEN; i++)
-		mic[i] = b[i] ^ s0[i];
-
-	return 0;
-}
-
-
-static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
-	struct ieee80211_ccmp_data *key = priv;
-	u8 keyidx, *pos;
-	struct ieee80211_hdr_4addr *hdr;
-	u8 pn[6];
-	size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
-	u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
-	u8 *b0 = key->rx_b0;
-	u8 *b = key->rx_b;
-	u8 *a = key->rx_a;
-	int i, blocks, last, len;
-
-	if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
-		key->dot11RSNAStatsCCMPFormatErrors++;
-		return -1;
-	}
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	pos = skb->data + hdr_len;
-	keyidx = pos[3];
-	if (!(keyidx & (1 << 5))) {
-		if (net_ratelimit()) {
-			pr_debug("received packet without ExtIV flag from %pM\n",
-				 hdr->addr2);
-		}
-		key->dot11RSNAStatsCCMPFormatErrors++;
-		return -2;
-	}
-	keyidx >>= 6;
-	if (key->key_idx != keyidx) {
-		pr_debug("RX tkey->key_idx=%d frame keyidx=%d priv=%p\n",
-			 key->key_idx, keyidx, priv);
-		return -6;
-	}
-	if (!key->key_set) {
-		if (net_ratelimit()) {
-			pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n",
-				 hdr->addr2, keyidx);
-		}
-		return -3;
-	}
-
-	pn[0] = pos[7];
-	pn[1] = pos[6];
-	pn[2] = pos[5];
-	pn[3] = pos[4];
-	pn[4] = pos[1];
-	pn[5] = pos[0];
-	pos += 8;
-
-	if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
-		if (net_ratelimit()) {
-			pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n",
-				 hdr->addr2, key->rx_pn, pn);
-		}
-		key->dot11RSNAStatsCCMPReplays++;
-		return -4;
-	}
-
-	ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
-	xor_block(mic, b, CCMP_MIC_LEN);
-
-	blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
-	last = data_len % AES_BLOCK_LEN;
-
-	for (i = 1; i <= blocks; i++) {
-		len = (i == blocks && last) ? last : AES_BLOCK_LEN;
-		/* Decrypt, with counter */
-		b0[14] = (i >> 8) & 0xff;
-		b0[15] = i & 0xff;
-		ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
-		xor_block(pos, b, len);
-		/* Authentication */
-		xor_block(a, pos, len);
-		ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
-		pos += len;
-	}
-
-	if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
-		if (net_ratelimit())
-			pr_debug("decrypt failed: STA=%pM\n", hdr->addr2);
-
-		key->dot11RSNAStatsCCMPDecryptErrors++;
-		return -5;
-	}
-
-	memcpy(key->rx_pn, pn, CCMP_PN_LEN);
-
-	/* Remove hdr and MIC */
-	memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
-	skb_pull(skb, CCMP_HDR_LEN);
-	skb_trim(skb, skb->len - CCMP_MIC_LEN);
-
-	return keyidx;
-}
-
-
-static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
-{
-	struct ieee80211_ccmp_data *data = priv;
-	int keyidx;
-	struct crypto_tfm *tfm = data->tfm;
-
-	keyidx = data->key_idx;
-	memset(data, 0, sizeof(*data));
-	data->key_idx = keyidx;
-	data->tfm = tfm;
-	if (len == CCMP_TK_LEN) {
-		memcpy(data->key, key, CCMP_TK_LEN);
-		data->key_set = 1;
-		if (seq) {
-			data->rx_pn[0] = seq[5];
-			data->rx_pn[1] = seq[4];
-			data->rx_pn[2] = seq[3];
-			data->rx_pn[3] = seq[2];
-			data->rx_pn[4] = seq[1];
-			data->rx_pn[5] = seq[0];
-		}
-		crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN);
-	} else if (len == 0)
-		data->key_set = 0;
-	else
-		return -1;
-
-	return 0;
-}
-
-
-static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
-{
-	struct ieee80211_ccmp_data *data = priv;
-
-	if (len < CCMP_TK_LEN)
-		return -1;
-
-	if (!data->key_set)
-		return 0;
-	memcpy(key, data->key, CCMP_TK_LEN);
-
-	if (seq) {
-		seq[0] = data->tx_pn[5];
-		seq[1] = data->tx_pn[4];
-		seq[2] = data->tx_pn[3];
-		seq[3] = data->tx_pn[2];
-		seq[4] = data->tx_pn[1];
-		seq[5] = data->tx_pn[0];
-	}
-
-	return CCMP_TK_LEN;
-}
-
-
-static char *ieee80211_ccmp_print_stats(char *p, void *priv)
-{
-	struct ieee80211_ccmp_data *ccmp = priv;
-	p += sprintf(p,
-		     "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n",
-		     ccmp->key_idx, ccmp->key_set,
-		     ccmp->tx_pn, ccmp->rx_pn,
-		     ccmp->dot11RSNAStatsCCMPFormatErrors,
-		     ccmp->dot11RSNAStatsCCMPReplays,
-		     ccmp->dot11RSNAStatsCCMPDecryptErrors);
-
-	return p;
-}
-
-void ieee80211_ccmp_null(void)
-{
-	return;
-}
-static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
-	.name			= "CCMP",
-	.init			= ieee80211_ccmp_init,
-	.deinit			= ieee80211_ccmp_deinit,
-	.encrypt_mpdu		= ieee80211_ccmp_encrypt,
-	.decrypt_mpdu		= ieee80211_ccmp_decrypt,
-	.encrypt_msdu		= NULL,
-	.decrypt_msdu		= NULL,
-	.set_key		= ieee80211_ccmp_set_key,
-	.get_key		= ieee80211_ccmp_get_key,
-	.print_stats		= ieee80211_ccmp_print_stats,
-	.extra_prefix_len	= CCMP_HDR_LEN,
-	.extra_postfix_len	= CCMP_MIC_LEN,
-	.owner			= THIS_MODULE,
-};
-
-
-int ieee80211_crypto_ccmp_init(void)
-{
-	return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
-}
-
-
-void ieee80211_crypto_ccmp_exit(void)
-{
-	ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
deleted file mode 100644
index 6c1acc5..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <asm/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: TKIP");
-MODULE_LICENSE("GPL");
-
-
-struct ieee80211_tkip_data {
-#define TKIP_KEY_LEN 32
-	u8 key[TKIP_KEY_LEN];
-	int key_set;
-
-	u32 tx_iv32;
-	u16 tx_iv16;
-	u16 tx_ttak[5];
-	int tx_phase1_done;
-
-	u32 rx_iv32;
-	u16 rx_iv16;
-	u16 rx_ttak[5];
-	int rx_phase1_done;
-	u32 rx_iv32_new;
-	u16 rx_iv16_new;
-
-	u32 dot11RSNAStatsTKIPReplays;
-	u32 dot11RSNAStatsTKIPICVErrors;
-	u32 dot11RSNAStatsTKIPLocalMICFailures;
-
-	int key_idx;
-
-	struct crypto_blkcipher *rx_tfm_arc4;
-	struct crypto_hash *rx_tfm_michael;
-	struct crypto_blkcipher *tx_tfm_arc4;
-	struct crypto_hash *tx_tfm_michael;
-	struct crypto_tfm *tfm_arc4;
-	struct crypto_tfm *tfm_michael;
-
-	/* scratch buffers for virt_to_page() (crypto API) */
-	u8 rx_hdr[16], tx_hdr[16];
-};
-
-static void *ieee80211_tkip_init(int key_idx)
-{
-	struct ieee80211_tkip_data *priv;
-
-	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
-	if (priv == NULL)
-		goto fail;
-	priv->key_idx = key_idx;
-
-	priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
-						CRYPTO_ALG_ASYNC);
-	if (IS_ERR(priv->tx_tfm_arc4)) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-		       "crypto API arc4\n");
-		priv->tx_tfm_arc4 = NULL;
-		goto fail;
-	}
-
-	priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
-						 CRYPTO_ALG_ASYNC);
-	if (IS_ERR(priv->tx_tfm_michael)) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-		       "crypto API michael_mic\n");
-		priv->tx_tfm_michael = NULL;
-		goto fail;
-	}
-
-	priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
-						CRYPTO_ALG_ASYNC);
-	if (IS_ERR(priv->rx_tfm_arc4)) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-		       "crypto API arc4\n");
-		priv->rx_tfm_arc4 = NULL;
-		goto fail;
-	}
-
-	priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
-						 CRYPTO_ALG_ASYNC);
-	if (IS_ERR(priv->rx_tfm_michael)) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-		       "crypto API michael_mic\n");
-		priv->rx_tfm_michael = NULL;
-		goto fail;
-	}
-
-	return priv;
-
-fail:
-	if (priv) {
-		if (priv->tx_tfm_michael)
-			crypto_free_hash(priv->tx_tfm_michael);
-		if (priv->tx_tfm_arc4)
-			crypto_free_blkcipher(priv->tx_tfm_arc4);
-		if (priv->rx_tfm_michael)
-			crypto_free_hash(priv->rx_tfm_michael);
-		if (priv->rx_tfm_arc4)
-			crypto_free_blkcipher(priv->rx_tfm_arc4);
-		kfree(priv);
-	}
-
-	return NULL;
-}
-
-
-static void ieee80211_tkip_deinit(void *priv)
-{
-	struct ieee80211_tkip_data *_priv = priv;
-
-	if (_priv) {
-		if (_priv->tx_tfm_michael)
-			crypto_free_hash(_priv->tx_tfm_michael);
-		if (_priv->tx_tfm_arc4)
-			crypto_free_blkcipher(_priv->tx_tfm_arc4);
-		if (_priv->rx_tfm_michael)
-			crypto_free_hash(_priv->rx_tfm_michael);
-		if (_priv->rx_tfm_arc4)
-			crypto_free_blkcipher(_priv->rx_tfm_arc4);
-	}
-	kfree(priv);
-}
-
-
-static inline u16 RotR1(u16 val)
-{
-	return (val >> 1) | (val << 15);
-}
-
-
-static inline u8 Lo8(u16 val)
-{
-	return val & 0xff;
-}
-
-
-static inline u8 Hi8(u16 val)
-{
-	return val >> 8;
-}
-
-
-static inline u16 Lo16(u32 val)
-{
-	return val & 0xffff;
-}
-
-
-static inline u16 Hi16(u32 val)
-{
-	return val >> 16;
-}
-
-
-static inline u16 Mk16(u8 hi, u8 lo)
-{
-	return lo | (((u16) hi) << 8);
-}
-
-
-static inline u16 Mk16_le(u16 *v)
-{
-	return le16_to_cpu(*v);
-}
-
-
-static const u16 Sbox[256] = {
-	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
-	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
-	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
-	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
-	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
-	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
-	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
-	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
-	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
-	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
-	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
-	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
-	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
-	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
-	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
-	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
-	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
-	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
-	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
-	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
-	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
-	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
-	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
-	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
-	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
-	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
-	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
-	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
-	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
-	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
-	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
-	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
-};
-
-
-static inline u16 _S_(u16 v)
-{
-	u16 t = Sbox[Hi8(v)];
-	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
-}
-
-#define PHASE1_LOOP_COUNT 8
-
-static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
-{
-	int i, j;
-
-	/* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
-	TTAK[0] = Lo16(IV32);
-	TTAK[1] = Hi16(IV32);
-	TTAK[2] = Mk16(TA[1], TA[0]);
-	TTAK[3] = Mk16(TA[3], TA[2]);
-	TTAK[4] = Mk16(TA[5], TA[4]);
-
-	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
-		j = 2 * (i & 1);
-		TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
-		TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
-		TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
-		TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
-		TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
-	}
-}
-
-
-static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
-			       u16 IV16)
-{
-	/* Make temporary area overlap WEP seed so that the final copy can be
-	 * avoided on little endian hosts. */
-	u16 *PPK = (u16 *) &WEPSeed[4];
-
-	/* Step 1 - make copy of TTAK and bring in TSC */
-	PPK[0] = TTAK[0];
-	PPK[1] = TTAK[1];
-	PPK[2] = TTAK[2];
-	PPK[3] = TTAK[3];
-	PPK[4] = TTAK[4];
-	PPK[5] = TTAK[4] + IV16;
-
-	/* Step 2 - 96-bit bijective mixing using S-box */
-	PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
-	PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
-	PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
-	PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
-	PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
-	PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
-
-	PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
-	PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
-	PPK[2] += RotR1(PPK[1]);
-	PPK[3] += RotR1(PPK[2]);
-	PPK[4] += RotR1(PPK[3]);
-	PPK[5] += RotR1(PPK[4]);
-
-	/* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
-	 * WEPSeed[0..2] is transmitted as WEP IV */
-	WEPSeed[0] = Hi8(IV16);
-	WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
-	WEPSeed[2] = Lo8(IV16);
-	WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
-
-#ifdef __BIG_ENDIAN
-	{
-		int i;
-		for (i = 0; i < 6; i++)
-			PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
-	}
-#endif
-}
-
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
-	struct ieee80211_tkip_data *tkey = priv;
-	struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
-	int len;
-	u8  *pos;
-	struct ieee80211_hdr_4addr *hdr;
-	u8 rc4key[16], *icv;
-	u32 crc;
-	struct scatterlist sg;
-	int ret;
-
-	ret = 0;
-	if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
-	    skb->len < hdr_len)
-		return -1;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
-	if (!tkey->tx_phase1_done) {
-		tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
-				   tkey->tx_iv32);
-		tkey->tx_phase1_done = 1;
-	}
-	tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
-
-	len = skb->len - hdr_len;
-	pos = skb_push(skb, 8);
-	memmove(pos, pos + 8, hdr_len);
-	pos += hdr_len;
-
-	*pos++ = rc4key[0];
-	*pos++ = rc4key[1];
-	*pos++ = rc4key[2];
-	*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
-	*pos++ = tkey->tx_iv32 & 0xff;
-	*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
-	*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
-	*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
-
-	icv = skb_put(skb, 4);
-	crc = ~crc32_le(~0, pos, len);
-	icv[0] = crc;
-	icv[1] = crc >> 8;
-	icv[2] = crc >> 16;
-	icv[3] = crc >> 24;
-	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	sg_init_one(&sg, pos, len + 4);
-	ret = crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-
-	tkey->tx_iv16++;
-	if (tkey->tx_iv16 == 0) {
-		tkey->tx_phase1_done = 0;
-		tkey->tx_iv32++;
-	}
-	   return ret;
-}
-
-static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
-	struct ieee80211_tkip_data *tkey = priv;
-	struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
-	u8 keyidx, *pos;
-	u32 iv32;
-	u16 iv16;
-	struct ieee80211_hdr_4addr *hdr;
-	u8 icv[4];
-	u32 crc;
-	struct scatterlist sg;
-	u8 rc4key[16];
-	int plen;
-
-	if (skb->len < hdr_len + 8 + 4)
-		return -1;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	pos = skb->data + hdr_len;
-	keyidx = pos[3];
-	if (!(keyidx & (1 << 5))) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
-			       " flag from %pM\n", hdr->addr2);
-		}
-		return -2;
-	}
-	keyidx >>= 6;
-	if (tkey->key_idx != keyidx) {
-		printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
-		       "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
-		return -6;
-	}
-	if (!tkey->key_set) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: received packet from %pM"
-			       " with keyid=%d that does not have a configured"
-			       " key\n", hdr->addr2, keyidx);
-		}
-		return -3;
-	}
-	iv16 = (pos[0] << 8) | pos[2];
-	iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
-	pos += 8;
-
-	if (iv32 < tkey->rx_iv32 ||
-	    (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
-			       " previous TSC %08x%04x received TSC "
-			       "%08x%04x\n", hdr->addr2,
-			       tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
-		}
-		tkey->dot11RSNAStatsTKIPReplays++;
-		return -4;
-	}
-
-	if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
-		tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
-		tkey->rx_phase1_done = 1;
-	}
-	tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
-
-	plen = skb->len - hdr_len - 12;
-	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	sg_init_one(&sg, pos, plen + 4);
-	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG ": TKIP: failed to decrypt "
-			       "received packet from %pM\n",
-			       hdr->addr2);
-		}
-		return -7;
-	}
-
-	crc = ~crc32_le(~0, pos, plen);
-	icv[0] = crc;
-	icv[1] = crc >> 8;
-	icv[2] = crc >> 16;
-	icv[3] = crc >> 24;
-	if (memcmp(icv, pos + plen, 4) != 0) {
-		if (iv32 != tkey->rx_iv32) {
-			/* Previously cached Phase1 result was already lost, so
-			 * it needs to be recalculated for the next packet. */
-			tkey->rx_phase1_done = 0;
-		}
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "TKIP: ICV error detected: STA="
-			       "%pM\n", hdr->addr2);
-		}
-		tkey->dot11RSNAStatsTKIPICVErrors++;
-		return -5;
-	}
-
-	/* Update real counters only after Michael MIC verification has
-	 * completed */
-	tkey->rx_iv32_new = iv32;
-	tkey->rx_iv16_new = iv16;
-
-	/* Remove IV and ICV */
-	memmove(skb->data + 8, skb->data, hdr_len);
-	skb_pull(skb, 8);
-	skb_trim(skb, skb->len - 4);
-
-	return keyidx;
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, u8 *hdr,
-			u8 *data, size_t data_len, u8 *mic)
-{
-	struct hash_desc desc;
-	struct scatterlist sg[2];
-
-	if (tfm_michael == NULL) {
-		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
-		return -1;
-	}
-
-	sg_init_table(sg, 2);
-	sg_set_buf(&sg[0], hdr, 16);
-	sg_set_buf(&sg[1], data, data_len);
-
-	if (crypto_hash_setkey(tfm_michael, key, 8))
-		return -1;
-
-	desc.tfm = tfm_michael;
-	desc.flags = 0;
-	return crypto_hash_digest(&desc, sg, data_len + 16, mic);
-}
-
-static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
-{
-	struct ieee80211_hdr_4addr *hdr11;
-
-	hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
-	switch (le16_to_cpu(hdr11->frame_ctl) &
-		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
-	case IEEE80211_FCTL_TODS:
-		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
-		break;
-	case IEEE80211_FCTL_FROMDS:
-		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
-		break;
-	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
-		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
-		break;
-	case 0:
-		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
-		break;
-	}
-
-	hdr[12] = 0; /* priority */
-
-	hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
-}
-
-
-static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
-				     void *priv)
-{
-	struct ieee80211_tkip_data *tkey = priv;
-	u8 *pos;
-	struct ieee80211_hdr_4addr *hdr;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
-	if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
-		printk(KERN_DEBUG "Invalid packet for Michael MIC add "
-		       "(tailroom=%d hdr_len=%d skb->len=%d)\n",
-		       skb_tailroom(skb), hdr_len, skb->len);
-		return -1;
-	}
-
-	michael_mic_hdr(skb, tkey->tx_hdr);
-
-	if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
-		tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
-
-	pos = skb_put(skb, 8);
-
-	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
-			skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
-		return -1;
-
-	return 0;
-}
-
-static void ieee80211_michael_mic_failure(struct net_device *dev,
-					  struct ieee80211_hdr_4addr *hdr,
-					  int keyidx)
-{
-	union iwreq_data wrqu;
-	struct iw_michaelmicfailure ev;
-
-	/* TODO: needed parameters: count, keyid, key type, TSC */
-	memset(&ev, 0, sizeof(ev));
-	ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
-	if (hdr->addr1[0] & 0x01)
-		ev.flags |= IW_MICFAILURE_GROUP;
-	else
-		ev.flags |= IW_MICFAILURE_PAIRWISE;
-	ev.src_addr.sa_family = ARPHRD_ETHER;
-	memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
-	memset(&wrqu, 0, sizeof(wrqu));
-	wrqu.data.length = sizeof(ev);
-	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
-}
-
-static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
-					int hdr_len, void *priv)
-{
-	struct ieee80211_tkip_data *tkey = priv;
-	u8 mic[8];
-	struct ieee80211_hdr_4addr *hdr;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
-	if (!tkey->key_set)
-		return -1;
-
-	michael_mic_hdr(skb, tkey->rx_hdr);
-	if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
-		tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
-
-	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
-			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
-		return -1;
-
-	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
-		struct ieee80211_hdr_4addr *hdr;
-		hdr = (struct ieee80211_hdr_4addr *)skb->data;
-		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
-		       "MSDU from %pM keyidx=%d\n",
-		       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
-		       keyidx);
-		if (skb->dev)
-			ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
-		tkey->dot11RSNAStatsTKIPLocalMICFailures++;
-		return -1;
-	}
-
-	/* Update TSC counters for RX now that the packet verification has
-	 * completed. */
-	tkey->rx_iv32 = tkey->rx_iv32_new;
-	tkey->rx_iv16 = tkey->rx_iv16_new;
-
-	skb_trim(skb, skb->len - 8);
-
-	return 0;
-}
-
-
-static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
-{
-	struct ieee80211_tkip_data *tkey = priv;
-	int keyidx;
-	struct crypto_hash *tfm = tkey->tx_tfm_michael;
-	struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
-	struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
-	struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-
-	keyidx = tkey->key_idx;
-	memset(tkey, 0, sizeof(*tkey));
-	tkey->key_idx = keyidx;
-
-	tkey->tx_tfm_michael = tfm;
-	tkey->tx_tfm_arc4 = tfm2;
-	tkey->rx_tfm_michael = tfm3;
-	tkey->rx_tfm_arc4 = tfm4;
-
-	if (len == TKIP_KEY_LEN) {
-		memcpy(tkey->key, key, TKIP_KEY_LEN);
-		tkey->key_set = 1;
-		tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
-		if (seq) {
-			tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
-				(seq[3] << 8) | seq[2];
-			tkey->rx_iv16 = (seq[1] << 8) | seq[0];
-		}
-	} else if (len == 0)
-		tkey->key_set = 0;
-	else
-		return -1;
-
-	return 0;
-}
-
-
-static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
-{
-	struct ieee80211_tkip_data *tkey = priv;
-
-	if (len < TKIP_KEY_LEN)
-		return -1;
-
-	if (!tkey->key_set)
-		return 0;
-	memcpy(key, tkey->key, TKIP_KEY_LEN);
-
-	if (seq) {
-		/* Return the sequence number of the last transmitted frame. */
-		u16 iv16 = tkey->tx_iv16;
-		u32 iv32 = tkey->tx_iv32;
-		if (iv16 == 0)
-			iv32--;
-		iv16--;
-		seq[0] = tkey->tx_iv16;
-		seq[1] = tkey->tx_iv16 >> 8;
-		seq[2] = tkey->tx_iv32;
-		seq[3] = tkey->tx_iv32 >> 8;
-		seq[4] = tkey->tx_iv32 >> 16;
-		seq[5] = tkey->tx_iv32 >> 24;
-	}
-
-	return TKIP_KEY_LEN;
-}
-
-
-static char *ieee80211_tkip_print_stats(char *p, void *priv)
-{
-	struct ieee80211_tkip_data *tkip = priv;
-	p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
-		     "tx_pn=%02x%02x%02x%02x%02x%02x "
-		     "rx_pn=%02x%02x%02x%02x%02x%02x "
-		     "replays=%d icv_errors=%d local_mic_failures=%d\n",
-		     tkip->key_idx, tkip->key_set,
-		     (tkip->tx_iv32 >> 24) & 0xff,
-		     (tkip->tx_iv32 >> 16) & 0xff,
-		     (tkip->tx_iv32 >> 8) & 0xff,
-		     tkip->tx_iv32 & 0xff,
-		     (tkip->tx_iv16 >> 8) & 0xff,
-		     tkip->tx_iv16 & 0xff,
-		     (tkip->rx_iv32 >> 24) & 0xff,
-		     (tkip->rx_iv32 >> 16) & 0xff,
-		     (tkip->rx_iv32 >> 8) & 0xff,
-		     tkip->rx_iv32 & 0xff,
-		     (tkip->rx_iv16 >> 8) & 0xff,
-		     tkip->rx_iv16 & 0xff,
-		     tkip->dot11RSNAStatsTKIPReplays,
-		     tkip->dot11RSNAStatsTKIPICVErrors,
-		     tkip->dot11RSNAStatsTKIPLocalMICFailures);
-	return p;
-}
-
-
-static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
-	.name			= "TKIP",
-	.init			= ieee80211_tkip_init,
-	.deinit			= ieee80211_tkip_deinit,
-	.encrypt_mpdu		= ieee80211_tkip_encrypt,
-	.decrypt_mpdu		= ieee80211_tkip_decrypt,
-	.encrypt_msdu		= ieee80211_michael_mic_add,
-	.decrypt_msdu		= ieee80211_michael_mic_verify,
-	.set_key		= ieee80211_tkip_set_key,
-	.get_key		= ieee80211_tkip_get_key,
-	.print_stats		= ieee80211_tkip_print_stats,
-	.extra_prefix_len	= 4 + 4, /* IV + ExtIV */
-	.extra_postfix_len	= 8 + 4, /* MIC + ICV */
-	.owner		        = THIS_MODULE,
-};
-
-
-int ieee80211_crypto_tkip_init(void)
-{
-	return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-
-void ieee80211_crypto_tkip_exit(void)
-{
-	ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-
-void ieee80211_tkip_null(void)
-{
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
deleted file mode 100644
index f253672..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Host AP crypt: host-based WEP encryption implementation for Host AP driver
- *
- * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: WEP");
-MODULE_LICENSE("GPL");
-
-struct prism2_wep_data {
-	u32 iv;
-#define WEP_KEY_LEN 13
-	u8 key[WEP_KEY_LEN + 1];
-	u8 key_len;
-	u8 key_idx;
-	struct crypto_blkcipher *tx_tfm;
-	struct crypto_blkcipher *rx_tfm;
-};
-
-static void *prism2_wep_init(int keyidx)
-{
-	struct prism2_wep_data *priv;
-
-	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
-	if (priv == NULL)
-		goto fail;
-	priv->key_idx = keyidx;
-	priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(priv->tx_tfm)) {
-		pr_debug("could not allocate crypto API arc4\n");
-		priv->tx_tfm = NULL;
-		goto fail;
-	}
-	priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(priv->rx_tfm)) {
-		pr_debug("could not allocate crypto API arc4\n");
-		priv->rx_tfm = NULL;
-		goto fail;
-	}
-
-	/* start WEP IV from a random value */
-	get_random_bytes(&priv->iv, 4);
-
-	return priv;
-
-fail:
-	if (priv) {
-		if (priv->tx_tfm)
-			crypto_free_blkcipher(priv->tx_tfm);
-		if (priv->rx_tfm)
-			crypto_free_blkcipher(priv->rx_tfm);
-		kfree(priv);
-	}
-
-	return NULL;
-}
-
-static void prism2_wep_deinit(void *priv)
-{
-	struct prism2_wep_data *_priv = priv;
-
-	if (_priv) {
-		if (_priv->tx_tfm)
-			crypto_free_blkcipher(_priv->tx_tfm);
-		if (_priv->rx_tfm)
-			crypto_free_blkcipher(_priv->rx_tfm);
-	}
-
-	kfree(priv);
-}
-
-/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- * so the payload length increases with 8 bytes.
- *
- * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- */
-static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
-	struct prism2_wep_data *wep = priv;
-	struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
-	u32 klen, len;
-	u8 key[WEP_KEY_LEN + 3];
-	u8 *pos;
-	u32 crc;
-	u8 *icv;
-	struct scatterlist sg;
-
-	if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
-	    skb->len < hdr_len)
-		return -1;
-
-	len = skb->len - hdr_len;
-	pos = skb_push(skb, 4);
-	memmove(pos, pos + 4, hdr_len);
-	pos += hdr_len;
-
-	klen = 3 + wep->key_len;
-
-	wep->iv++;
-
-	/* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
-	 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
-	 * can be used to speedup attacks, so avoid using them. */
-	if ((wep->iv & 0xff00) == 0xff00) {
-		u8 B = (wep->iv >> 16) & 0xff;
-		if (B >= 3 && B < klen)
-			wep->iv += 0x0100;
-	}
-
-	/* Prepend 24-bit IV to RC4 key and TX frame */
-	*pos++ = key[0] = (wep->iv >> 16) & 0xff;
-	*pos++ = key[1] = (wep->iv >> 8) & 0xff;
-	*pos++ = key[2] = wep->iv & 0xff;
-	*pos++ = wep->key_idx << 6;
-
-	/* Copy rest of the WEP key (the secret part) */
-	memcpy(key + 3, wep->key, wep->key_len);
-
-	/* Append little-endian CRC32 and encrypt it to produce ICV */
-	crc = ~crc32_le(~0, pos, len);
-	icv = skb_put(skb, 4);
-	icv[0] = crc;
-	icv[1] = crc >> 8;
-	icv[2] = crc >> 16;
-	icv[3] = crc >> 24;
-
-	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg_init_one(&sg, pos, len + 4);
-
-	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-}
-
-/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
- * the frame: IV (4 bytes), encrypted payload (including SNAP header),
- * ICV (4 bytes). len includes both IV and ICV.
- *
- * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
- * failure. If frame is OK, IV and ICV will be removed.
- */
-static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
-	struct prism2_wep_data *wep = priv;
-	struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
-	u32 klen, plen;
-	u8 key[WEP_KEY_LEN + 3];
-	u8 keyidx, *pos;
-	u32 crc;
-	u8 icv[4];
-	struct scatterlist sg;
-
-	if (skb->len < hdr_len + 8)
-		return -1;
-
-	pos = skb->data + hdr_len;
-	key[0] = *pos++;
-	key[1] = *pos++;
-	key[2] = *pos++;
-	keyidx = *pos++ >> 6;
-	if (keyidx != wep->key_idx)
-		return -1;
-
-	klen = 3 + wep->key_len;
-
-	/* Copy rest of the WEP key (the secret part) */
-	memcpy(key + 3, wep->key, wep->key_len);
-
-	/* Apply RC4 to data and compute CRC32 over decrypted data */
-	plen = skb->len - hdr_len - 8;
-
-	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg_init_one(&sg, pos, plen + 4);
-
-	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
-		return -7;
-
-	crc = ~crc32_le(~0, pos, plen);
-	icv[0] = crc;
-	icv[1] = crc >> 8;
-	icv[2] = crc >> 16;
-	icv[3] = crc >> 24;
-
-	if (memcmp(icv, pos + plen, 4) != 0) {
-		/* ICV mismatch - drop frame */
-		return -2;
-	}
-
-	/* Remove IV and ICV */
-	memmove(skb->data + 4, skb->data, hdr_len);
-	skb_pull(skb, 4);
-	skb_trim(skb, skb->len - 4);
-	return 0;
-}
-
-static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
-{
-	struct prism2_wep_data *wep = priv;
-
-	if (len < 0 || len > WEP_KEY_LEN)
-		return -1;
-
-	memcpy(wep->key, key, len);
-	wep->key_len = len;
-
-	return 0;
-}
-
-static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
-{
-	struct prism2_wep_data *wep = priv;
-
-	if (len < wep->key_len)
-		return -1;
-
-	memcpy(key, wep->key, wep->key_len);
-
-	return wep->key_len;
-}
-
-static char *prism2_wep_print_stats(char *p, void *priv)
-{
-	struct prism2_wep_data *wep = priv;
-	p += sprintf(p, "key[%d] alg=WEP len=%d\n",
-		     wep->key_idx, wep->key_len);
-	return p;
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
-	.name			= "WEP",
-	.init			= prism2_wep_init,
-	.deinit			= prism2_wep_deinit,
-	.encrypt_mpdu		= prism2_wep_encrypt,
-	.decrypt_mpdu		= prism2_wep_decrypt,
-	.encrypt_msdu		= NULL,
-	.decrypt_msdu		= NULL,
-	.set_key		= prism2_wep_set_key,
-	.get_key		= prism2_wep_get_key,
-	.print_stats		= prism2_wep_print_stats,
-	.extra_prefix_len	= 4, /* IV */
-	.extra_postfix_len	= 4, /* ICV */
-	.owner			= THIS_MODULE,
-};
-
-int ieee80211_crypto_wep_init(void)
-{
-	return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_crypto_wep_exit(void)
-{
-	ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_wep_null(void)
-{
-	return;
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
deleted file mode 100644
index 07a1fbb..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*******************************************************************************
-
-  Copyright(c) 2004 Intel Corporation. All rights reserved.
-
-  Portions of this file are based on the WEP enablement code provided by the
-  Host AP project hostap-drivers v0.1.3
-  Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
-  <jkmaline@cc.hut.fi>
-  Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of version 2 of the GNU General Public License 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.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-
-  Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/compiler.h>
-//#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <net/arp.h>
-#include <net/net_namespace.h>
-
-#include "ieee80211.h"
-
-MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
-MODULE_LICENSE("GPL");
-
-#define DRV_NAME "ieee80211"
-
-static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
-{
-	if (ieee->networks)
-		return 0;
-
-	ieee->networks = kcalloc(
-		MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
-		GFP_KERNEL);
-	if (!ieee->networks)
-		return -ENOMEM;
-
-	return 0;
-}
-
-static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
-{
-	if (!ieee->networks)
-		return;
-	kfree(ieee->networks);
-	ieee->networks = NULL;
-}
-
-static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
-{
-	int i;
-
-	INIT_LIST_HEAD(&ieee->network_free_list);
-	INIT_LIST_HEAD(&ieee->network_list);
-	for (i = 0; i < MAX_NETWORK_COUNT; i++)
-		list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
-}
-
-
-struct net_device *alloc_ieee80211(int sizeof_priv)
-{
-	struct ieee80211_device *ieee;
-	struct net_device *dev;
-	int i, err;
-
-	IEEE80211_DEBUG_INFO("Initializing...\n");
-
-	dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
-	if (!dev) {
-		IEEE80211_ERROR("Unable to network device.\n");
-		goto failed;
-	}
-	ieee = netdev_priv(dev);
-
-	ieee->dev = dev;
-
-	err = ieee80211_networks_allocate(ieee);
-	if (err) {
-		IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
-				err);
-		goto failed;
-	}
-	ieee80211_networks_initialize(ieee);
-
-	/* Default fragmentation threshold is maximum payload size */
-	ieee->fts = DEFAULT_FTS;
-	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
-	ieee->open_wep = 1;
-
-	/* Default to enabling full open WEP with host based encrypt/decrypt */
-	ieee->host_encrypt = 1;
-	ieee->host_decrypt = 1;
-	ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
-
-	INIT_LIST_HEAD(&ieee->crypt_deinit_list);
-	init_timer(&ieee->crypt_deinit_timer);
-	ieee->crypt_deinit_timer.data = (unsigned long)ieee;
-	ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
-
-	spin_lock_init(&ieee->lock);
-	spin_lock_init(&ieee->wpax_suitlist_lock);
-
-	ieee->wpax_type_set = 0;
-	ieee->wpa_enabled = 0;
-	ieee->tkip_countermeasures = 0;
-	ieee->drop_unencrypted = 0;
-	ieee->privacy_invoked = 0;
-	ieee->ieee802_1x = 1;
-	ieee->raw_tx = 0;
-
-	ieee80211_softmac_init(ieee);
-
-	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
-		INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
-
-	for (i = 0; i < 17; i++) {
-		ieee->last_rxseq_num[i] = -1;
-		ieee->last_rxfrag_num[i] = -1;
-		ieee->last_packet_time[i] = 0;
-	}
-//These function were added to load crypte module autoly
-	ieee80211_tkip_null();
-	ieee80211_wep_null();
-	ieee80211_ccmp_null();
-	return dev;
-
- failed:
-	if (dev)
-		free_netdev(dev);
-	return NULL;
-}
-
-
-void free_ieee80211(struct net_device *dev)
-{
-	struct ieee80211_device *ieee = netdev_priv(dev);
-
-	int i;
-	struct list_head *p, *q;
-
-
-	ieee80211_softmac_free(ieee);
-	del_timer_sync(&ieee->crypt_deinit_timer);
-	ieee80211_crypt_deinit_entries(ieee, 1);
-
-	for (i = 0; i < WEP_KEYS; i++) {
-		struct ieee80211_crypt_data *crypt = ieee->crypt[i];
-		if (crypt) {
-			if (crypt->ops)
-				crypt->ops->deinit(crypt->priv);
-			kfree(crypt);
-			ieee->crypt[i] = NULL;
-		}
-	}
-
-	ieee80211_networks_free(ieee);
-
-	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
-		list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
-			kfree(list_entry(p, struct ieee_ibss_seq, list));
-			list_del(p);
-		}
-	}
-
-
-	free_netdev(dev);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
deleted file mode 100644
index b522b57..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ /dev/null
@@ -1,1486 +0,0 @@
-/*
- * Original code based Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3 - hostap.o module, common routines
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- ******************************************************************************
-
-  Few modifications for Realtek's Wi-Fi drivers by
-  Andrea Merello <andrea.merello@gmail.com>
-
-  A special thanks goes to Realtek for their support !
-
-******************************************************************************/
-
-
-#include <linux/compiler.h>
-//#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <linux/ctype.h>
-
-#include "ieee80211.h"
-#include "dot11d.h"
-static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
-					struct sk_buff *skb,
-					struct ieee80211_rx_stats *rx_stats)
-{
-	struct ieee80211_hdr_4addr *hdr =
-		(struct ieee80211_hdr_4addr *)skb->data;
-	u16 fc = le16_to_cpu(hdr->frame_ctl);
-
-	skb->dev = ieee->dev;
-	skb_reset_mac_header(skb);
-	skb_pull(skb, ieee80211_get_hdrlen(fc));
-	skb->pkt_type = PACKET_OTHERHOST;
-	skb->protocol = __constant_htons(ETH_P_80211_RAW);
-	memset(skb->cb, 0, sizeof(skb->cb));
-	netif_rx(skb);
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static struct ieee80211_frag_entry *
-ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
-			  unsigned int frag, u8 tid, u8 *src, u8 *dst)
-{
-	struct ieee80211_frag_entry *entry;
-	int i;
-
-	for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
-		entry = &ieee->frag_cache[tid][i];
-		if (entry->skb != NULL &&
-		    time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
-			IEEE80211_DEBUG_FRAG(
-				"expiring fragment cache entry "
-				"seq=%u last_frag=%u\n",
-				entry->seq, entry->last_frag);
-			dev_kfree_skb_any(entry->skb);
-			entry->skb = NULL;
-		}
-
-		if (entry->skb != NULL && entry->seq == seq &&
-		    (entry->last_frag + 1 == frag || frag == -1) &&
-		    memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
-		    memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
-			return entry;
-	}
-
-	return NULL;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct sk_buff *
-ieee80211_frag_cache_get(struct ieee80211_device *ieee,
-			 struct ieee80211_hdr_4addr *hdr)
-{
-	struct sk_buff *skb = NULL;
-	u16 fc = le16_to_cpu(hdr->frame_ctl);
-	u16 sc = le16_to_cpu(hdr->seq_ctl);
-	unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
-	unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
-	struct ieee80211_frag_entry *entry;
-	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
-	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
-	u8 tid;
-
-	if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
-		hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
-		tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
-		tid = UP2AC(tid);
-		tid++;
-	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
-		hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
-		tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
-		tid = UP2AC(tid);
-		tid++;
-	} else {
-		tid = 0;
-	}
-
-	if (frag == 0) {
-		/* Reserve enough space to fit maximum frame length */
-		skb = dev_alloc_skb(ieee->dev->mtu +
-				    sizeof(struct ieee80211_hdr_4addr) +
-				    8 /* LLC */ +
-				    2 /* alignment */ +
-				    8 /* WEP */ +
-				    ETH_ALEN /* WDS */ +
-				    (IEEE80211_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */);
-		if (skb == NULL)
-			return NULL;
-
-		entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
-		ieee->frag_next_idx[tid]++;
-		if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
-			ieee->frag_next_idx[tid] = 0;
-
-		if (entry->skb != NULL)
-			dev_kfree_skb_any(entry->skb);
-
-		entry->first_frag_time = jiffies;
-		entry->seq = seq;
-		entry->last_frag = frag;
-		entry->skb = skb;
-		memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
-		memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
-	} else {
-		/* received a fragment of a frame for which the head fragment
-		 * should have already been received */
-		entry = ieee80211_frag_cache_find(ieee, seq, frag, tid, hdr->addr2,
-						  hdr->addr1);
-		if (entry != NULL) {
-			entry->last_frag = frag;
-			skb = entry->skb;
-		}
-	}
-
-	return skb;
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
-					   struct ieee80211_hdr_4addr *hdr)
-{
-	u16 fc = le16_to_cpu(hdr->frame_ctl);
-	u16 sc = le16_to_cpu(hdr->seq_ctl);
-	unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
-	struct ieee80211_frag_entry *entry;
-	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
-	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
-	u8 tid;
-
-	if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
-		hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
-		tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
-		tid = UP2AC(tid);
-		tid++;
-	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
-		hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
-		tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
-		tid = UP2AC(tid);
-		tid++;
-	} else {
-		tid = 0;
-	}
-
-	entry = ieee80211_frag_cache_find(ieee, seq, -1, tid, hdr->addr2,
-					  hdr->addr1);
-
-	if (entry == NULL) {
-		IEEE80211_DEBUG_FRAG(
-			"could not invalidate fragment cache "
-			"entry (seq=%u)\n", seq);
-		return -1;
-	}
-
-	entry->skb = NULL;
-	return 0;
-}
-
-
-
-/* ieee80211_rx_frame_mgtmt
- *
- * Responsible for handling management control frames
- *
- * Called by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
-			struct ieee80211_rx_stats *rx_stats, u16 type,
-			u16 stype)
-{
-	struct ieee80211_hdr_4addr *hdr;
-
-	// cheat the the hdr type
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
-	/* On the struct stats definition there is written that
-	 * this is not mandatory.... but seems that the probe
-	 * response parser uses it
-	 */
-	rx_stats->len = skb->len;
-	ieee80211_rx_mgt(ieee, (struct ieee80211_hdr_4addr *)skb->data,
-			 rx_stats);
-
-	if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) {
-		dev_kfree_skb_any(skb);
-		return 0;
-	}
-
-	ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
-
-	dev_kfree_skb_any(skb);
-
-	return 0;
-
-}
-
-
-
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
-/* Called by ieee80211_rx_frame_decrypt */
-static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
-				    struct sk_buff *skb, size_t hdrlen)
-{
-	struct net_device *dev = ieee->dev;
-	u16 fc, ethertype;
-	struct ieee80211_hdr_4addr *hdr;
-	u8 *pos;
-
-	if (skb->len < 24)
-		return 0;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	fc = le16_to_cpu(hdr->frame_ctl);
-
-	/* check that the frame is unicast frame to us */
-	if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
-	    IEEE80211_FCTL_TODS &&
-	    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
-	    memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
-		/* ToDS frame with own addr BSSID and DA */
-	} else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
-		   IEEE80211_FCTL_FROMDS &&
-		   memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
-		/* FromDS frame with own addr as DA */
-	} else
-		return 0;
-
-	if (skb->len < 24 + 8)
-		return 0;
-
-	/* check for port access entity Ethernet type */
-//	pos = skb->data + 24;
-	pos = skb->data + hdrlen;
-	ethertype = (pos[6] << 8) | pos[7];
-	if (ethertype == ETH_P_PAE)
-		return 1;
-
-	return 0;
-}
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
-			   struct ieee80211_crypt_data *crypt)
-{
-	struct ieee80211_hdr_4addr *hdr;
-	int res, hdrlen;
-
-	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
-		return 0;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
-	if (ieee->tkip_countermeasures &&
-	    strcmp(crypt->ops->name, "TKIP") == 0) {
-		if (net_ratelimit()) {
-			netdev_dbg(ieee->dev,
-				   "TKIP countermeasures: dropped received packet from %pM\n",
-				   ieee->dev->name, hdr->addr2);
-		}
-		return -1;
-	}
-#endif
-
-	atomic_inc(&crypt->refcnt);
-	res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
-	atomic_dec(&crypt->refcnt);
-	if (res < 0) {
-		IEEE80211_DEBUG_DROP(
-			"decryption failed (SA=%pM"
-			") res=%d\n", hdr->addr2, res);
-		if (res == -2)
-			IEEE80211_DEBUG_DROP("Decryption failed ICV "
-					     "mismatch (key %d)\n",
-					     skb->data[hdrlen + 3] >> 6);
-		ieee->ieee_stats.rx_discards_undecryptable++;
-		return -1;
-	}
-
-	return res;
-}
-
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
-				struct sk_buff *skb, int keyidx,
-				struct ieee80211_crypt_data *crypt)
-{
-	struct ieee80211_hdr_4addr *hdr;
-	int res, hdrlen;
-
-	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
-		return 0;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
-	atomic_inc(&crypt->refcnt);
-	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
-	atomic_dec(&crypt->refcnt);
-	if (res < 0) {
-		netdev_dbg(ieee->dev,
-			   "MSDU decryption/MIC verification failed (SA=%pM keyidx=%d)\n",
-			   hdr->addr2, keyidx);
-		return -1;
-	}
-
-	return 0;
-}
-
-
-/* this function is stolen from ipw2200 driver*/
-#define IEEE_PACKET_RETRY_TIME (5*HZ)
-static int is_duplicate_packet(struct ieee80211_device *ieee,
-			       struct ieee80211_hdr_4addr *header)
-{
-	u16 fc = le16_to_cpu(header->frame_ctl);
-	u16 sc = le16_to_cpu(header->seq_ctl);
-	u16 seq = WLAN_GET_SEQ_SEQ(sc);
-	u16 frag = WLAN_GET_SEQ_FRAG(sc);
-	u16 *last_seq, *last_frag;
-	unsigned long *last_time;
-	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
-	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
-	u8 tid;
-
-	//TO2DS and QoS
-	if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
-		hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
-		tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
-		tid = UP2AC(tid);
-		tid++;
-	} else if (IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
-		hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header;
-		tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
-		tid = UP2AC(tid);
-		tid++;
-	} else { // no QoS
-		tid = 0;
-	}
-	switch (ieee->iw_mode) {
-	case IW_MODE_ADHOC:
-	{
-		struct list_head *p;
-		struct ieee_ibss_seq *entry = NULL;
-		u8 *mac = header->addr2;
-		int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
-
-		list_for_each(p, &ieee->ibss_mac_hash[index]) {
-			entry = list_entry(p, struct ieee_ibss_seq, list);
-			if (!memcmp(entry->mac, mac, ETH_ALEN))
-				break;
-		}
-	//	if (memcmp(entry->mac, mac, ETH_ALEN)){
-		if (p == &ieee->ibss_mac_hash[index]) {
-			entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
-			if (!entry)
-				return 0;
-
-			memcpy(entry->mac, mac, ETH_ALEN);
-			entry->seq_num[tid] = seq;
-			entry->frag_num[tid] = frag;
-			entry->packet_time[tid] = jiffies;
-			list_add(&entry->list, &ieee->ibss_mac_hash[index]);
-			return 0;
-		}
-		last_seq = &entry->seq_num[tid];
-		last_frag = &entry->frag_num[tid];
-		last_time = &entry->packet_time[tid];
-		break;
-	}
-
-	case IW_MODE_INFRA:
-		last_seq = &ieee->last_rxseq_num[tid];
-		last_frag = &ieee->last_rxfrag_num[tid];
-		last_time = &ieee->last_packet_time[tid];
-
-		break;
-	default:
-		return 0;
-	}
-
-//	if(tid != 0) {
-//		printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
-//	}
-	if ((*last_seq == seq) &&
-	    time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
-		if (*last_frag == frag) {
-			//printk(KERN_WARNING "[1] go drop!\n");
-			goto drop;
-
-		}
-		if (*last_frag + 1 != frag)
-			/* out-of-order fragment */
-			//printk(KERN_WARNING "[2] go drop!\n");
-			goto drop;
-	} else
-		*last_seq = seq;
-
-	*last_frag = frag;
-	*last_time = jiffies;
-	return 0;
-
-drop:
-//	BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
-//	printk("DUP\n");
-
-	return 1;
-}
-
-
-/* All received frames are sent to this function. @skb contains the frame in
- * IEEE 802.11 format, i.e., in the format it was sent over air.
- * This function is called only as a tasklet (software IRQ). */
-int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-		     struct ieee80211_rx_stats *rx_stats)
-{
-	struct net_device *dev = ieee->dev;
-	//struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct ieee80211_hdr_4addr *hdr;
-
-	size_t hdrlen;
-	u16 fc, type, stype, sc;
-	struct net_device_stats *stats;
-	unsigned int frag;
-	u8 *payload;
-	u16 ethertype;
-	u8 dst[ETH_ALEN];
-	u8 src[ETH_ALEN];
-	u8 bssid[ETH_ALEN];
-	struct ieee80211_crypt_data *crypt = NULL;
-	int keyidx = 0;
-
-	// cheat the the hdr type
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	stats = &ieee->stats;
-
-	if (skb->len < 10) {
-		netdev_info(ieee->dev, "SKB length < 10\n");
-		goto rx_dropped;
-	}
-
-	fc = le16_to_cpu(hdr->frame_ctl);
-	type = WLAN_FC_GET_TYPE(fc);
-	stype = WLAN_FC_GET_STYPE(fc);
-	sc = le16_to_cpu(hdr->seq_ctl);
-
-	frag = WLAN_GET_SEQ_FRAG(sc);
-
-//YJ,add,080828,for keep alive
-	if ((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS) {
-		if (!memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN))
-			ieee->NumRxUnicast++;
-	} else {
-		if (!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
-			ieee->NumRxUnicast++;
-	}
-//YJ,add,080828,for keep alive,end
-
-	hdrlen = ieee80211_get_hdrlen(fc);
-
-
-	if (ieee->iw_mode == IW_MODE_MONITOR) {
-		ieee80211_monitor_rx(ieee, skb, rx_stats);
-		stats->rx_packets++;
-		stats->rx_bytes += skb->len;
-		return 1;
-	}
-
-	if (ieee->host_decrypt) {
-		int idx = 0;
-		if (skb->len >= hdrlen + 3)
-			idx = skb->data[hdrlen + 3] >> 6;
-		crypt = ieee->crypt[idx];
-
-		/* allow NULL decrypt to indicate an station specific override
-		 * for default encryption */
-		if (crypt && (crypt->ops == NULL ||
-			      crypt->ops->decrypt_mpdu == NULL))
-			crypt = NULL;
-
-		if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
-			/* This seems to be triggered by some (multicast?)
-			 * frames from other than current BSS, so just drop the
-			 * frames silently instead of filling system log with
-			 * these reports. */
-			IEEE80211_DEBUG_DROP("Decryption failed (not set)"
-					     " (SA=%pM)\n",
-					     hdr->addr2);
-			ieee->ieee_stats.rx_discards_undecryptable++;
-			goto rx_dropped;
-		}
-	}
-
-	if (skb->len < IEEE80211_DATA_HDR3_LEN)
-		goto rx_dropped;
-
-	// if QoS enabled, should check the sequence for each of the AC
-	if (is_duplicate_packet(ieee, hdr))
-		goto rx_dropped;
-
-
-	if (type == IEEE80211_FTYPE_MGMT) {
-		if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
-			goto rx_dropped;
-		else
-			goto rx_exit;
-	}
-
-	/* Data frame - extract src/dst addresses */
-	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
-	case IEEE80211_FCTL_FROMDS:
-		memcpy(dst, hdr->addr1, ETH_ALEN);
-		memcpy(src, hdr->addr3, ETH_ALEN);
-		memcpy(bssid, hdr->addr2, ETH_ALEN);
-		break;
-	case IEEE80211_FCTL_TODS:
-		memcpy(dst, hdr->addr3, ETH_ALEN);
-		memcpy(src, hdr->addr2, ETH_ALEN);
-		memcpy(bssid, hdr->addr1, ETH_ALEN);
-		break;
-	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
-		if (skb->len < IEEE80211_DATA_HDR4_LEN)
-			goto rx_dropped;
-		memcpy(dst, hdr->addr3, ETH_ALEN);
-		memcpy(src, hdr->addr4, ETH_ALEN);
-		memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
-		break;
-	case 0:
-		memcpy(dst, hdr->addr1, ETH_ALEN);
-		memcpy(src, hdr->addr2, ETH_ALEN);
-		memcpy(bssid, hdr->addr3, ETH_ALEN);
-		break;
-	}
-
-
-	dev->last_rx = jiffies;
-
-
-	/* Nullfunc frames may have PS-bit set, so they must be passed to
-	 * hostap_handle_sta_rx() before being dropped here. */
-	if (stype != IEEE80211_STYPE_DATA &&
-	    stype != IEEE80211_STYPE_DATA_CFACK &&
-	    stype != IEEE80211_STYPE_DATA_CFPOLL &&
-	    stype != IEEE80211_STYPE_DATA_CFACKPOLL &&
-	    stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
-	    ) {
-		if (stype != IEEE80211_STYPE_NULLFUNC)
-			IEEE80211_DEBUG_DROP(
-				"RX: dropped data frame "
-				"with no data (type=0x%02x, "
-				"subtype=0x%02x, len=%d)\n",
-				type, stype, skb->len);
-		goto rx_dropped;
-	}
-	if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
-		goto rx_dropped;
-
-	ieee->NumRxDataInPeriod++;
-	ieee->NumRxOkTotal++;
-	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
-
-	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
-	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
-		goto rx_dropped;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
-	/* skb: hdr + (possibly fragmented) plaintext payload */
-	// PR: FIXME: hostap has additional conditions in the "if" below:
-	// ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
-	if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
-		int flen;
-		struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
-		IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
-
-		if (!frag_skb) {
-			IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
-					"Rx cannot get skb from fragment "
-					"cache (morefrag=%d seq=%u frag=%u)\n",
-					(fc & IEEE80211_FCTL_MOREFRAGS) != 0,
-					WLAN_GET_SEQ_SEQ(sc), frag);
-			goto rx_dropped;
-		}
-		flen = skb->len;
-		if (frag != 0)
-			flen -= hdrlen;
-
-		if (frag_skb->tail + flen > frag_skb->end) {
-			netdev_warn(ieee->dev,
-				    "host decrypted and reassembled frame did not fit skb\n");
-			ieee80211_frag_cache_invalidate(ieee, hdr);
-			goto rx_dropped;
-		}
-
-		if (frag == 0) {
-			/* copy first fragment (including full headers) into
-			 * beginning of the fragment cache skb */
-			memcpy(skb_put(frag_skb, flen), skb->data, flen);
-		} else {
-			/* append frame payload to the end of the fragment
-			 * cache skb */
-			memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
-			       flen);
-		}
-		dev_kfree_skb_any(skb);
-		skb = NULL;
-
-		if (fc & IEEE80211_FCTL_MOREFRAGS) {
-			/* more fragments expected - leave the skb in fragment
-			 * cache for now; it will be delivered to upper layers
-			 * after all fragments have been received */
-			goto rx_exit;
-		}
-
-		/* this was the last fragment and the frame will be
-		 * delivered, so remove skb from fragment cache */
-		skb = frag_skb;
-		hdr = (struct ieee80211_hdr_4addr *)skb->data;
-		ieee80211_frag_cache_invalidate(ieee, hdr);
-	}
-
-	/* skb: hdr + (possible reassembled) full MSDU payload; possibly still
-	 * encrypted/authenticated */
-	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
-	    ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
-		goto rx_dropped;
-
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
-		if (/*ieee->ieee802_1x &&*/
-		    ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
-
-#ifdef CONFIG_IEEE80211_DEBUG
-			/* pass unencrypted EAPOL frames even if encryption is
-			 * configured */
-			struct eapol *eap = (struct eapol *)(skb->data +
-				24);
-			IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
-						eap_get_type(eap->type));
-#endif
-		} else {
-			IEEE80211_DEBUG_DROP(
-				"encryption configured, but RX "
-				"frame not encrypted (SA=%pM)\n",
-				hdr->addr2);
-			goto rx_dropped;
-		}
-	}
-
-#ifdef CONFIG_IEEE80211_DEBUG
-	if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
-	    ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
-			struct eapol *eap = (struct eapol *)(skb->data +
-				24);
-			IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
-						eap_get_type(eap->type));
-	}
-#endif
-
-	if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
-	    !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
-		IEEE80211_DEBUG_DROP(
-			"dropped unencrypted RX data "
-			"frame from %pM"
-			" (drop_unencrypted=1)\n",
-			hdr->addr2);
-		goto rx_dropped;
-	}
-/*
-	if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
-		printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
-	}
-*/
-	/* skb: hdr + (possible reassembled) full plaintext payload */
-	payload = skb->data + hdrlen;
-	ethertype = (payload[6] << 8) | payload[7];
-
-
-	/* convert hdr + possible LLC headers into Ethernet header */
-	if (skb->len - hdrlen >= 8 &&
-	    ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
-	      ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-	     memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
-		/* remove RFC1042 or Bridge-Tunnel encapsulation and
-		 * replace EtherType */
-		skb_pull(skb, hdrlen + SNAP_SIZE);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	} else {
-		u16 len;
-		/* Leave Ethernet header part of hdr and full payload */
-		skb_pull(skb, hdrlen);
-		len = htons(skb->len);
-		memcpy(skb_push(skb, 2), &len, 2);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	}
-
-
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
-
-	if (skb) {
-		skb->protocol = eth_type_trans(skb, dev);
-		memset(skb->cb, 0, sizeof(skb->cb));
-		skb->dev = dev;
-		skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
-		ieee->last_rx_ps_time = jiffies;
-		netif_rx(skb);
-	}
-
- rx_exit:
-	return 1;
-
- rx_dropped:
-	stats->rx_dropped++;
-
-	/* Returning 0 indicates to caller that we have not handled the SKB--
-	 * so it is still allocated and can be used again by underlying
-	 * hardware as a DMA target */
-	return 0;
-}
-
-#define MGMT_FRAME_FIXED_PART_LENGTH		0x24
-
-static inline int ieee80211_is_ofdm_rate(u8 rate)
-{
-	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
-	case IEEE80211_OFDM_RATE_6MB:
-	case IEEE80211_OFDM_RATE_9MB:
-	case IEEE80211_OFDM_RATE_12MB:
-	case IEEE80211_OFDM_RATE_18MB:
-	case IEEE80211_OFDM_RATE_24MB:
-	case IEEE80211_OFDM_RATE_36MB:
-	case IEEE80211_OFDM_RATE_48MB:
-	case IEEE80211_OFDM_RATE_54MB:
-		return 1;
-	}
-	return 0;
-}
-
-static inline int ieee80211_SignalStrengthTranslate(int CurrSS)
-{
-	int RetSS;
-
-	// Step 1. Scale mapping.
-	if (CurrSS >= 71 && CurrSS <= 100)
-		RetSS = 90 + ((CurrSS - 70) / 3);
-	else if (CurrSS >= 41 && CurrSS <= 70)
-		RetSS = 78 + ((CurrSS - 40) / 3);
-	else if (CurrSS >= 31 && CurrSS <= 40)
-		RetSS = 66 + (CurrSS - 30);
-	else if (CurrSS >= 21 && CurrSS <= 30)
-		RetSS = 54 + (CurrSS - 20);
-	else if (CurrSS >= 5 && CurrSS <= 20)
-		RetSS = 42 + (((CurrSS - 5) * 2) / 3);
-	else if (CurrSS == 4)
-		RetSS = 36;
-	else if (CurrSS == 3)
-		RetSS = 27;
-	else if (CurrSS == 2)
-		RetSS = 18;
-	else if (CurrSS == 1)
-		RetSS = 9;
-	else
-		RetSS = CurrSS;
-
-	//RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
-	// Step 2. Smoothing.
-
-	//RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
-	return RetSS;
-}
-
-static inline void
-ieee80211_extract_country_ie(struct ieee80211_device *ieee,
-			     struct ieee80211_info_element *info_element,
-			     struct ieee80211_network *network, u8 *addr2)
-{
-	if (IS_DOT11D_ENABLE(ieee)) {
-		if (info_element->len != 0) {
-			memcpy(network->CountryIeBuf, info_element->data, info_element->len);
-			network->CountryIeLen = info_element->len;
-
-			if (!IS_COUNTRY_IE_VALID(ieee))
-				Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
-		}
-
-		//
-		// 070305, rcnjko: I update country IE watch dog here because
-		// some AP (e.g. Cisco 1242) don't include country IE in their
-		// probe response frame.
-		//
-		if (IS_EQUAL_CIE_SRC(ieee, addr2))
-			UPDATE_CIE_WATCHDOG(ieee);
-	}
-
-}
-
-/* SignalStrengthIndex is 0-100 */
-static int ieee80211_TranslateToDbm(unsigned char SignalStrengthIndex)
-{
-	unsigned char SignalPower; // in dBm.
-
-	// Translate to dBm (x=0.5y-95).
-	SignalPower = (int)SignalStrengthIndex * 7 / 10;
-	SignalPower -= 95;
-
-	return SignalPower;
-}
-inline int ieee80211_network_init(
-	struct ieee80211_device *ieee,
-	struct ieee80211_probe_response *beacon,
-	struct ieee80211_network *network,
-	struct ieee80211_rx_stats *stats)
-{
-#ifdef CONFIG_IEEE80211_DEBUG
-	char rates_str[64];
-	char *p;
-#endif
-	struct ieee80211_info_element *info_element;
-	u16 left;
-	u8 i;
-	short offset;
-	u8 curRate = 0, hOpRate = 0, curRate_ex = 0;
-
-	/* Pull out fixed field data */
-	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
-	network->capability = beacon->capability;
-	network->last_scanned = jiffies;
-	network->time_stamp[0] = beacon->time_stamp[0];
-	network->time_stamp[1] = beacon->time_stamp[1];
-	network->beacon_interval = beacon->beacon_interval;
-	/* Where to pull this? beacon->listen_interval;*/
-	network->listen_interval = 0x0A;
-	network->rates_len = network->rates_ex_len = 0;
-	network->last_associate = 0;
-	network->ssid_len = 0;
-	network->flags = 0;
-	network->atim_window = 0;
-	network->QoS_Enable = 0;
-//by amy 080312
-	network->HighestOperaRate = 0;
-//by amy 080312
-	network->Turbo_Enable = 0;
-	network->CountryIeLen = 0;
-	memset(network->CountryIeBuf, 0, MAX_IE_LEN);
-
-	if (stats->freq == IEEE80211_52GHZ_BAND) {
-		/* for A band (No DS info) */
-		network->channel = stats->received_channel;
-	} else
-		network->flags |= NETWORK_HAS_CCK;
-
-	network->wpa_ie_len = 0;
-	network->rsn_ie_len = 0;
-
-	info_element = &beacon->info_element;
-	left = stats->len - ((void *)info_element - (void *)beacon);
-	while (left >= sizeof(struct ieee80211_info_element_hdr)) {
-		if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
-			IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
-					     info_element->len + sizeof(struct ieee80211_info_element),
-					     left);
-			return 1;
-		}
-
-		switch (info_element->id) {
-		case MFIE_TYPE_SSID:
-			if (ieee80211_is_empty_essid(info_element->data,
-						     info_element->len)) {
-				network->flags |= NETWORK_EMPTY_ESSID;
-				break;
-			}
-
-			network->ssid_len = min(info_element->len,
-						(u8)IW_ESSID_MAX_SIZE);
-			memcpy(network->ssid, info_element->data, network->ssid_len);
-			if (network->ssid_len < IW_ESSID_MAX_SIZE)
-				memset(network->ssid + network->ssid_len, 0,
-				       IW_ESSID_MAX_SIZE - network->ssid_len);
-
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
-					     network->ssid, network->ssid_len);
-			break;
-
-		case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_DEBUG
-			p = rates_str;
-#endif
-			network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
-			for (i = 0; i < network->rates_len; i++) {
-				network->rates[i] = info_element->data[i];
-				curRate = network->rates[i] & 0x7f;
-				if (hOpRate < curRate)
-					hOpRate = curRate;
-#ifdef CONFIG_IEEE80211_DEBUG
-				p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
-#endif
-				if (ieee80211_is_ofdm_rate(info_element->data[i])) {
-					network->flags |= NETWORK_HAS_OFDM;
-					if (info_element->data[i] &
-					    IEEE80211_BASIC_RATE_MASK)
-						network->flags &=
-							~NETWORK_HAS_CCK;
-				}
-			}
-
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
-					     rates_str, network->rates_len);
-			break;
-
-		case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_DEBUG
-			p = rates_str;
-#endif
-			network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
-			for (i = 0; i < network->rates_ex_len; i++) {
-				network->rates_ex[i] = info_element->data[i];
-				curRate_ex = network->rates_ex[i] & 0x7f;
-				if (hOpRate < curRate_ex)
-					hOpRate = curRate_ex;
-#ifdef CONFIG_IEEE80211_DEBUG
-				p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
-#endif
-				if (ieee80211_is_ofdm_rate(info_element->data[i])) {
-					network->flags |= NETWORK_HAS_OFDM;
-					if (info_element->data[i] &
-					    IEEE80211_BASIC_RATE_MASK)
-						network->flags &=
-							~NETWORK_HAS_CCK;
-				}
-			}
-
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
-					     rates_str, network->rates_ex_len);
-			break;
-
-		case MFIE_TYPE_DS_SET:
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
-					     info_element->data[0]);
-			if (stats->freq == IEEE80211_24GHZ_BAND)
-				network->channel = info_element->data[0];
-			break;
-
-		case MFIE_TYPE_FH_SET:
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
-			break;
-
-		case MFIE_TYPE_CF_SET:
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
-			break;
-
-		case MFIE_TYPE_TIM:
-
-			if (info_element->len < 4)
-				break;
-
-			network->dtim_period = info_element->data[1];
-
-			if (ieee->state != IEEE80211_LINKED)
-				break;
-
-			network->last_dtim_sta_time[0] = jiffies;
-			network->last_dtim_sta_time[1] = stats->mac_time[1];
-
-			network->dtim_data = IEEE80211_DTIM_VALID;
-
-			if (info_element->data[0] != 0)
-				break;
-
-			if (info_element->data[2] & 1)
-				network->dtim_data |= IEEE80211_DTIM_MBCAST;
-
-			offset = (info_element->data[2] >> 1)*2;
-
-			//printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
-
-			/* add and modified for ps 2008.1.22 */
-			if (ieee->assoc_id < 8*offset ||
-				ieee->assoc_id > 8*(offset + info_element->len - 3)) {
-				break;
-			}
-
-			offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
-
-		//	printk("offset:%x data:%x, ucast:%d\n", offset,
-			//	info_element->data[3+offset] ,
-			//	info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
-
-			if (info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
-				network->dtim_data |= IEEE80211_DTIM_UCAST;
-
-			break;
-
-		case MFIE_TYPE_IBSS_SET:
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
-			break;
-
-		case MFIE_TYPE_CHALLENGE:
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
-			break;
-
-		case MFIE_TYPE_GENERIC:
-			//nic is 87B
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
-					     info_element->len);
-			if (info_element->len >= 4  &&
-			    info_element->data[0] == 0x00 &&
-			    info_element->data[1] == 0x50 &&
-			    info_element->data[2] == 0xf2 &&
-			    info_element->data[3] == 0x01) {
-				network->wpa_ie_len = min(info_element->len + 2,
-							 MAX_WPA_IE_LEN);
-				memcpy(network->wpa_ie, info_element,
-				       network->wpa_ie_len);
-			}
-
-			if (info_element->len == 7 &&
-			    info_element->data[0] == 0x00 &&
-			    info_element->data[1] == 0xe0 &&
-			    info_element->data[2] == 0x4c &&
-			    info_element->data[3] == 0x01 &&
-			    info_element->data[4] == 0x02) {
-				network->Turbo_Enable = 1;
-			}
-			if (1 == stats->nic_type) //nic 87
-				break;
-
-			if (info_element->len >= 5  &&
-			    info_element->data[0] == 0x00 &&
-			    info_element->data[1] == 0x50 &&
-			    info_element->data[2] == 0xf2 &&
-			    info_element->data[3] == 0x02 &&
-			    info_element->data[4] == 0x00) {
-				//printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
-				//WMM Information Element
-				network->wmm_info = info_element->data[6];
-				network->QoS_Enable = 1;
-			}
-
-			if (info_element->len >= 8  &&
-			    info_element->data[0] == 0x00 &&
-			    info_element->data[1] == 0x50 &&
-			    info_element->data[2] == 0xf2 &&
-			    info_element->data[3] == 0x02 &&
-			    info_element->data[4] == 0x01) {
-				// Not care about version at present.
-				//WMM Information Element
-				//printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
-				network->wmm_info = info_element->data[6];
-				//WMM Parameter Element
-				memcpy(network->wmm_param, (u8 *)(info_element->data + 8), (info_element->len - 8));
-				network->QoS_Enable = 1;
-			}
-			break;
-
-		case MFIE_TYPE_RSN:
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
-					     info_element->len);
-			network->rsn_ie_len = min(info_element->len + 2,
-						 MAX_WPA_IE_LEN);
-			memcpy(network->rsn_ie, info_element,
-			       network->rsn_ie_len);
-			break;
-		case MFIE_TYPE_COUNTRY:
-			IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
-					     info_element->len);
-//			printk("=====>Receive <%s> Country IE\n",network->ssid);
-			ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
-			break;
-		default:
-			IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
-					     info_element->id);
-			break;
-		}
-
-		left -= sizeof(struct ieee80211_info_element_hdr) +
-			info_element->len;
-		info_element = (struct ieee80211_info_element *)
-			&info_element->data[info_element->len];
-	}
-//by amy 080312
-	network->HighestOperaRate = hOpRate;
-//by amy 080312
-	network->mode = 0;
-	if (stats->freq == IEEE80211_52GHZ_BAND)
-		network->mode = IEEE_A;
-	else {
-		if (network->flags & NETWORK_HAS_OFDM)
-			network->mode |= IEEE_G;
-		if (network->flags & NETWORK_HAS_CCK)
-			network->mode |= IEEE_B;
-	}
-
-	if (network->mode == 0) {
-		IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
-				     "network.\n",
-				     escape_essid(network->ssid,
-						  network->ssid_len),
-				     network->bssid);
-		return 1;
-	}
-
-	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
-		network->flags |= NETWORK_EMPTY_ESSID;
-
-	stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
-	//stats->noise = stats->signal - stats->noise;
-	stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
-	memcpy(&network->stats, stats, sizeof(network->stats));
-
-	return 0;
-}
-
-static inline int is_same_network(struct ieee80211_network *src,
-				  struct ieee80211_network *dst,
-				  struct ieee80211_device *ieee)
-{
-	/* A network is only a duplicate if the channel, BSSID, ESSID
-	 * and the capability field (in particular IBSS and BSS) all match.
-	 * We treat all <hidden> with the same BSSID and channel
-	 * as one network */
-	return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&  //YJ,mod,080819,for hidden ap
-		//((src->ssid_len == dst->ssid_len) &&
-		(src->channel == dst->channel) &&
-		!memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
-		(!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
-		//!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
-		((src->capability & WLAN_CAPABILITY_IBSS) ==
-		(dst->capability & WLAN_CAPABILITY_IBSS)) &&
-		((src->capability & WLAN_CAPABILITY_BSS) ==
-		(dst->capability & WLAN_CAPABILITY_BSS)));
-}
-
-inline void update_network(struct ieee80211_network *dst,
-			   struct ieee80211_network *src)
-{
-	unsigned char quality = src->stats.signalstrength;
-	unsigned char signal = 0;
-	unsigned char noise = 0;
-	if (dst->stats.signalstrength > 0)
-		quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
-	signal = ieee80211_TranslateToDbm(quality);
-	//noise = signal - src->stats.noise;
-	if (dst->stats.noise > 0)
-		noise = (dst->stats.noise * 5 + src->stats.noise)/6;
-        //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
-//	printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
-	memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
-	dst->stats.signalstrength = quality;
-	dst->stats.signal = signal;
-//	printk("==================>stats.signal is %d\n",dst->stats.signal);
-	dst->stats.noise = noise;
-
-
-	dst->capability = src->capability;
-	memcpy(dst->rates, src->rates, src->rates_len);
-	dst->rates_len = src->rates_len;
-	memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
-	dst->rates_ex_len = src->rates_ex_len;
-	dst->HighestOperaRate = src->HighestOperaRate;
-	//printk("==========>in %s: src->ssid is %s,chan is %d\n",__func__,src->ssid,src->channel);
-
-	//YJ,add,080819,for hidden ap
-	if (src->ssid_len > 0) {
-		//if(src->ssid_len == 13)
-		//	printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
-		memset(dst->ssid, 0, dst->ssid_len);
-		dst->ssid_len = src->ssid_len;
-		memcpy(dst->ssid, src->ssid, src->ssid_len);
-	}
-	//YJ,add,080819,for hidden ap,end
-
-	dst->channel = src->channel;
-	dst->mode = src->mode;
-	dst->flags = src->flags;
-	dst->time_stamp[0] = src->time_stamp[0];
-	dst->time_stamp[1] = src->time_stamp[1];
-
-	dst->beacon_interval = src->beacon_interval;
-	dst->listen_interval = src->listen_interval;
-	dst->atim_window = src->atim_window;
-	dst->dtim_period = src->dtim_period;
-	dst->dtim_data = src->dtim_data;
-	dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
-	dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
-//	printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data);
-	memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
-	dst->wpa_ie_len = src->wpa_ie_len;
-	memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
-	dst->rsn_ie_len = src->rsn_ie_len;
-
-	dst->last_scanned = jiffies;
-	/* dst->last_associate is not overwritten */
-// disable QoS process now, added by David 2006/7/25
-#if 1
-	dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
-/*
-	if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
-	  memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
-	}
-*/
-	if (src->wmm_param[0].ac_aci_acm_aifsn || \
-	   src->wmm_param[1].ac_aci_acm_aifsn || \
-	   src->wmm_param[2].ac_aci_acm_aifsn || \
-	   src->wmm_param[3].ac_aci_acm_aifsn) {
-		memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
-	}
-	dst->QoS_Enable = src->QoS_Enable;
-#else
-	dst->QoS_Enable = 1;//for Rtl8187 simulation
-#endif
-	dst->SignalStrength = src->SignalStrength;
-	dst->Turbo_Enable = src->Turbo_Enable;
-	dst->CountryIeLen = src->CountryIeLen;
-	memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
-}
-
-
-inline void
-ieee80211_process_probe_response(struct ieee80211_device *ieee,
-				 struct ieee80211_probe_response *beacon,
-				 struct ieee80211_rx_stats *stats)
-{
-	struct ieee80211_network network;
-	struct ieee80211_network *target;
-	struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
-	struct ieee80211_info_element *info_element = &beacon->info_element;
-#endif
-	unsigned long flags;
-	short renew;
-	u8 wmm_info;
-	u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON) ? 1 : 0;  //YJ,add,080819,for hidden ap
-
-	memset(&network, 0, sizeof(struct ieee80211_network));
-
-	IEEE80211_DEBUG_SCAN(
-		"'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
-		escape_essid(info_element->data, info_element->len),
-		beacon->header.addr3,
-		(beacon->capability & (1<<0xf)) ? '1' : '0',
-		(beacon->capability & (1<<0xe)) ? '1' : '0',
-		(beacon->capability & (1<<0xd)) ? '1' : '0',
-		(beacon->capability & (1<<0xc)) ? '1' : '0',
-		(beacon->capability & (1<<0xb)) ? '1' : '0',
-		(beacon->capability & (1<<0xa)) ? '1' : '0',
-		(beacon->capability & (1<<0x9)) ? '1' : '0',
-		(beacon->capability & (1<<0x8)) ? '1' : '0',
-		(beacon->capability & (1<<0x7)) ? '1' : '0',
-		(beacon->capability & (1<<0x6)) ? '1' : '0',
-		(beacon->capability & (1<<0x5)) ? '1' : '0',
-		(beacon->capability & (1<<0x4)) ? '1' : '0',
-		(beacon->capability & (1<<0x3)) ? '1' : '0',
-		(beacon->capability & (1<<0x2)) ? '1' : '0',
-		(beacon->capability & (1<<0x1)) ? '1' : '0',
-		(beacon->capability & (1<<0x0)) ? '1' : '0');
-
-	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
-		IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
-				     escape_essid(info_element->data,
-						  info_element->len),
-				     beacon->header.addr3,
-				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
-				     IEEE80211_STYPE_PROBE_RESP ?
-				     "PROBE RESPONSE" : "BEACON");
-		return;
-	}
-
-	// For Asus EeePc request,
-	// (1) if wireless adapter receive get any 802.11d country code in AP beacon,
-	//	   wireless adapter should follow the country code.
-	// (2)  If there is no any country code in beacon,
-	//       then wireless adapter should do active scan from ch1~11 and
-	//       passive scan from ch12~14
-	if (ieee->bGlobalDomain) {
-		if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) {
-			// Case 1: Country code
-			if (IS_COUNTRY_IE_VALID(ieee)) {
-				if (!IsLegalChannel(ieee, network.channel)) {
-					printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
-					return;
-				}
-			}
-			// Case 2: No any country code.
-			else {
-				// Filter over channel ch12~14
-				if (network.channel > 11) {
-					printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
-					return;
-				}
-			}
-		} else {
-			// Case 1: Country code
-			if (IS_COUNTRY_IE_VALID(ieee)) {
-				if (!IsLegalChannel(ieee, network.channel)) {
-					printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network.channel);
-					return;
-				}
-			}
-			// Case 2: No any country code.
-			else {
-				// Filter over channel ch12~14
-				if (network.channel > 14) {
-					printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network.channel);
-					return;
-				}
-			}
-		}
-	}
-	/* The network parsed correctly -- so now we scan our known networks
-	 * to see if we can find it in our list.
-	 *
-	 * NOTE:  This search is definitely not optimized.  Once its doing
-	 *        the "right thing" we'll optimize it for efficiency if
-	 *        necessary */
-
-	/* Search for this entry in the list and update it if it is
-	 * already there. */
-
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if (is_same_network(&ieee->current_network, &network, ieee)) {
-		wmm_info = ieee->current_network.wmm_info;
-		//YJ,add,080819,for hidden ap
-		if (is_beacon == 0)
-			network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
-		else if (ieee->state == IEEE80211_LINKED)
-			ieee->NumRxBcnInPeriod++;
-		//YJ,add,080819,for hidden ap,end
-		//printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
-		update_network(&ieee->current_network, &network);
-	}
-
-	list_for_each_entry(target, &ieee->network_list, list) {
-		if (is_same_network(target, &network, ieee))
-			break;
-		if ((oldest == NULL) ||
-		    (target->last_scanned < oldest->last_scanned))
-			oldest = target;
-	}
-
-	/* If we didn't find a match, then get a new network slot to initialize
-	 * with this beacon's information */
-	if (&target->list == &ieee->network_list) {
-		if (list_empty(&ieee->network_free_list)) {
-			/* If there are no more slots, expire the oldest */
-			list_del(&oldest->list);
-			target = oldest;
-			IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
-					     "network list.\n",
-					     escape_essid(target->ssid,
-							  target->ssid_len),
-					     target->bssid);
-		} else {
-			/* Otherwise just pull from the free list */
-			target = list_entry(ieee->network_free_list.next,
-					    struct ieee80211_network, list);
-			list_del(ieee->network_free_list.next);
-		}
-
-
-#ifdef CONFIG_IEEE80211_DEBUG
-		IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
-				     escape_essid(network.ssid,
-						  network.ssid_len),
-				     network.bssid,
-				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
-				     IEEE80211_STYPE_PROBE_RESP ?
-				     "PROBE RESPONSE" : "BEACON");
-#endif
-
-		memcpy(target, &network, sizeof(*target));
-		list_add_tail(&target->list, &ieee->network_list);
-	} else {
-		IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
-				     escape_essid(target->ssid,
-						  target->ssid_len),
-				     target->bssid,
-				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
-				     IEEE80211_STYPE_PROBE_RESP ?
-				     "PROBE RESPONSE" : "BEACON");
-
-		/* we have an entry and we are going to update it. But this entry may
-		 * be already expired. In this case we do the same as we found a new
-		 * net and call the new_net handler
-		 */
-		renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
-		//YJ,add,080819,for hidden ap
-		if (is_beacon == 0)
-			network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
-		//if(strncmp(network.ssid, "linksys-c",9) == 0)
-		//	printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
-		if (((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
-		    && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
-		    || ((ieee->current_network.ssid_len == network.ssid_len) && (strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK))))
-			renew = 1;
-		//YJ,add,080819,for hidden ap,end
-		update_network(target, &network);
-	}
-
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-		      struct ieee80211_hdr_4addr *header,
-		      struct ieee80211_rx_stats *stats)
-{
-	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
-
-	case IEEE80211_STYPE_BEACON:
-		IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
-				     WLAN_FC_GET_STYPE(header->frame_ctl));
-		IEEE80211_DEBUG_SCAN("Beacon\n");
-		ieee80211_process_probe_response(
-			ieee, (struct ieee80211_probe_response *)header, stats);
-		break;
-
-	case IEEE80211_STYPE_PROBE_RESP:
-		IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
-				     WLAN_FC_GET_STYPE(header->frame_ctl));
-		IEEE80211_DEBUG_SCAN("Probe response\n");
-		ieee80211_process_probe_response(
-			ieee, (struct ieee80211_probe_response *)header, stats);
-		break;
-	}
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
deleted file mode 100644
index 03eb164..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ /dev/null
@@ -1,2711 +0,0 @@
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Few lines might be stolen from other part of the ieee80211
- * stack. Copyright who own it's copyright
- *
- * WPA code stolen from the ipw2200 driver.
- * Copyright who own it's copyright.
- *
- * released under the GPL
- */
-
-#include "ieee80211.h"
-
-#include <linux/random.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
-#include <linux/etherdevice.h>
-
-#include "dot11d.h"
-
-short ieee80211_is_54g(const struct ieee80211_network *net)
-{
-	return (net->rates_ex_len > 0) || (net->rates_len > 4);
-}
-
-short ieee80211_is_shortslot(const struct ieee80211_network *net)
-{
-	return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
-}
-
-/* returns the total length needed for placing the RATE MFIE
- * tag and the EXTENDED RATE MFIE tag if needed.
- * It encludes two bytes per tag for the tag itself and its len
- */
-static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
-{
-	unsigned int rate_len = 0;
-
-	if (ieee->modulation & IEEE80211_CCK_MODULATION)
-		rate_len = IEEE80211_CCK_RATE_LEN + 2;
-
-	if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-
-		rate_len += IEEE80211_OFDM_RATE_LEN + 2;
-
-	return rate_len;
-}
-
-/* place the MFIE rate, tag to the memory (double) poised.
- * Then it updates the pointer so that it points after the new MFIE tag added.
- */
-static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
-{
-	u8 *tag = *tag_p;
-
-	if (ieee->modulation & IEEE80211_CCK_MODULATION) {
-		*tag++ = MFIE_TYPE_RATES;
-		*tag++ = 4;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-	}
-
-	/* We may add an option for custom rates that specific HW might support */
-	*tag_p = tag;
-}
-
-static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
-{
-	u8 *tag = *tag_p;
-
-		if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
-		*tag++ = MFIE_TYPE_RATES_EX;
-		*tag++ = 8;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
-		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
-	}
-	/* We may add an option for custom rates that specific HW might support */
-	*tag_p = tag;
-}
-
-static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p)
-{
-	u8 *tag = *tag_p;
-
-	*tag++ = MFIE_TYPE_GENERIC; /* 0 */
-	*tag++ = 7;
-	*tag++ = 0x00;
-	*tag++ = 0x50;
-	*tag++ = 0xf2;
-	*tag++ = 0x02; /* 5 */
-	*tag++ = 0x00;
-	*tag++ = 0x01;
-#ifdef SUPPORT_USPD
-	if (ieee->current_network.wmm_info & 0x80)
-		*tag++ = 0x0f|MAX_SP_Len;
-	else
-		*tag++ = MAX_SP_Len;
-#else
-	*tag++ = MAX_SP_Len;
-#endif
-	*tag_p = tag;
-}
-
-static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
-{
-	u8 *tag = *tag_p;
-	*tag++ = MFIE_TYPE_GENERIC; /* 0 */
-	*tag++ = 7;
-	*tag++ = 0x00;
-	*tag++ = 0xe0;
-	*tag++ = 0x4c;
-	*tag++ = 0x01; /* 5 */
-	*tag++ = 0x02;
-	*tag++ = 0x11;
-	*tag++ = 0x00;
-	*tag_p = tag;
-	printk(KERN_ALERT "This is enable turbo mode IE process\n");
-}
-
-static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
-	int nh;
-	nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
-
-	ieee->mgmt_queue_head = nh;
-	ieee->mgmt_queue_ring[nh] = skb;
-}
-
-static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
-{
-	struct sk_buff *ret;
-
-	if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
-		return NULL;
-
-	ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
-
-	ieee->mgmt_queue_tail =
-		(ieee->mgmt_queue_tail + 1) % MGMT_QUEUE_NUM;
-
-	return ret;
-}
-
-static void init_mgmt_queue(struct ieee80211_device *ieee)
-{
-	ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
-}
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
-
-inline void softmac_mgmt_xmit(struct sk_buff *skb,
-			      struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
-	struct ieee80211_hdr_3addr  *header =
-		(struct ieee80211_hdr_3addr  *) skb->data;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	/* called with 2nd param 0, no mgmt lock required */
-	ieee80211_sta_wakeup(ieee, 0);
-
-	if (single) {
-		if (ieee->queue_stop) {
-			enqueue_mgmt(ieee, skb);
-		} else {
-			header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
-
-			if (ieee->seq_ctrl[0] == 0xFFF)
-				ieee->seq_ctrl[0] = 0;
-			else
-				ieee->seq_ctrl[0]++;
-
-			/* avoid watchdog triggers */
-			ieee->dev->trans_start = jiffies;
-			ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
-		}
-
-		spin_unlock_irqrestore(&ieee->lock, flags);
-	} else {
-		spin_unlock_irqrestore(&ieee->lock, flags);
-		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
-
-		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
-		if (ieee->seq_ctrl[0] == 0xFFF)
-			ieee->seq_ctrl[0] = 0;
-		else
-			ieee->seq_ctrl[0]++;
-
-		/* avoid watchdog triggers */
-		ieee->dev->trans_start = jiffies;
-		ieee->softmac_hard_start_xmit(skb, ieee->dev);
-
-		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
-	}
-}
-
-inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
-				 struct ieee80211_device *ieee)
-{
-	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
-	struct ieee80211_hdr_3addr  *header =
-		(struct ieee80211_hdr_3addr  *) skb->data;
-
-	if (single) {
-		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
-		if (ieee->seq_ctrl[0] == 0xFFF)
-			ieee->seq_ctrl[0] = 0;
-		else
-			ieee->seq_ctrl[0]++;
-
-		/* avoid watchdog triggers */
-		ieee->dev->trans_start = jiffies;
-		ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
-	} else {
-		header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
-		if (ieee->seq_ctrl[0] == 0xFFF)
-			ieee->seq_ctrl[0] = 0;
-		else
-			ieee->seq_ctrl[0]++;
-
-		/* avoid watchdog triggers */
-		ieee->dev->trans_start = jiffies;
-		ieee->softmac_hard_start_xmit(skb, ieee->dev);
-	}
-}
-
-inline struct sk_buff *
-ieee80211_disassociate_skb(struct ieee80211_network *beacon,
-			   struct ieee80211_device *ieee, u8 asRsn)
-{
-	struct sk_buff *skb;
-	struct ieee80211_disassoc_frame *disass;
-
-	skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame));
-	if (!skb)
-		return NULL;
-
-	disass = (struct ieee80211_disassoc_frame *) skb_put(skb, sizeof(struct ieee80211_disassoc_frame));
-	disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
-	disass->header.duration_id = 0;
-
-	memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
-	memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
-
-	disass->reasoncode = asRsn;
-	return skb;
-}
-
-void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, u8 asRsn)
-{
-	struct ieee80211_network *beacon = &ieee->current_network;
-	struct sk_buff *skb;
-	skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
-	if (skb)
-		softmac_mgmt_xmit(skb, ieee);
-}
-
-inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
-{
-	unsigned int len, rate_len;
-	u8 *tag;
-	struct sk_buff *skb;
-	struct ieee80211_probe_request *req;
-
-	len = ieee->current_network.ssid_len;
-
-	rate_len = ieee80211_MFIE_rate_len(ieee);
-
-	skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
-			    2 + len + rate_len);
-	if (!skb)
-		return NULL;
-
-	req = (struct ieee80211_probe_request *) skb_put(skb, sizeof(struct ieee80211_probe_request));
-	req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-	req->header.duration_id = 0; /* FIXME: is this OK ? */
-
-	memset(req->header.addr1, 0xff, ETH_ALEN);
-	memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memset(req->header.addr3, 0xff, ETH_ALEN);
-
-	tag = (u8 *) skb_put(skb, len + 2 + rate_len);
-
-	*tag++ = MFIE_TYPE_SSID;
-	*tag++ = len;
-	memcpy(tag, ieee->current_network.ssid, len);
-	tag += len;
-	ieee80211_MFIE_Brate(ieee, &tag);
-	ieee80211_MFIE_Grate(ieee, &tag);
-
-	return skb;
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
-
-static void ieee80211_send_beacon(struct ieee80211_device *ieee)
-{
-	struct sk_buff *skb;
-
-	skb = ieee80211_get_beacon_(ieee);
-
-	if (skb) {
-		softmac_mgmt_xmit(skb, ieee);
-		ieee->softmac_stats.tx_beacons++;
-		dev_kfree_skb_any(skb);
-	}
-
-	ieee->beacon_timer.expires = jiffies +
-		(MSECS(ieee->current_network.beacon_interval - 5));
-
-	if (ieee->beacon_txing)
-		add_timer(&ieee->beacon_timer);
-}
-
-
-static void ieee80211_send_beacon_cb(unsigned long _ieee)
-{
-	struct ieee80211_device *ieee =
-		(struct ieee80211_device *) _ieee;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ieee->beacon_lock, flags);
-	ieee80211_send_beacon(ieee);
-	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-static void ieee80211_send_probe(struct ieee80211_device *ieee)
-{
-	struct sk_buff *skb;
-
-	skb = ieee80211_probe_req(ieee);
-	if (skb) {
-		softmac_mgmt_xmit(skb, ieee);
-		ieee->softmac_stats.tx_probe_rq++;
-	}
-}
-
-static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
-{
-	if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
-		ieee80211_send_probe(ieee);
-		ieee80211_send_probe(ieee);
-	}
-}
-
-/* this performs syncro scan blocking the caller until all channels
- * in the allowed channel map has been checked.
- */
-static void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
-{
-	short ch = 0;
-	u8 channel_map[MAX_CHANNEL_NUMBER+1];
-	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-	down(&ieee->scan_sem);
-
-	while (1) {
-		do {
-			ch++;
-			if (ch > MAX_CHANNEL_NUMBER)
-				goto out; /* scan completed */
-
-		} while (!channel_map[ch]);
-		/* this function can be called in two situations
-		 * 1- We have switched to ad-hoc mode and we are
-		 *    performing a complete syncro scan before conclude
-		 *    there are no interesting cell and to create a
-		 *    new one. In this case the link state is
-		 *    IEEE80211_NOLINK until we found an interesting cell.
-		 *    If so the ieee8021_new_net, called by the RX path
-		 *    will set the state to IEEE80211_LINKED, so we stop
-		 *    scanning
-		 * 2- We are linked and the root uses run iwlist scan.
-		 *    So we switch to IEEE80211_LINKED_SCANNING to remember
-		 *    that we are still logically linked (not interested in
-		 *    new network events, despite for updating the net list,
-		 *    but we are temporarily 'unlinked' as the driver shall
-		 *    not filter RX frames and the channel is changing.
-		 * So the only situation in witch are interested is to check
-		 * if the state become LINKED because of the #1 situation
-		 */
-
-		if (ieee->state == IEEE80211_LINKED)
-			goto out;
-
-		ieee->set_chan(ieee->dev, ch);
-		if (channel_map[ch] == 1)
-			ieee80211_send_probe_requests(ieee);
-
-		/* this prevent excessive time wait when we
-		 * need to wait for a syncro scan to end..
-		 */
-		if (ieee->sync_scan_hurryup)
-			goto out;
-
-		msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
-	}
-out:
-	ieee->sync_scan_hurryup = 0;
-	up(&ieee->scan_sem);
-	if (IS_DOT11D_ENABLE(ieee))
-		DOT11D_ScanComplete(ieee);
-}
-
-void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
-{
-	int ch;
-	unsigned int watch_dog = 0;
-	u8 channel_map[MAX_CHANNEL_NUMBER+1];
-	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-	down(&ieee->scan_sem);
-	ch = ieee->current_network.channel;
-
-	while (1) {
-		/* this function can be called in two situations
-		 * 1- We have switched to ad-hoc mode and we are
-		 *    performing a complete syncro scan before conclude
-		 *    there are no interesting cell and to create a
-		 *    new one. In this case the link state is
-		 *    IEEE80211_NOLINK until we found an interesting cell.
-		 *    If so the ieee8021_new_net, called by the RX path
-		 *    will set the state to IEEE80211_LINKED, so we stop
-		 *    scanning
-		 * 2- We are linked and the root uses run iwlist scan.
-		 *    So we switch to IEEE80211_LINKED_SCANNING to remember
-		 *    that we are still logically linked (not interested in
-		 *    new network events, despite for updating the net list,
-		 *    but we are temporarily 'unlinked' as the driver shall
-		 *    not filter RX frames and the channel is changing.
-		 * So the only situation in witch are interested is to check
-		 * if the state become LINKED because of the #1 situation
-		 */
-		if (ieee->state == IEEE80211_LINKED)
-			goto out;
-
-		if (channel_map[ieee->current_network.channel] > 0)
-			ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
-		if (channel_map[ieee->current_network.channel] == 1)
-			ieee80211_send_probe_requests(ieee);
-
-		msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
-
-		do {
-			if (watch_dog++ >= MAX_CHANNEL_NUMBER)
-				goto out; /* scan completed */
-
-			ieee->current_network.channel = (ieee->current_network.channel + 1)%MAX_CHANNEL_NUMBER;
-		} while (!channel_map[ieee->current_network.channel]);
-	}
-out:
-	ieee->actscanning = false;
-	up(&ieee->scan_sem);
-	if (IS_DOT11D_ENABLE(ieee))
-		DOT11D_ScanComplete(ieee);
-}
-
-static void ieee80211_softmac_scan_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
-	static short watchdog;
-	u8 channel_map[MAX_CHANNEL_NUMBER+1];
-	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-	down(&ieee->scan_sem);
-
-	do {
-		ieee->current_network.channel =
-			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
-		if (watchdog++ > MAX_CHANNEL_NUMBER)
-				goto out; /* no good chans */
-	} while (!channel_map[ieee->current_network.channel]);
-
-	if (ieee->scanning == 0) {
-		printk("error out, scanning = 0\n");
-		goto out;
-	}
-	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-	if (channel_map[ieee->current_network.channel] == 1)
-		ieee80211_send_probe_requests(ieee);
-
-	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
-	up(&ieee->scan_sem);
-	return;
-out:
-	ieee->actscanning = false;
-	watchdog = 0;
-	ieee->scanning = 0;
-	up(&ieee->scan_sem);
-
-	if (IS_DOT11D_ENABLE(ieee))
-		DOT11D_ScanComplete(ieee);
-	return;
-}
-
-static void ieee80211_beacons_start(struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&ieee->beacon_lock, flags);
-
-	ieee->beacon_txing = 1;
-	ieee80211_send_beacon(ieee);
-
-	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&ieee->beacon_lock, flags);
-
-	ieee->beacon_txing = 0;
-	del_timer_sync(&ieee->beacon_timer);
-
-	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
-{
-	if (ieee->stop_send_beacons)
-		ieee->stop_send_beacons(ieee->dev);
-	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
-		ieee80211_beacons_stop(ieee);
-}
-
-void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
-{
-	if (ieee->start_send_beacons)
-		ieee->start_send_beacons(ieee->dev);
-	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
-		ieee80211_beacons_start(ieee);
-}
-
-static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
-{
-	down(&ieee->scan_sem);
-
-	if (ieee->scanning == 1) {
-		ieee->scanning = 0;
-		cancel_delayed_work(&ieee->softmac_scan_wq);
-	}
-
-	up(&ieee->scan_sem);
-}
-
-void ieee80211_stop_scan(struct ieee80211_device *ieee)
-{
-	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
-		ieee80211_softmac_stop_scan(ieee);
-	else
-		ieee->stop_scan(ieee->dev);
-}
-
-/* called with ieee->lock held */
-void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
-{
-	if (IS_DOT11D_ENABLE(ieee)) {
-		if (IS_COUNTRY_IE_VALID(ieee))
-			RESET_CIE_WATCHDOG(ieee);
-	}
-
-	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
-		if (ieee->scanning == 0) {
-			ieee->scanning = 1;
-#if 1
-			queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
-#endif
-		}
-	}else
-		ieee->start_scan(ieee->dev);
-}
-
-/* called with wx_sem held */
-void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
-{
-	if (IS_DOT11D_ENABLE(ieee)) {
-		if (IS_COUNTRY_IE_VALID(ieee))
-			RESET_CIE_WATCHDOG(ieee);
-	}
-	ieee->sync_scan_hurryup = 0;
-
-	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
-		ieee80211_softmac_scan_syncro(ieee);
-	else
-		ieee->scan_syncro(ieee->dev);
-}
-
-inline struct sk_buff *
-ieee80211_authentication_req(struct ieee80211_network *beacon,
-			     struct ieee80211_device *ieee, int challengelen)
-{
-	struct sk_buff *skb;
-	struct ieee80211_authentication *auth;
-
-	skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
-
-	if (!skb)
-		return NULL;
-
-	auth = (struct ieee80211_authentication *)
-		skb_put(skb, sizeof(struct ieee80211_authentication));
-
-	auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
-	if (challengelen)
-		auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
-
-	auth->header.duration_id = 0x013a; /* FIXME */
-
-	memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
-	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
-
-	auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
-
-	auth->transaction = cpu_to_le16(ieee->associate_seq);
-	ieee->associate_seq++;
-
-	auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
-
-	return skb;
-}
-
-static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee,
-					    u8 *dest)
-{
-	u8 *tag;
-	int beacon_size;
-	struct ieee80211_probe_response *beacon_buf;
-	struct sk_buff *skb;
-	int encrypt;
-	int atim_len, erp_len;
-	struct ieee80211_crypt_data *crypt;
-
-	char *ssid = ieee->current_network.ssid;
-	int ssid_len = ieee->current_network.ssid_len;
-	int rate_len = ieee->current_network.rates_len+2;
-	int rate_ex_len = ieee->current_network.rates_ex_len;
-	int wpa_ie_len = ieee->wpa_ie_len;
-	if (rate_ex_len > 0)
-		rate_ex_len += 2;
-
-	if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
-		atim_len = 4;
-	else
-		atim_len = 0;
-
-	if (ieee80211_is_54g(&ieee->current_network))
-		erp_len = 3;
-	else
-		erp_len = 0;
-
-	beacon_size = sizeof(struct ieee80211_probe_response)+
-		ssid_len
-		+3 /* channel */
-		+rate_len
-		+rate_ex_len
-		+atim_len
-		+wpa_ie_len
-		+erp_len;
-
-	skb = dev_alloc_skb(beacon_size);
-
-	if (!skb)
-		return NULL;
-
-	beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, beacon_size);
-
-	memcpy(beacon_buf->header.addr1, dest, ETH_ALEN);
-	memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
-
-	beacon_buf->header.duration_id = 0; /* FIXME */
-	beacon_buf->beacon_interval =
-		cpu_to_le16(ieee->current_network.beacon_interval);
-	beacon_buf->capability =
-		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
-
-	if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
-		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
-	crypt = ieee->crypt[ieee->tx_keyidx];
-
-	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
-		((0 == strcmp(crypt->ops->name, "WEP")) || wpa_ie_len);
-
-	if (encrypt)
-		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
-
-	beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
-
-	beacon_buf->info_element.id = MFIE_TYPE_SSID;
-	beacon_buf->info_element.len = ssid_len;
-
-	tag = (u8 *) beacon_buf->info_element.data;
-
-	memcpy(tag, ssid, ssid_len);
-
-	tag += ssid_len;
-
-	*(tag++) = MFIE_TYPE_RATES;
-	*(tag++) = rate_len - 2;
-	memcpy(tag, ieee->current_network.rates, rate_len-2);
-	tag += rate_len - 2;
-
-	*(tag++) = MFIE_TYPE_DS_SET;
-	*(tag++) = 1;
-	*(tag++) = ieee->current_network.channel;
-
-	if (atim_len) {
-		*(tag++) = MFIE_TYPE_IBSS_SET;
-		*(tag++) = 2;
-		*((u16 *)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
-		tag += 2;
-	}
-
-	if (erp_len) {
-		*(tag++) = MFIE_TYPE_ERP;
-		*(tag++) = 1;
-		*(tag++) = 0;
-	}
-
-	if (rate_ex_len) {
-		*(tag++) = MFIE_TYPE_RATES_EX;
-		*(tag++) = rate_ex_len-2;
-		memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
-		tag += rate_ex_len - 2;
-	}
-
-	if (wpa_ie_len)	{
-		if (ieee->iw_mode == IW_MODE_ADHOC) {
-			/* as Windows will set pairwise key same as the group
-			 * key which is not allowed in Linux, so set this for
-			 * IOT issue.
-			 */
-			memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
-		}
-
-		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
-	}
-	skb->dev = ieee->dev;
-	return skb;
-}
-
-static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
-					    u8 *dest)
-{
-	struct sk_buff *skb;
-	u8 *tag;
-
-	struct ieee80211_crypt_data *crypt;
-	struct ieee80211_assoc_response_frame *assoc;
-	short encrypt;
-
-	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
-	int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
-
-	skb = dev_alloc_skb(len);
-
-	if (!skb)
-		return NULL;
-
-	assoc = (struct ieee80211_assoc_response_frame *)
-		skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
-
-	assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
-	memcpy(assoc->header.addr1, dest, ETH_ALEN);
-	memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
-		WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
-
-	if (ieee->short_slot)
-		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
-	if (ieee->host_encrypt)
-		crypt = ieee->crypt[ieee->tx_keyidx];
-	else
-		crypt = NULL;
-
-	encrypt = (crypt && crypt->ops);
-
-	if (encrypt)
-		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
-	assoc->status = 0;
-	assoc->aid = cpu_to_le16(ieee->assoc_id);
-	if (ieee->assoc_id == 0x2007)
-		ieee->assoc_id = 0;
-	else
-		ieee->assoc_id++;
-
-	tag = (u8 *) skb_put(skb, rate_len);
-
-	ieee80211_MFIE_Brate(ieee, &tag);
-	ieee80211_MFIE_Grate(ieee, &tag);
-
-	return skb;
-}
-
-static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
-					   int status, u8 *dest)
-{
-	struct sk_buff *skb;
-	struct ieee80211_authentication *auth;
-
-	skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
-
-	if (!skb)
-		return NULL;
-
-	skb->len = sizeof(struct ieee80211_authentication);
-
-	auth = (struct ieee80211_authentication *)skb->data;
-
-	auth->status = cpu_to_le16(status);
-	auth->transaction = cpu_to_le16(2);
-	auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
-
-	memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(auth->header.addr1, dest, ETH_ALEN);
-	auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
-	return skb;
-}
-
-static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee, short pwr)
-{
-	struct sk_buff *skb;
-	struct ieee80211_hdr_3addr *hdr;
-
-	skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
-
-	if (!skb)
-		return NULL;
-
-	hdr = (struct ieee80211_hdr_3addr *)skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
-
-	memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
-	memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
-
-	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
-		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
-		(pwr ? IEEE80211_FCTL_PM:0));
-
-	return skb;
-}
-
-static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
-{
-	struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
-
-	if (buf) {
-		softmac_mgmt_xmit(buf, ieee);
-		dev_kfree_skb_any(buf);
-	}
-}
-
-static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8 *dest)
-{
-	struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
-
-	if (buf) {
-		softmac_mgmt_xmit(buf, ieee);
-		dev_kfree_skb_any(buf);
-	}
-}
-
-static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
-{
-	struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
-
-	if (buf) {
-		softmac_mgmt_xmit(buf, ieee);
-		dev_kfree_skb_any(buf);
-	}
-}
-
-inline struct sk_buff *
-ieee80211_association_req(struct ieee80211_network *beacon,
-			  struct ieee80211_device *ieee)
-{
-	struct sk_buff *skb;
-
-	struct ieee80211_assoc_request_frame *hdr;
-	u8 *tag;
-	unsigned int wpa_len = beacon->wpa_ie_len;
-#if 1
-	/* for testing purpose */
-	unsigned int rsn_len = beacon->rsn_ie_len;
-#endif
-	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
-	unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
-	unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
-
-	u8  encry_proto = ieee->wpax_type_notify & 0xff;
-
-	int len = 0;
-
-	/* [0] Notify type of encryption: WPA/WPA2
-	 * [1] pair wise type
-	 * [2] authen type
-	 */
-	if (ieee->wpax_type_set) {
-		if (IEEE_PROTO_WPA == encry_proto) {
-			rsn_len = 0;
-		} else if (IEEE_PROTO_RSN == encry_proto) {
-			wpa_len = 0;
-		}
-	}
-	len = sizeof(struct ieee80211_assoc_request_frame)+
-		+ beacon->ssid_len /* essid tagged val */
-		+ rate_len /* rates tagged val */
-		+ wpa_len
-		+ rsn_len
-		+ wmm_info_len
-		+ turbo_info_len;
-
-	skb = dev_alloc_skb(len);
-
-	if (!skb)
-		return NULL;
-
-	hdr = (struct ieee80211_assoc_request_frame *)
-		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
-
-	hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
-	hdr->header.duration_id = 37; /* FIXME */
-	memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
-	memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
-	memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN); /* for HW security */
-
-	hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
-	if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
-		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-	if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
-		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
-
-	if (ieee->short_slot)
-		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
-	hdr->listen_interval = 0xa; /* FIXME */
-
-	hdr->info_element.id = MFIE_TYPE_SSID;
-
-	hdr->info_element.len = beacon->ssid_len;
-	tag = skb_put(skb, beacon->ssid_len);
-	memcpy(tag, beacon->ssid, beacon->ssid_len);
-
-	tag = skb_put(skb, rate_len);
-
-	ieee80211_MFIE_Brate(ieee, &tag);
-	ieee80211_MFIE_Grate(ieee, &tag);
-
-	/* add rsn==0 condition for ap's mix security mode(wpa+wpa2)
-	 * choose AES encryption as default algorithm while using mixed mode.
-	 */
-
-	tag = skb_put(skb, ieee->wpa_ie_len);
-	memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
-
-	tag = skb_put(skb, wmm_info_len);
-	if (wmm_info_len)
-	  ieee80211_WMM_Info(ieee, &tag);
-
-	tag = skb_put(skb, turbo_info_len);
-	if (turbo_info_len)
-		ieee80211_TURBO_Info(ieee, &tag);
-
-	return skb;
-}
-
-void ieee80211_associate_abort(struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	ieee->associate_seq++;
-
-	/* don't scan, and avoid to have the RX path possibly
-	 * try again to associate. Even do not react to AUTH or
-	 * ASSOC response. Just wait for the retry wq to be scheduled.
-	 * Here we will check if there are good nets to associate
-	 * with, so we retry or just get back to NO_LINK and scanning
-	 */
-	if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING) {
-		IEEE80211_DEBUG_MGMT("Authentication failed\n");
-		ieee->softmac_stats.no_auth_rs++;
-	} else {
-		IEEE80211_DEBUG_MGMT("Association failed\n");
-		ieee->softmac_stats.no_ass_rs++;
-	}
-
-	ieee->state = IEEE80211_ASSOCIATING_RETRY;
-
-	queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
-
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static void ieee80211_associate_abort_cb(unsigned long dev)
-{
-	ieee80211_associate_abort((struct ieee80211_device *) dev);
-}
-
-static void ieee80211_associate_step1(struct ieee80211_device *ieee)
-{
-	struct ieee80211_network *beacon = &ieee->current_network;
-	struct sk_buff *skb;
-
-	IEEE80211_DEBUG_MGMT("Stopping scan\n");
-	ieee->softmac_stats.tx_auth_rq++;
-	skb = ieee80211_authentication_req(beacon, ieee, 0);
-	if (!skb) {
-		ieee80211_associate_abort(ieee);
-	} else {
-		ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING;
-		IEEE80211_DEBUG_MGMT("Sending authentication request\n");
-		softmac_mgmt_xmit(skb, ieee);
-		/* BUGON when you try to add_timer twice, using mod_timer may
-		 * be better.
-		 */
-		if (!timer_pending(&ieee->associate_timer)) {
-			ieee->associate_timer.expires = jiffies + (HZ / 2);
-			add_timer(&ieee->associate_timer);
-		}
-		/* If call dev_kfree_skb_any,a warning will ocur....
-		 * KERNEL: assertion (!atomic_read(&skb->users)) failed at
-		 * net/core/dev.c (1708)
-		 */
-	}
-}
-
-static void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge,
-				  int chlen)
-{
-	u8 *c;
-	struct sk_buff *skb;
-	struct ieee80211_network *beacon = &ieee->current_network;
-	del_timer_sync(&ieee->associate_timer);
-	ieee->associate_seq++;
-	ieee->softmac_stats.tx_auth_rq++;
-
-	skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
-	if (!skb)
-		ieee80211_associate_abort(ieee);
-	else {
-		c = skb_put(skb, chlen+2);
-		*(c++) = MFIE_TYPE_CHALLENGE;
-		*(c++) = chlen;
-		memcpy(c, challenge, chlen);
-
-		IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
-
-		ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr));
-
-		softmac_mgmt_xmit(skb, ieee);
-		if (!timer_pending(&ieee->associate_timer)) {
-		ieee->associate_timer.expires = jiffies + (HZ / 2);
-		add_timer(&ieee->associate_timer);
-		}
-		dev_kfree_skb_any(skb);
-	}
-	kfree(challenge);
-}
-
-static void ieee80211_associate_step2(struct ieee80211_device *ieee)
-{
-	struct sk_buff *skb;
-	struct ieee80211_network *beacon = &ieee->current_network;
-
-	del_timer_sync(&ieee->associate_timer);
-
-	IEEE80211_DEBUG_MGMT("Sending association request\n");
-	ieee->softmac_stats.tx_ass_rq++;
-	skb = ieee80211_association_req(beacon, ieee);
-	if (!skb)
-		ieee80211_associate_abort(ieee);
-	else {
-		softmac_mgmt_xmit(skb, ieee);
-		if (!timer_pending(&ieee->associate_timer)) {
-		ieee->associate_timer.expires = jiffies + (HZ / 2);
-		add_timer(&ieee->associate_timer);
-		}
-	}
-}
-
-static void ieee80211_associate_complete_wq(struct work_struct *work)
-{
-	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
-
-	printk(KERN_INFO "Associated successfully\n");
-	if (ieee80211_is_54g(&ieee->current_network) &&
-		(ieee->modulation & IEEE80211_OFDM_MODULATION)) {
-		ieee->rate = 540;
-		printk(KERN_INFO"Using G rates\n");
-	} else {
-		ieee->rate = 110;
-		printk(KERN_INFO"Using B rates\n");
-	}
-	ieee->link_change(ieee->dev);
-	notify_wx_assoc_event(ieee);
-	if (ieee->data_hard_resume)
-		ieee->data_hard_resume(ieee->dev);
-	netif_carrier_on(ieee->dev);
-}
-
-static void ieee80211_associate_complete(struct ieee80211_device *ieee)
-{
-	del_timer_sync(&ieee->associate_timer);
-
-	ieee->state = IEEE80211_LINKED;
-	IEEE80211_DEBUG_MGMT("Successfully associated\n");
-
-	queue_work(ieee->wq, &ieee->associate_complete_wq);
-}
-
-static void ieee80211_associate_procedure_wq(struct work_struct *work)
-{
-	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
-
-	ieee->sync_scan_hurryup = 1;
-	down(&ieee->wx_sem);
-
-	if (ieee->data_hard_stop)
-		ieee->data_hard_stop(ieee->dev);
-
-	ieee80211_stop_scan(ieee);
-	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
-	ieee->associate_seq = 1;
-	ieee80211_associate_step1(ieee);
-
-	up(&ieee->wx_sem);
-}
-
-inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
-				      struct ieee80211_network *net)
-{
-	u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
-	int tmp_ssid_len = 0;
-
-	short apset, ssidset, ssidbroad, apmatch, ssidmatch;
-
-	/* we are interested in new new only if we are not associated
-	 * and we are not associating / authenticating
-	 */
-	if (ieee->state != IEEE80211_NOLINK)
-		return;
-
-	if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
-		return;
-
-	if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
-		return;
-
-	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
-		/* if the user specified the AP MAC, we need also the essid
-		 * This could be obtained by beacons or, if the network does not
-		 * broadcast it, it can be put manually.
-		 */
-		apset = ieee->wap_set;
-		ssidset = ieee->ssid_set;
-		ssidbroad =  !(net->ssid_len == 0 || net->ssid[0] == '\0');
-		apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0);
-
-		if (ieee->current_network.ssid_len != net->ssid_len)
-			ssidmatch = 0;
-		else
-			ssidmatch = (0 == strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
-
-		/* if the user set the AP check if match.
-		 * if the network does not broadcast essid we check the user
-		 * supplied ANY essid
-		 * if the network does broadcast and the user does not set essid
-		 * it is OK
-		 * if the network does broadcast and the user did set essid
-		 * chech if essid match
-		 * (apset && apmatch && ((ssidset && ssidbroad && ssidmatch) ||
-		 *  (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
-		 * if the ap is not set, check that the user set the bssid and
-		 * the network does broadcast and that those two bssid matches
-		 * (!apset && ssidset && ssidbroad && ssidmatch)
-		 */
-		if ((apset && apmatch && ((ssidset && ssidbroad && ssidmatch) ||
-		     (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
-		    (!apset && ssidset && ssidbroad && ssidmatch)) {
-			/* if the essid is hidden replace it with the
-			 * essid provided by the user.
-			 */
-			if (!ssidbroad) {
-				strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
-				tmp_ssid_len = ieee->current_network.ssid_len;
-			}
-			memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
-
-			if (!ssidbroad) {
-				strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
-				ieee->current_network.ssid_len = tmp_ssid_len;
-			}
-			printk(KERN_INFO"Linking with %s: channel is %d\n", ieee->current_network.ssid, ieee->current_network.channel);
-
-			if (ieee->iw_mode == IW_MODE_INFRA) {
-				ieee->state = IEEE80211_ASSOCIATING;
-				ieee->beinretry = false;
-				queue_work(ieee->wq, &ieee->associate_procedure_wq);
-			} else {
-				if (ieee80211_is_54g(&ieee->current_network) &&
-						(ieee->modulation & IEEE80211_OFDM_MODULATION)) {
-					ieee->rate = 540;
-					printk(KERN_INFO"Using G rates\n");
-				} else {
-					ieee->rate = 110;
-					printk(KERN_INFO"Using B rates\n");
-				}
-				ieee->state = IEEE80211_LINKED;
-				ieee->beinretry = false;
-			}
-		}
-	}
-}
-
-void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-	struct ieee80211_network *target;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	list_for_each_entry(target, &ieee->network_list, list) {
-		/* if the state become different that NOLINK means
-		 * we had found what we are searching for
-		 */
-		if (ieee->state != IEEE80211_NOLINK)
-			break;
-
-		if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
-			ieee80211_softmac_new_net(ieee, target);
-	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
-{
-	struct ieee80211_authentication *a;
-	u8 *t;
-	if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
-		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
-		return 0xcafe;
-	}
-	*challenge = NULL;
-	a = (struct ieee80211_authentication *) skb->data;
-	if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
-		t = skb->data + sizeof(struct ieee80211_authentication);
-
-		if (*(t++) == MFIE_TYPE_CHALLENGE) {
-			*chlen = *(t++);
-			*challenge = kmemdup(t, *chlen, GFP_ATOMIC);
-			if (!*challenge)
-				return -ENOMEM;
-		}
-	}
-	return cpu_to_le16(a->status);
-}
-
-static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
-{
-	struct ieee80211_authentication *a;
-
-	if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
-		IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len);
-		return -1;
-	}
-	a = (struct ieee80211_authentication *) skb->data;
-
-	memcpy(dest, a->header.addr2, ETH_ALEN);
-
-	if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
-		return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
-
-	return WLAN_STATUS_SUCCESS;
-}
-
-static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb,
-			    u8 *src)
-{
-	u8 *tag;
-	u8 *skbend;
-	u8 *ssid = NULL;
-	u8 ssidlen = 0;
-
-	struct ieee80211_hdr_3addr   *header =
-		(struct ieee80211_hdr_3addr   *) skb->data;
-
-	if (skb->len < sizeof(struct ieee80211_hdr_3addr))
-		return -1; /* corrupted */
-
-	memcpy(src, header->addr2, ETH_ALEN);
-
-	skbend = (u8 *)skb->data + skb->len;
-
-	tag = skb->data + sizeof(struct ieee80211_hdr_3addr);
-
-	while (tag+1 < skbend) {
-		if (*tag == 0) {
-			ssid = tag+2;
-			ssidlen = *(tag+1);
-			break;
-		}
-		tag++; /* point to the len field */
-		tag = tag + *(tag); /* point to the last data byte of the tag */
-		tag++; /* point to the next tag */
-	}
-
-	if (ssidlen == 0)
-		return 1;
-
-	if (!ssid)
-		 return 1; /* ssid not found in tagged param */
-
-	return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
-
-}
-
-static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
-{
-	struct ieee80211_assoc_request_frame *a;
-
-	if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
-		sizeof(struct ieee80211_info_element))) {
-
-		IEEE80211_DEBUG_MGMT("invalid len in auth request:%d\n", skb->len);
-		return -1;
-	}
-
-	a = (struct ieee80211_assoc_request_frame *) skb->data;
-
-	memcpy(dest, a->header.addr2, ETH_ALEN);
-
-	return 0;
-}
-
-static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
-{
-	struct ieee80211_assoc_response_frame *a;
-	if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
-		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
-		return 0xcafe;
-	}
-
-	a = (struct ieee80211_assoc_response_frame *) skb->data;
-	*aid = le16_to_cpu(a->aid) & 0x3fff;
-	return le16_to_cpu(a->status);
-}
-
-static inline void ieee80211_rx_probe_rq(struct ieee80211_device *ieee,
-					 struct sk_buff *skb)
-{
-	u8 dest[ETH_ALEN];
-
-	ieee->softmac_stats.rx_probe_rq++;
-	if (probe_rq_parse(ieee, skb, dest)) {
-		ieee->softmac_stats.tx_probe_rs++;
-		ieee80211_resp_to_probe(ieee, dest);
-	}
-}
-
-inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee,
-				 struct sk_buff *skb)
-{
-	u8 dest[ETH_ALEN];
-	int status;
-	ieee->softmac_stats.rx_auth_rq++;
-
-	status = auth_rq_parse(skb, dest);
-	if (status != -1)
-		ieee80211_resp_to_auth(ieee, status, dest);
-}
-
-inline void
-ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
-
-	u8 dest[ETH_ALEN];
-
-	ieee->softmac_stats.rx_ass_rq++;
-	if (assoc_rq_parse(skb, dest) != -1)
-		ieee80211_resp_to_assoc_rq(ieee, dest);
-
-
-	printk(KERN_INFO"New client associated: %pM\n", dest);
-}
-
-void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
-{
-	struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
-
-	if (buf)
-		softmac_ps_mgmt_xmit(buf, ieee);
-}
-
-static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
-			     u32 *time_l)
-{
-	int timeout = 0;
-
-	u8 dtim;
-	dtim = ieee->current_network.dtim_data;
-
-	if (!(dtim & IEEE80211_DTIM_VALID))
-		return 0;
-	else
-		timeout = ieee->current_network.beacon_interval;
-
-	ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
-
-	if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps))
-		return 2;
-
-	if (!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
-		return 0;
-
-	if (!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
-		return 0;
-
-	if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
-		(ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
-		return 0;
-
-	if (time_l) {
-		*time_l = ieee->current_network.last_dtim_sta_time[0]
-			+ MSECS((ieee->current_network.beacon_interval));
-	}
-
-	if (time_h) {
-		*time_h = ieee->current_network.last_dtim_sta_time[1];
-		if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
-			*time_h += 1;
-	}
-
-	return 1;
-}
-
-static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
-{
-
-	u32 th, tl;
-	short sleep;
-
-	unsigned long flags, flags2;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if ((ieee->ps == IEEE80211_PS_DISABLED ||
-		ieee->iw_mode != IW_MODE_INFRA ||
-		ieee->state != IEEE80211_LINKED)) {
-
-		/* #warning CHECK_LOCK_HERE */
-		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
-		ieee80211_sta_wakeup(ieee, 1);
-
-		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
-	}
-
-	sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl);
-	/* 2 wake, 1 sleep, 0 do nothing */
-	if (sleep == 0)
-		goto out;
-
-	if (sleep == 1) {
-		if (ieee->sta_sleep == 1)
-			ieee->enter_sleep_state(ieee->dev, th, tl);
-
-		else if (ieee->sta_sleep == 0) {
-			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-			if (ieee->ps_is_queue_empty(ieee->dev)) {
-				ieee->sta_sleep = 2;
-
-				ieee->ps_request_tx_ack(ieee->dev);
-
-				ieee80211_sta_ps_send_null_frame(ieee, 1);
-
-				ieee->ps_th = th;
-				ieee->ps_tl = tl;
-			}
-			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
-		}
-	} else if (sleep == 2) {
-		/* #warning CHECK_LOCK_HERE */
-		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
-		ieee80211_sta_wakeup(ieee, 1);
-
-		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
-	}
-out:
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
-{
-	if (ieee->sta_sleep == 0) {
-		if (nl) {
-			ieee->ps_request_tx_ack(ieee->dev);
-			ieee80211_sta_ps_send_null_frame(ieee, 0);
-		}
-		return;
-	}
-
-	if (ieee->sta_sleep == 1)
-		ieee->sta_wake_up(ieee->dev);
-
-	ieee->sta_sleep = 0;
-
-	if (nl) {
-		ieee->ps_request_tx_ack(ieee->dev);
-		ieee80211_sta_ps_send_null_frame(ieee, 0);
-	}
-}
-
-void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
-{
-	unsigned long flags, flags2;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	if (ieee->sta_sleep == 2) {
-		/* Null frame with PS bit set */
-		if (success) {
-			ieee->sta_sleep = 1;
-			ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl);
-		}
-		/* if the card report not success we can't be sure the AP
-		 * has not RXed so we can't assume the AP believe us awake
-		 */
-	} else {
-		if ((ieee->sta_sleep == 0) && !success) {
-			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-			ieee80211_sta_ps_send_null_frame(ieee, 0);
-			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
-		}
-	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-inline int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
-				      struct sk_buff *skb,
-				      struct ieee80211_rx_stats *rx_stats,
-				      u16 type,	u16 stype)
-{
-	struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
-	u16 errcode;
-	u8 *challenge = NULL;
-	int chlen = 0;
-	int aid = 0;
-	struct ieee80211_assoc_response_frame *assoc_resp;
-	struct ieee80211_info_element *info_element;
-
-	if (!ieee->proto_started)
-		return 0;
-
-	if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
-		ieee->iw_mode == IW_MODE_INFRA &&
-		ieee->state == IEEE80211_LINKED))
-
-		tasklet_schedule(&ieee->ps_task);
-
-	if (WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_PROBE_RESP &&
-		WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_BEACON)
-		ieee->last_rx_ps_time = jiffies;
-
-	switch (WLAN_FC_GET_STYPE(header->frame_control)) {
-		case IEEE80211_STYPE_ASSOC_RESP:
-		case IEEE80211_STYPE_REASSOC_RESP:
-			IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
-					WLAN_FC_GET_STYPE(header->frame_ctl));
-			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
-				ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
-				ieee->iw_mode == IW_MODE_INFRA) {
-				errcode = assoc_parse(skb, &aid);
-				if (0 == errcode) {
-					u16 left;
-
-					ieee->state = IEEE80211_LINKED;
-					ieee->assoc_id = aid;
-					ieee->softmac_stats.rx_ass_ok++;
-					/* card type is 8187 */
-					if (1 == rx_stats->nic_type)
-						goto associate_complete;
-
-					assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
-					info_element = &assoc_resp->info_element;
-					left = skb->len - ((void *)info_element - (void *)assoc_resp);
-
-					while (left >= sizeof(struct ieee80211_info_element_hdr)) {
-						if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
-							printk(KERN_WARNING "[re]associate response error!");
-							return 1;
-						}
-						switch (info_element->id) {
-						  case MFIE_TYPE_GENERIC:
-							IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
-							if (info_element->len >= 8  &&
-							    info_element->data[0] == 0x00 &&
-							    info_element->data[1] == 0x50 &&
-							    info_element->data[2] == 0xf2 &&
-							    info_element->data[3] == 0x02 &&
-							    info_element->data[4] == 0x01) {
-								/* Not care about version at present.
-								 * WMM Parameter Element.
-								 */
-								memcpy(ieee->current_network.wmm_param, (u8 *)(info_element->data\
-									+ 8), (info_element->len - 8));
-
-								if (((ieee->current_network.wmm_info^info_element->data[6])& \
-										    0x0f) || (!ieee->init_wmmparam_flag)) {
-									/* refresh parameter element for current network
-									 * update the register parameter for hardware.
-									 */
-									ieee->init_wmmparam_flag = 1;
-									queue_work(ieee->wq, &ieee->wmm_param_update_wq);
-								}
-								/* update info_element for current network */
-								ieee->current_network.wmm_info  = info_element->data[6];
-							}
-							break;
-						  default:
-							/* nothing to do at present!!! */
-							break;
-						}
-
-						left -= sizeof(struct ieee80211_info_element_hdr) +
-							info_element->len;
-						info_element = (struct ieee80211_info_element *)
-							&info_element->data[info_element->len];
-					}
-					/* legacy AP, reset the AC_xx_param register */
-					if (!ieee->init_wmmparam_flag) {
-						queue_work(ieee->wq, &ieee->wmm_param_update_wq);
-						ieee->init_wmmparam_flag = 1; /* indicate AC_xx_param upated since last associate */
-					}
-associate_complete:
-					ieee80211_associate_complete(ieee);
-				} else {
-					ieee->softmac_stats.rx_ass_err++;
-					IEEE80211_DEBUG_MGMT(
-						"Association response status code 0x%x\n",
-						errcode);
-					ieee80211_associate_abort(ieee);
-				}
-			}
-			break;
-		case IEEE80211_STYPE_ASSOC_REQ:
-		case IEEE80211_STYPE_REASSOC_REQ:
-			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
-				ieee->iw_mode == IW_MODE_MASTER)
-
-				ieee80211_rx_assoc_rq(ieee, skb);
-			break;
-		case IEEE80211_STYPE_AUTH:
-			if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
-				if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
-				ieee->iw_mode == IW_MODE_INFRA){
-						IEEE80211_DEBUG_MGMT("Received authentication response");
-
-						errcode = auth_parse(skb, &challenge, &chlen);
-						if (0 == errcode) {
-							if (ieee->open_wep || !challenge) {
-								ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
-								ieee->softmac_stats.rx_auth_rs_ok++;
-
-								ieee80211_associate_step2(ieee);
-							} else {
-								ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
-							}
-						} else {
-							ieee->softmac_stats.rx_auth_rs_err++;
-							IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x", errcode);
-							ieee80211_associate_abort(ieee);
-						}
-
-					} else if (ieee->iw_mode == IW_MODE_MASTER) {
-						ieee80211_rx_auth_rq(ieee, skb);
-					}
-				}
-			break;
-		case IEEE80211_STYPE_PROBE_REQ:
-			if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
-				((ieee->iw_mode == IW_MODE_ADHOC ||
-				ieee->iw_mode == IW_MODE_MASTER) &&
-				ieee->state == IEEE80211_LINKED))
-
-				ieee80211_rx_probe_rq(ieee, skb);
-			break;
-		case IEEE80211_STYPE_DISASSOC:
-		case IEEE80211_STYPE_DEAUTH:
-			/* FIXME for now repeat all the association procedure
-			 * both for disassociation and deauthentication
-			 */
-			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
-				(ieee->state == IEEE80211_LINKED) &&
-				(ieee->iw_mode == IW_MODE_INFRA) &&
-				(!memcmp(header->addr2, ieee->current_network.bssid, ETH_ALEN))) {
-				ieee->state = IEEE80211_ASSOCIATING;
-				ieee->softmac_stats.reassoc++;
-
-				queue_work(ieee->wq, &ieee->associate_procedure_wq);
-			}
-			break;
-		default:
-			return -1;
-			break;
-	}
-	return 0;
-}
-
-/* following are for a simpler TX queue management.
- * Instead of using netif_[stop/wake]_queue the driver
- * will uses these two function (plus a reset one), that
- * will internally uses the kernel netif_* and takes
- * care of the ieee802.11 fragmentation.
- * So the driver receives a fragment per time and might
- * call the stop function when it want without take care
- * to have enough room to TX an entire packet.
- * This might be useful if each fragment need it's own
- * descriptor, thus just keep a total free memory > than
- * the max fragmentation threshold is not enough.. If the
- * ieee802.11 stack passed a TXB struct then you needed
- * to keep N free descriptors where
- * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
- * In this way you need just one and the 802.11 stack
- * will take care of buffering fragments and pass them to
- * to the driver later, when it wakes the queue.
- */
-
-void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
-			    struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-	int  i;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	/* called with 2nd parm 0, no tx mgmt lock required */
-	ieee80211_sta_wakeup(ieee, 0);
-
-	for (i = 0; i < txb->nr_frags; i++) {
-		if (ieee->queue_stop) {
-			ieee->tx_pending.txb = txb;
-			ieee->tx_pending.frag = i;
-			goto exit;
-		} else {
-			ieee->softmac_data_hard_start_xmit(
-				txb->fragments[i],
-				ieee->dev, ieee->rate);
-			ieee->stats.tx_packets++;
-			ieee->stats.tx_bytes += txb->fragments[i]->len;
-			ieee->dev->trans_start = jiffies;
-		}
-	}
-
-	ieee80211_txb_free(txb);
-
-	exit:
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-/* called with ieee->lock acquired */
-static void ieee80211_resume_tx(struct ieee80211_device *ieee)
-{
-	int i;
-	for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
-
-		if (ieee->queue_stop) {
-			ieee->tx_pending.frag = i;
-			return;
-		} else {
-			ieee->softmac_data_hard_start_xmit(
-				ieee->tx_pending.txb->fragments[i],
-				ieee->dev, ieee->rate);
-			ieee->stats.tx_packets++;
-			ieee->dev->trans_start = jiffies;
-		}
-	}
-
-	ieee80211_txb_free(ieee->tx_pending.txb);
-	ieee->tx_pending.txb = NULL;
-}
-
-void ieee80211_reset_queue(struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	init_mgmt_queue(ieee);
-	if (ieee->tx_pending.txb) {
-		ieee80211_txb_free(ieee->tx_pending.txb);
-		ieee->tx_pending.txb = NULL;
-	}
-	ieee->queue_stop = 0;
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-	struct sk_buff *skb;
-	struct ieee80211_hdr_3addr  *header;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	if (!ieee->queue_stop)
-		goto exit;
-
-	ieee->queue_stop = 0;
-
-	if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
-		while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) {
-			header = (struct ieee80211_hdr_3addr  *) skb->data;
-
-			header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
-			if (ieee->seq_ctrl[0] == 0xFFF)
-				ieee->seq_ctrl[0] = 0;
-			else
-				ieee->seq_ctrl[0]++;
-
-			ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
-			dev_kfree_skb_any(skb);
-		}
-	}
-	if (!ieee->queue_stop && ieee->tx_pending.txb)
-		ieee80211_resume_tx(ieee);
-
-	if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
-		ieee->softmac_stats.swtxawake++;
-		netif_wake_queue(ieee->dev);
-	}
-exit:
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
-{
-	if (!netif_queue_stopped(ieee->dev)) {
-		netif_stop_queue(ieee->dev);
-		ieee->softmac_stats.swtxstop++;
-	}
-	ieee->queue_stop = 1;
-}
-
-inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
-{
-	random_ether_addr(ieee->current_network.bssid);
-}
-
-/* called in user context only */
-void ieee80211_start_master_bss(struct ieee80211_device *ieee)
-{
-	ieee->assoc_id = 1;
-
-	if (ieee->current_network.ssid_len == 0) {
-		strncpy(ieee->current_network.ssid,
-			IEEE80211_DEFAULT_TX_ESSID,
-			IW_ESSID_MAX_SIZE);
-
-		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
-		ieee->ssid_set = 1;
-	}
-
-	memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
-
-	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-	ieee->state = IEEE80211_LINKED;
-	ieee->link_change(ieee->dev);
-	notify_wx_assoc_event(ieee);
-
-	if (ieee->data_hard_resume)
-		ieee->data_hard_resume(ieee->dev);
-
-	netif_carrier_on(ieee->dev);
-}
-
-static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
-{
-	if (ieee->raw_tx) {
-
-		if (ieee->data_hard_resume)
-			ieee->data_hard_resume(ieee->dev);
-
-		netif_carrier_on(ieee->dev);
-	}
-}
-
-static void ieee80211_start_ibss_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
-
-	/* iwconfig mode ad-hoc will schedule this and return
-	 * on the other hand this will block further iwconfig SET
-	 * operations because of the wx_sem hold.
-	 * Anyway some most set operations set a flag to speed-up
-	 * (abort) this wq (when syncro scanning) before sleeping
-	 * on the semaphore
-	 */
-
-	down(&ieee->wx_sem);
-
-	if (ieee->current_network.ssid_len == 0) {
-		strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
-		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
-		ieee->ssid_set = 1;
-	}
-
-	/* check if we have this cell in our network list */
-	ieee80211_softmac_check_all_nets(ieee);
-
-	if (ieee->state == IEEE80211_NOLINK)
-		ieee->current_network.channel = 10;
-	/* if not then the state is not linked. Maybe the user switched to
-	 * ad-hoc mode just after being in monitor mode, or just after
-	 * being very few time in managed mode (so the card have had no
-	 * time to scan all the chans..) or we have just run up the iface
-	 * after setting ad-hoc mode. So we have to give another try..
-	 * Here, in ibss mode, should be safe to do this without extra care
-	 * (in bss mode we had to make sure no-one tried to associate when
-	 * we had just checked the ieee->state and we was going to start the
-	 * scan) because in ibss mode the ieee80211_new_net function, when
-	 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
-	 * so, at worst, we waste a bit of time to initiate an unneeded syncro
-	 * scan, that will stop at the first round because it sees the state
-	 * associated.
-	 */
-	if (ieee->state == IEEE80211_NOLINK)
-		ieee80211_start_scan_syncro(ieee);
-
-	/* the network definitively is not here.. create a new cell */
-	if (ieee->state == IEEE80211_NOLINK) {
-		printk("creating new IBSS cell\n");
-		if (!ieee->wap_set)
-			ieee80211_randomize_cell(ieee);
-
-		if (ieee->modulation & IEEE80211_CCK_MODULATION) {
-			ieee->current_network.rates_len = 4;
-
-			ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
-			ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
-			ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
-			ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-
-		} else
-			ieee->current_network.rates_len = 0;
-
-		if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
-			ieee->current_network.rates_ex_len = 8;
-
-			ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
-			ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
-			ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
-			ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
-			ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
-			ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
-			ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
-			ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
-			ieee->rate = 540;
-		} else {
-			ieee->current_network.rates_ex_len = 0;
-			ieee->rate = 110;
-		}
-
-		/* By default, WMM function will be disabled in IBSS mode */
-		ieee->current_network.QoS_Enable = 0;
-
-		ieee->current_network.atim_window = 0;
-		ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
-		if (ieee->short_slot)
-			ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
-	}
-
-	ieee->state = IEEE80211_LINKED;
-	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-	ieee->link_change(ieee->dev);
-
-	notify_wx_assoc_event(ieee);
-
-	ieee80211_start_send_beacons(ieee);
-	printk(KERN_WARNING "after sending beacon packet!\n");
-
-	if (ieee->data_hard_resume)
-		ieee->data_hard_resume(ieee->dev);
-
-	netif_carrier_on(ieee->dev);
-
-	up(&ieee->wx_sem);
-}
-
-inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
-{
-	queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 100);
-}
-
-/* this is called only in user context, with wx_sem held */
-void ieee80211_start_bss(struct ieee80211_device *ieee)
-{
-	unsigned long flags;
-	/* Ref: 802.11d 11.1.3.3
-	 * STA shall not start a BSS unless properly formed Beacon frame
-	 * including a Country IE.
-	 */
-	if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
-		if (!ieee->bGlobalDomain)
-			return;
-	}
-	/* check if we have already found the net we are interested in (if any).
-	 * if not (we are disassociated and we are not
-	 * in associating / authenticating phase) start the background scanning.
-	 */
-	ieee80211_softmac_check_all_nets(ieee);
-
-	/* ensure no-one start an associating process (thus setting
-	 * the ieee->state to ieee80211_ASSOCIATING) while we
-	 * have just cheked it and we are going to enable scan.
-	 * The ieee80211_new_net function is always called with
-	 * lock held (from both ieee80211_softmac_check_all_nets and
-	 * the rx path), so we cannot be in the middle of such function
-	 */
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if (ieee->state == IEEE80211_NOLINK) {
-		ieee->actscanning = true;
-		ieee80211_rtl_start_scan(ieee);
-	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-/* called only in userspace context */
-void ieee80211_disassociate(struct ieee80211_device *ieee)
-{
-	netif_carrier_off(ieee->dev);
-
-	if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
-			ieee80211_reset_queue(ieee);
-
-	if (ieee->data_hard_stop)
-			ieee->data_hard_stop(ieee->dev);
-
-	if (IS_DOT11D_ENABLE(ieee))
-		Dot11d_Reset(ieee);
-
-	ieee->link_change(ieee->dev);
-	if (ieee->state == IEEE80211_LINKED)
-		notify_wx_assoc_event(ieee);
-	ieee->state = IEEE80211_NOLINK;
-
-}
-static void ieee80211_associate_retry_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
-	unsigned long flags;
-	down(&ieee->wx_sem);
-	if (!ieee->proto_started)
-		goto exit;
-	if (ieee->state != IEEE80211_ASSOCIATING_RETRY)
-		goto exit;
-	/* until we do not set the state to IEEE80211_NOLINK
-	* there are no possibility to have someone else trying
-	* to start an association procedure (we get here with
-	* ieee->state = IEEE80211_ASSOCIATING).
-	* When we set the state to IEEE80211_NOLINK it is possible
-	* that the RX path run an attempt to associate, but
-	* both ieee80211_softmac_check_all_nets and the
-	* RX path works with ieee->lock held so there are no
-	* problems. If we are still disassociated then start a scan.
-	* the lock here is necessary to ensure no one try to start
-	* an association procedure when we have just checked the
-	* state and we are going to start the scan.
-	*/
-	ieee->state = IEEE80211_NOLINK;
-	ieee->beinretry = true;
-	ieee80211_softmac_check_all_nets(ieee);
-
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if (ieee->state == IEEE80211_NOLINK) {
-		ieee->beinretry = false;
-		ieee->actscanning = true;
-		ieee80211_rtl_start_scan(ieee);
-	}
-	if (ieee->state == IEEE80211_NOLINK)
-		notify_wx_assoc_event(ieee);
-	spin_unlock_irqrestore(&ieee->lock, flags);
-
-exit:
-	up(&ieee->wx_sem);
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
-{
-	u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-	struct sk_buff *skb = NULL;
-	struct ieee80211_probe_response *b;
-
-	skb = ieee80211_probe_resp(ieee, broadcast_addr);
-	if (!skb)
-		return NULL;
-
-	b = (struct ieee80211_probe_response *) skb->data;
-	b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
-
-	return skb;
-}
-
-struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
-{
-	struct sk_buff *skb;
-	struct ieee80211_probe_response *b;
-
-	skb = ieee80211_get_beacon_(ieee);
-	if (!skb)
-		return NULL;
-
-	b = (struct ieee80211_probe_response *) skb->data;
-	b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
-	if (ieee->seq_ctrl[0] == 0xFFF)
-		ieee->seq_ctrl[0] = 0;
-	else
-		ieee->seq_ctrl[0]++;
-
-	return skb;
-}
-
-void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
-{
-	ieee->sync_scan_hurryup = 1;
-	down(&ieee->wx_sem);
-	ieee80211_stop_protocol(ieee);
-	up(&ieee->wx_sem);
-}
-
-void ieee80211_stop_protocol(struct ieee80211_device *ieee)
-{
-	if (!ieee->proto_started)
-		return;
-
-	ieee->proto_started = 0;
-
-	ieee80211_stop_send_beacons(ieee);
-	if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_LINKED))
-		SendDisassociation(ieee, NULL, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
-
-	del_timer_sync(&ieee->associate_timer);
-	cancel_delayed_work(&ieee->associate_retry_wq);
-	cancel_delayed_work(&ieee->start_ibss_wq);
-	ieee80211_stop_scan(ieee);
-
-	ieee80211_disassociate(ieee);
-}
-
-void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
-{
-	ieee->sync_scan_hurryup = 0;
-	down(&ieee->wx_sem);
-	ieee80211_start_protocol(ieee);
-	up(&ieee->wx_sem);
-}
-
-void ieee80211_start_protocol(struct ieee80211_device *ieee)
-{
-	short ch = 0;
-	int i = 0;
-
-	if (ieee->proto_started)
-		return;
-
-	ieee->proto_started = 1;
-
-	if (ieee->current_network.channel == 0) {
-		do {
-			ch++;
-			if (ch > MAX_CHANNEL_NUMBER)
-				return; /* no channel found */
-
-		} while (!GET_DOT11D_INFO(ieee)->channel_map[ch]);
-
-		ieee->current_network.channel = ch;
-	}
-
-	if (ieee->current_network.beacon_interval == 0)
-		ieee->current_network.beacon_interval = 100;
-	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
-	for (i = 0; i < 17; i++) {
-		ieee->last_rxseq_num[i] = -1;
-		ieee->last_rxfrag_num[i] = -1;
-		ieee->last_packet_time[i] = 0;
-	}
-
-	ieee->init_wmmparam_flag = 0; /* reinitialize AC_xx_PARAM registers. */
-
-	/* if the user set the MAC of the ad-hoc cell and then
-	 * switch to managed mode, shall we  make sure that association
-	 * attempts does not fail just because the user provide the essid
-	 * and the nic is still checking for the AP MAC ??
-	 */
-	switch (ieee->iw_mode) {
-		case IW_MODE_AUTO:
-			ieee->iw_mode = IW_MODE_INFRA;
-			/* not set break here intentionly */
-		case IW_MODE_INFRA:
-			ieee80211_start_bss(ieee);
-			break;
-
-		case IW_MODE_ADHOC:
-			ieee80211_start_ibss(ieee);
-			break;
-
-		case IW_MODE_MASTER:
-			ieee80211_start_master_bss(ieee);
-		break;
-
-		case IW_MODE_MONITOR:
-			ieee80211_start_monitor_mode(ieee);
-			break;
-
-		default:
-			ieee->iw_mode = IW_MODE_INFRA;
-			ieee80211_start_bss(ieee);
-			break;
-	}
-}
-
-#define DRV_NAME  "Ieee80211"
-void ieee80211_softmac_init(struct ieee80211_device *ieee)
-{
-	int i;
-	memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
-
-	ieee->state = IEEE80211_NOLINK;
-	ieee->sync_scan_hurryup = 0;
-	for (i = 0; i < 5; i++)
-		ieee->seq_ctrl[i] = 0;
-
-	ieee->assoc_id = 0;
-	ieee->queue_stop = 0;
-	ieee->scanning = 0;
-	ieee->softmac_features = 0; /* so IEEE2100-like driver are happy */
-	ieee->wap_set = 0;
-	ieee->ssid_set = 0;
-	ieee->proto_started = 0;
-	ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
-	ieee->rate = 3;
-	ieee->ps = IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST;
-	ieee->sta_sleep = 0;
-	ieee->bInactivePs = false;
-	ieee->actscanning = false;
-	ieee->ListenInterval = 2;
-	ieee->NumRxDataInPeriod = 0;
-	ieee->NumRxBcnInPeriod = 0;
-	ieee->NumRxOkTotal = 0;
-	ieee->NumRxUnicast = 0; /* for keep alive */
-	ieee->beinretry = false;
-	ieee->bHwRadioOff = false;
-
-	init_mgmt_queue(ieee);
-
-	ieee->tx_pending.txb = NULL;
-
-	init_timer(&ieee->associate_timer);
-	ieee->associate_timer.data = (unsigned long)ieee;
-	ieee->associate_timer.function = ieee80211_associate_abort_cb;
-
-	init_timer(&ieee->beacon_timer);
-	ieee->beacon_timer.data = (unsigned long) ieee;
-	ieee->beacon_timer.function = ieee80211_send_beacon_cb;
-
-	ieee->wq = create_workqueue(DRV_NAME);
-
-	INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *) ieee80211_start_ibss_wq);
-	INIT_WORK(&ieee->associate_complete_wq, (void *) ieee80211_associate_complete_wq);
-	INIT_WORK(&ieee->associate_procedure_wq, (void *) ieee80211_associate_procedure_wq);
-	INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *) ieee80211_softmac_scan_wq);
-	INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *) ieee80211_associate_retry_wq);
-	INIT_WORK(&ieee->wx_sync_scan_wq, (void *) ieee80211_wx_sync_scan_wq);
-
-	sema_init(&ieee->wx_sem, 1);
-	sema_init(&ieee->scan_sem, 1);
-
-	spin_lock_init(&ieee->mgmt_tx_lock);
-	spin_lock_init(&ieee->beacon_lock);
-
-	tasklet_init(&ieee->ps_task,
-	     (void(*)(unsigned long)) ieee80211_sta_ps,
-	     (unsigned long)ieee);
-	ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
-}
-
-void ieee80211_softmac_free(struct ieee80211_device *ieee)
-{
-	down(&ieee->wx_sem);
-
-	del_timer_sync(&ieee->associate_timer);
-	cancel_delayed_work(&ieee->associate_retry_wq);
-
-	/* add for RF power on power of */
-	cancel_delayed_work(&ieee->GPIOChangeRFWorkItem);
-
-	destroy_workqueue(ieee->wq);
-	kfree(ieee->pDot11dInfo);
-	up(&ieee->wx_sem);
-}
-
-/* Start of WPA code. This is stolen from the ipw2200 driver  */
-static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
-{
-	/* This is called when wpa_supplicant loads and closes the driver
-	 * interface. */
-	printk("%s WPA\n", value ? "enabling" : "disabling");
-	ieee->wpa_enabled = value;
-	return 0;
-}
-
-static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie,
-			       int wpa_ie_len)
-{
-	/* make sure WPA is enabled */
-	ieee80211_wpa_enable(ieee, 1);
-
-	ieee80211_disassociate(ieee);
-}
-
-static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command,
-			      int reason)
-{
-	int ret = 0;
-
-	switch (command) {
-	case IEEE_MLME_STA_DEAUTH:
-		/* silently ignore */
-		break;
-
-	case IEEE_MLME_STA_DISASSOC:
-		ieee80211_disassociate(ieee);
-		break;
-
-	default:
-		printk("Unknown MLME request: %d\n", command);
-		ret = -EOPNOTSUPP;
-	}
-
-	return ret;
-}
-
-static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
-				    struct ieee_param *param, int plen)
-{
-	u8 *buf;
-
-	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
-	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
-		return -EINVAL;
-
-	if (param->u.wpa_ie.len) {
-		buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
-			      GFP_KERNEL);
-		if (buf == NULL)
-			return -ENOMEM;
-
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = buf;
-		ieee->wpa_ie_len = param->u.wpa_ie.len;
-	} else {
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = NULL;
-		ieee->wpa_ie_len = 0;
-	}
-
-	ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
-	return 0;
-}
-
-#define AUTH_ALG_OPEN_SYSTEM			0x1
-#define AUTH_ALG_SHARED_KEY			0x2
-
-static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
-{
-	struct ieee80211_security sec = {
-		.flags = SEC_AUTH_MODE,
-	};
-	int ret = 0;
-
-	if (value & AUTH_ALG_SHARED_KEY) {
-		sec.auth_mode = WLAN_AUTH_SHARED_KEY;
-		ieee->open_wep = 0;
-	} else {
-		sec.auth_mode = WLAN_AUTH_OPEN;
-		ieee->open_wep = 1;
-	}
-
-	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
-	else
-		ret = -EOPNOTSUPP;
-
-	return ret;
-}
-
-static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name,
-				   u32 value)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	switch (name) {
-	case IEEE_PARAM_WPA_ENABLED:
-		ret = ieee80211_wpa_enable(ieee, value);
-		break;
-
-	case IEEE_PARAM_TKIP_COUNTERMEASURES:
-		ieee->tkip_countermeasures = value;
-		break;
-
-	case IEEE_PARAM_DROP_UNENCRYPTED: {
-		/* HACK:
-		 *
-		 * wpa_supplicant calls set_wpa_enabled when the driver
-		 * is loaded and unloaded, regardless of if WPA is being
-		 * used.  No other calls are made which can be used to
-		 * determine if encryption will be used or not prior to
-		 * association being expected.  If encryption is not being
-		 * used, drop_unencrypted is set to false, else true -- we
-		 * can use this to determine if the CAP_PRIVACY_ON bit should
-		 * be set.
-		 */
-		struct ieee80211_security sec = {
-			.flags = SEC_ENABLED,
-			.enabled = value,
-		};
-		ieee->drop_unencrypted = value;
-		/* We only change SEC_LEVEL for open mode. Others
-		 * are set by ipw_wpa_set_encryption.
-		 */
-		if (!value) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_0;
-		} else {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_1;
-		}
-		if (ieee->set_security)
-			ieee->set_security(ieee->dev, &sec);
-		break;
-	}
-
-	case IEEE_PARAM_PRIVACY_INVOKED:
-		ieee->privacy_invoked = value;
-		break;
-	case IEEE_PARAM_AUTH_ALGS:
-		ret = ieee80211_wpa_set_auth_algs(ieee, value);
-		break;
-	case IEEE_PARAM_IEEE_802_1X:
-		ieee->ieee802_1x = value;
-		break;
-	case IEEE_PARAM_WPAX_SELECT:
-		spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
-		ieee->wpax_type_set = 1;
-		ieee->wpax_type_notify = value;
-		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
-		break;
-	default:
-		printk("Unknown WPA param: %d\n", name);
-		ret = -EOPNOTSUPP;
-	}
-
-	return ret;
-}
-
-/* implementation borrowed from hostap driver */
-
-static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
-					struct ieee_param *param, int param_len)
-{
-	int ret = 0;
-
-	struct ieee80211_crypto_ops *ops;
-	struct ieee80211_crypt_data **crypt;
-
-	struct ieee80211_security sec = {
-		.flags = 0,
-	};
-
-	param->u.crypt.err = 0;
-	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
-	if (param_len !=
-	    (int) ((char *) param->u.crypt.key - (char *) param) +
-	    param->u.crypt.key_len) {
-		printk("Len mismatch %d, %d\n", param_len,
-			       param->u.crypt.key_len);
-		return -EINVAL;
-	}
-	if (is_broadcast_ether_addr(param->sta_addr)) {
-		if (param->u.crypt.idx >= WEP_KEYS)
-			return -EINVAL;
-		crypt = &ieee->crypt[param->u.crypt.idx];
-	} else {
-		return -EINVAL;
-	}
-
-	if (strcmp(param->u.crypt.alg, "none") == 0) {
-		if (crypt) {
-			sec.enabled = 0;
-			/* FIXME FIXME */
-			sec.level = SEC_LEVEL_0;
-			sec.flags |= SEC_ENABLED | SEC_LEVEL;
-			ieee80211_crypt_delayed_deinit(ieee, crypt);
-		}
-		goto done;
-	}
-	sec.enabled = 1;
-	/* FIXME FIXME */
-	sec.flags |= SEC_ENABLED;
-
-	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
-	if (!(ieee->host_encrypt || ieee->host_decrypt) &&
-	    strcmp(param->u.crypt.alg, "TKIP"))
-		goto skip_host_crypt;
-
-	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	if (ops == NULL) {
-		printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
-		param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
-		ret = -EINVAL;
-		goto done;
-	}
-
-	if (*crypt == NULL || (*crypt)->ops != ops) {
-		struct ieee80211_crypt_data *new_crypt;
-
-		ieee80211_crypt_delayed_deinit(ieee, crypt);
-
-		new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
-		if (new_crypt == NULL) {
-			ret = -ENOMEM;
-			goto done;
-		}
-		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
-		new_crypt->ops = ops;
-		if (new_crypt->ops)
-			new_crypt->priv =
-				new_crypt->ops->init(param->u.crypt.idx);
-
-		if (new_crypt->priv == NULL) {
-			kfree(new_crypt);
-			param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
-			ret = -EINVAL;
-			goto done;
-		}
-
-		*crypt = new_crypt;
-	}
-
-	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
-	    (*crypt)->ops->set_key(param->u.crypt.key,
-				   param->u.crypt.key_len, param->u.crypt.seq,
-				   (*crypt)->priv) < 0) {
-		printk("key setting failed\n");
-		param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
-		ret = -EINVAL;
-		goto done;
-	}
-
- skip_host_crypt:
-	if (param->u.crypt.set_tx) {
-		ieee->tx_keyidx = param->u.crypt.idx;
-		sec.active_key = param->u.crypt.idx;
-		sec.flags |= SEC_ACTIVE_KEY;
-	} else
-		sec.flags &= ~SEC_ACTIVE_KEY;
-
-	if (param->u.crypt.alg != NULL) {
-		memcpy(sec.keys[param->u.crypt.idx],
-		       param->u.crypt.key,
-		       param->u.crypt.key_len);
-		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
-		sec.flags |= (1 << param->u.crypt.idx);
-
-		if (strcmp(param->u.crypt.alg, "WEP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_1;
-		} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_2;
-		} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_3;
-		}
-	}
- done:
-	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
-
-	/* Do not reset port if card is in Managed mode since resetting will
-	 * generate new IEEE 802.11 authentication which may end up in looping
-	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
-	 * configuration (for example... Prism2), implement the reset_port in
-	 * the callbacks structures used to initialize the 802.11 stack. */
-	if (ieee->reset_on_keychange &&
-	    ieee->iw_mode != IW_MODE_INFRA &&
-	    ieee->reset_port &&
-	    ieee->reset_port(ieee->dev)) {
-		printk("reset_port failed\n");
-		param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
-				   struct iw_point *p)
-{
-	struct ieee_param *param;
-	int ret = 0;
-
-	down(&ieee->wx_sem);
-
-	if (p->length < sizeof(struct ieee_param) || !p->pointer) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	param = memdup_user(p->pointer, p->length);
-	if (IS_ERR(param)) {
-		ret = PTR_ERR(param);
-		goto out;
-	}
-
-	switch (param->cmd) {
-	case IEEE_CMD_SET_WPA_PARAM:
-		ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
-					param->u.wpa_param.value);
-		break;
-	case IEEE_CMD_SET_WPA_IE:
-		ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
-		break;
-	case IEEE_CMD_SET_ENCRYPTION:
-		ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
-		break;
-	case IEEE_CMD_MLME:
-		ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
-				   param->u.mlme.reason_code);
-		break;
-	default:
-		printk("Unknown WPA supplicant request: %d\n", param->cmd);
-		ret = -EOPNOTSUPP;
-		break;
-	}
-
-	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
-		ret = -EFAULT;
-
-	kfree(param);
-out:
-	up(&ieee->wx_sem);
-
-	return ret;
-}
-
-void notify_wx_assoc_event(struct ieee80211_device *ieee)
-{
-	union iwreq_data wrqu;
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	if (ieee->state == IEEE80211_LINKED)
-		memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
-	else
-		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
-	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
deleted file mode 100644
index 46f3564..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Some pieces of code might be stolen from ipw2100 driver
- * copyright of who own it's copyright ;-)
- *
- * PS wx handler mostly stolen from hostap, copyright who
- * own it's copyright ;-)
- *
- * released under the GPL
- */
-
-
-#include <linux/etherdevice.h>
-
-#include "ieee80211.h"
-
-/* FIXME: add A freqs */
-
-const long ieee80211_wlan_frequencies[] = {
-	2412, 2417, 2422, 2427,
-	2432, 2437, 2442, 2447,
-	2452, 2457, 2462, 2467,
-	2472, 2484
-};
-
-
-int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
-			  struct iw_request_info *a, union iwreq_data *wrqu,
-			  char *b)
-{
-	int ret;
-	struct iw_freq *fwrq = &wrqu->freq;
-//	printk("in %s\n",__func__);
-	down(&ieee->wx_sem);
-
-	if (ieee->iw_mode == IW_MODE_INFRA) {
-		ret = -EOPNOTSUPP;
-		goto out;
-	}
-
-	/* if setting by freq convert to channel */
-	if (fwrq->e == 1) {
-		if ((fwrq->m >= (int) 2.412e8 &&
-		     fwrq->m <= (int) 2.487e8)) {
-			int f = fwrq->m / 100000;
-			int c = 0;
-
-			while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
-				c++;
-
-			/* hack to fall through */
-			fwrq->e = 0;
-			fwrq->m = c + 1;
-		}
-	}
-
-	if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
-		ret = -EOPNOTSUPP;
-		goto out;
-
-	} else { /* Set the channel */
-
-
-		ieee->current_network.channel = fwrq->m;
-		ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
-		if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
-			if (ieee->state == IEEE80211_LINKED) {
-				ieee80211_stop_send_beacons(ieee);
-				ieee80211_start_send_beacons(ieee);
-			}
-	}
-
-	ret = 0;
-out:
-	up(&ieee->wx_sem);
-	return ret;
-}
-
-
-int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
-			  struct iw_request_info *a, union iwreq_data *wrqu,
-			  char *b)
-{
-	struct iw_freq *fwrq = &wrqu->freq;
-
-	if (ieee->current_network.channel == 0)
-		return -1;
-
-	fwrq->m = ieee->current_network.channel;
-	fwrq->e = 0;
-
-	return 0;
-}
-
-int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
-			 struct iw_request_info *info, union iwreq_data *wrqu,
-			 char *extra)
-{
-	unsigned long flags;
-
-	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
-	if (ieee->iw_mode == IW_MODE_MONITOR)
-		return -1;
-
-	/* We want avoid to give to the user inconsistent infos*/
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if (ieee->state != IEEE80211_LINKED &&
-		ieee->state != IEEE80211_LINKED_SCANNING &&
-		ieee->wap_set == 0)
-
-		memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
-	else
-		memcpy(wrqu->ap_addr.sa_data,
-		       ieee->current_network.bssid, ETH_ALEN);
-
-	spin_unlock_irqrestore(&ieee->lock, flags);
-
-	return 0;
-}
-
-
-int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
-			 struct iw_request_info *info, union iwreq_data *awrq,
-			 char *extra)
-{
-
-	int ret = 0;
-	unsigned long flags;
-
-	short ifup = ieee->proto_started;//dev->flags & IFF_UP;
-	struct sockaddr *temp = (struct sockaddr *)awrq;
-
-	//printk("=======Set WAP:");
-	ieee->sync_scan_hurryup = 1;
-
-	down(&ieee->wx_sem);
-	/* use ifconfig hw ether */
-	if (ieee->iw_mode == IW_MODE_MASTER) {
-		ret = -1;
-		goto out;
-	}
-
-	if (temp->sa_family != ARPHRD_ETHER) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	if (ifup)
-		ieee80211_stop_protocol(ieee);
-
-	/* just to avoid to give inconsistent infos in the
-	 * get wx method. not really needed otherwise
-	 */
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
-	ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
-	//printk(" %x:%x:%x:%x:%x:%x\n", ieee->current_network.bssid[0],ieee->current_network.bssid[1],ieee->current_network.bssid[2],ieee->current_network.bssid[3],ieee->current_network.bssid[4],ieee->current_network.bssid[5]);
-
-	spin_unlock_irqrestore(&ieee->lock, flags);
-
-	if (ifup)
-		ieee80211_start_protocol(ieee);
-
-out:
-	up(&ieee->wx_sem);
-	return ret;
-}
-
-int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
-			   struct iw_request_info *a, union iwreq_data *wrqu,
-			   char *b)
-{
-	int len, ret = 0;
-	unsigned long flags;
-
-	if (ieee->iw_mode == IW_MODE_MONITOR)
-		return -1;
-
-	/* We want avoid to give to the user inconsistent infos*/
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if (ieee->current_network.ssid[0] == '\0' ||
-		ieee->current_network.ssid_len == 0){
-		ret = -1;
-		goto out;
-	}
-
-	if (ieee->state != IEEE80211_LINKED &&
-		ieee->state != IEEE80211_LINKED_SCANNING &&
-		ieee->ssid_set == 0){
-		ret = -1;
-		goto out;
-	}
-	len = ieee->current_network.ssid_len;
-	wrqu->essid.length = len;
-	strncpy(b, ieee->current_network.ssid, len);
-	wrqu->essid.flags = 1;
-
-out:
-	spin_unlock_irqrestore(&ieee->lock, flags);
-
-	return ret;
-
-}
-
-int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
-			  struct iw_request_info *info, union iwreq_data *wrqu,
-			  char *extra)
-{
-
-	u32 target_rate = wrqu->bitrate.value;
-
-	//added by lizhaoming for auto mode
-	if (target_rate == -1)
-		ieee->rate = 110;
-	else
-		ieee->rate = target_rate/100000;
-
-	//FIXME: we might want to limit rate also in management protocols.
-	return 0;
-}
-
-
-
-int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
-			  struct iw_request_info *info, union iwreq_data *wrqu,
-			  char *extra)
-{
-
-	wrqu->bitrate.value = ieee->rate * 100000;
-
-	return 0;
-}
-
-int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
-			  struct iw_request_info *a, union iwreq_data *wrqu,
-			  char *b)
-{
-
-	ieee->sync_scan_hurryup = 1;
-
-	down(&ieee->wx_sem);
-
-	if (wrqu->mode == ieee->iw_mode)
-		goto out;
-
-	if (wrqu->mode == IW_MODE_MONITOR)
-		ieee->dev->type = ARPHRD_IEEE80211;
-	else
-		ieee->dev->type = ARPHRD_ETHER;
-
-	if (!ieee->proto_started) {
-		ieee->iw_mode = wrqu->mode;
-	} else {
-		ieee80211_stop_protocol(ieee);
-		ieee->iw_mode = wrqu->mode;
-		ieee80211_start_protocol(ieee);
-	}
-
-out:
-	up(&ieee->wx_sem);
-	return 0;
-}
-
-
-void ieee80211_wx_sync_scan_wq(struct work_struct *work)
-{
-	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
-	short chan;
-
-	chan = ieee->current_network.channel;
-
-	if (ieee->data_hard_stop)
-		ieee->data_hard_stop(ieee->dev);
-
-	ieee80211_stop_send_beacons(ieee);
-
-	ieee->state = IEEE80211_LINKED_SCANNING;
-	ieee->link_change(ieee->dev);
-
-	ieee80211_start_scan_syncro(ieee);
-
-	ieee->set_chan(ieee->dev, chan);
-
-	ieee->state = IEEE80211_LINKED;
-	ieee->link_change(ieee->dev);
-
-	if (ieee->data_hard_resume)
-		ieee->data_hard_resume(ieee->dev);
-
-	if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
-		ieee80211_start_send_beacons(ieee);
-
-	//YJ,add,080828, In prevent of lossing ping packet during scanning
-	//ieee80211_sta_ps_send_null_frame(ieee, false);
-	//YJ,add,080828,end
-
-	up(&ieee->wx_sem);
-
-}
-
-int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
-			  struct iw_request_info *a, union iwreq_data *wrqu,
-			  char *b)
-{
-	int ret = 0;
-
-	down(&ieee->wx_sem);
-
-	if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
-		ret = -1;
-		goto out;
-	}
-	//YJ,add,080828
-	//In prevent of lossing ping packet during scanning
-	//ieee80211_sta_ps_send_null_frame(ieee, true);
-	//YJ,add,080828,end
-
-	if (ieee->state == IEEE80211_LINKED) {
-		queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
-		/* intentionally forget to up sem */
-		return 0;
-	}
-
-out:
-	up(&ieee->wx_sem);
-	return ret;
-}
-
-int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
-			   struct iw_request_info *a, union iwreq_data *wrqu,
-			   char *extra)
-{
-
-	int ret = 0, len;
-	short proto_started;
-	unsigned long flags;
-
-	ieee->sync_scan_hurryup = 1;
-
-	down(&ieee->wx_sem);
-
-	proto_started = ieee->proto_started;
-
-	if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
-		ret = -E2BIG;
-		goto out;
-	}
-
-	if (ieee->iw_mode == IW_MODE_MONITOR) {
-		ret = -1;
-		goto out;
-	}
-
-	if (proto_started)
-		ieee80211_stop_protocol(ieee);
-
-	/* this is just to be sure that the GET wx callback
-	 * has consistent infos. not needed otherwise
-	 */
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if (wrqu->essid.flags && wrqu->essid.length) {
-//YJ,modified,080819
-		len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE;
-		memset(ieee->current_network.ssid, 0, ieee->current_network.ssid_len); //YJ,add,080819
-		strncpy(ieee->current_network.ssid, extra, len);
-		ieee->current_network.ssid_len = len;
-		ieee->ssid_set = 1;
-//YJ,modified,080819,end
-
-		//YJ,add,080819,for hidden ap
-		if (len == 0) {
-			memset(ieee->current_network.bssid, 0, ETH_ALEN);
-			ieee->current_network.capability = 0;
-		}
-		//YJ,add,080819,for hidden ap,end
-	} else {
-		ieee->ssid_set = 0;
-		ieee->current_network.ssid[0] = '\0';
-		ieee->current_network.ssid_len = 0;
-	}
-	//printk("==========set essid %s!\n",ieee->current_network.ssid);
-	spin_unlock_irqrestore(&ieee->lock, flags);
-
-	if (proto_started)
-		ieee80211_start_protocol(ieee);
-out:
-	up(&ieee->wx_sem);
-	return ret;
-}
-
-int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
-			  struct iw_request_info *a, union iwreq_data *wrqu,
-			  char *b)
-{
-
-	wrqu->mode = ieee->iw_mode;
-	return 0;
-}
-
-int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
-			   struct iw_request_info *info, union iwreq_data *wrqu,
-			   char *extra)
-{
-
-	int *parms = (int *)extra;
-	int enable = (parms[0] > 0);
-	short prev = ieee->raw_tx;
-
-	down(&ieee->wx_sem);
-
-	if (enable)
-		ieee->raw_tx = 1;
-	else
-		ieee->raw_tx = 0;
-
-	netdev_info(ieee->dev, "raw TX is %s\n",
-		    ieee->raw_tx ? "enabled" : "disabled");
-
-	if (ieee->iw_mode == IW_MODE_MONITOR) {
-		if (prev == 0 && ieee->raw_tx) {
-			if (ieee->data_hard_resume)
-				ieee->data_hard_resume(ieee->dev);
-
-			netif_carrier_on(ieee->dev);
-		}
-
-		if (prev && ieee->raw_tx == 1)
-			netif_carrier_off(ieee->dev);
-	}
-
-	up(&ieee->wx_sem);
-
-	return 0;
-}
-
-int ieee80211_wx_get_name(struct ieee80211_device *ieee,
-			  struct iw_request_info *info, union iwreq_data *wrqu,
-			  char *extra)
-{
-	strlcpy(wrqu->name, "802.11", IFNAMSIZ);
-	if (ieee->modulation & IEEE80211_CCK_MODULATION) {
-		strlcat(wrqu->name, "b", IFNAMSIZ);
-		if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-			strlcat(wrqu->name, "/g", IFNAMSIZ);
-	} else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-		strlcat(wrqu->name, "g", IFNAMSIZ);
-
-	if ((ieee->state == IEEE80211_LINKED) ||
-		(ieee->state == IEEE80211_LINKED_SCANNING))
-		strlcat(wrqu->name, "  link", IFNAMSIZ);
-	else if (ieee->state != IEEE80211_NOLINK)
-		strlcat(wrqu->name, " .....", IFNAMSIZ);
-
-
-	return 0;
-}
-
-
-/* this is mostly stolen from hostap */
-int ieee80211_wx_set_power(struct ieee80211_device *ieee,
-			   struct iw_request_info *info, union iwreq_data *wrqu,
-			   char *extra)
-{
-	int ret = 0;
-
-	if ((!ieee->sta_wake_up) ||
-	    (!ieee->ps_request_tx_ack) ||
-	    (!ieee->enter_sleep_state) ||
-	    (!ieee->ps_is_queue_empty)) {
-
-		printk("ERROR. PS mode tried to be use but driver missed a callback\n\n");
-
-		return -1;
-	}
-
-	down(&ieee->wx_sem);
-
-	if (wrqu->power.disabled) {
-		ieee->ps = IEEE80211_PS_DISABLED;
-
-		goto exit;
-	}
-	switch (wrqu->power.flags & IW_POWER_MODE) {
-	case IW_POWER_UNICAST_R:
-		ieee->ps = IEEE80211_PS_UNICAST;
-
-		break;
-	case IW_POWER_ALL_R:
-		ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
-		break;
-
-	case IW_POWER_ON:
-		ieee->ps = IEEE80211_PS_DISABLED;
-		break;
-
-	default:
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	if (wrqu->power.flags & IW_POWER_TIMEOUT) {
-
-		ieee->ps_timeout = wrqu->power.value / 1000;
-		printk("Timeout %d\n", ieee->ps_timeout);
-	}
-
-	if (wrqu->power.flags & IW_POWER_PERIOD) {
-
-		ret = -EOPNOTSUPP;
-		goto exit;
-		//wrq->value / 1024;
-
-	}
-exit:
-	up(&ieee->wx_sem);
-	return ret;
-
-}
-
-/* this is stolen from hostap */
-int ieee80211_wx_get_power(struct ieee80211_device *ieee,
-			   struct iw_request_info *info, union iwreq_data *wrqu,
-			   char *extra)
-{
-	int ret = 0;
-
-	down(&ieee->wx_sem);
-
-	if (ieee->ps == IEEE80211_PS_DISABLED) {
-		wrqu->power.disabled = 1;
-		goto exit;
-	}
-
-	wrqu->power.disabled = 0;
-
-//	if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
-		wrqu->power.flags = IW_POWER_TIMEOUT;
-		wrqu->power.value = ieee->ps_timeout * 1000;
-//	} else {
-//		ret = -EOPNOTSUPP;
-//		goto exit;
-		//wrqu->power.flags = IW_POWER_PERIOD;
-		//wrqu->power.value = ieee->current_network.dtim_period *
-		//	ieee->current_network.beacon_interval * 1024;
-//	}
-
-
-	if (ieee->ps & IEEE80211_PS_MBCAST)
-		wrqu->power.flags |= IW_POWER_ALL_R;
-	else
-		wrqu->power.flags |= IW_POWER_UNICAST_R;
-
-exit:
-	up(&ieee->wx_sem);
-	return ret;
-
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
deleted file mode 100644
index 0dc5ae4..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/******************************************************************************
-
-  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of version 2 of the GNU General Public License 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.
-
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-
-  Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************
-
-  Few modifications for Realtek's Wi-Fi drivers by
-  Andrea Merello <andrea.merello@gmail.com>
-
-  A special thanks goes to Realtek for their support !
-
-******************************************************************************/
-
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <linux/if_vlan.h>
-
-#include "ieee80211.h"
-
-
-/*
-
-
-802.11 Data Frame
-
-
-802.11 frame_contorl for data frames - 2 bytes
-     ,-----------------------------------------------------------------------------------------.
-bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
-     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
-     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
-     |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
-     '-----------------------------------------------------------------------------------------'
-		                                    /\
-                                                    |
-802.11 Data Frame                                   |
-           ,--------- 'ctrl' expands to >-----------'
-          |
-      ,--'---,-------------------------------------------------------------.
-Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
-      |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
-      |      | tion | (BSSID) |         |         | ence |  data   |      |
-      `--------------------------------------------------|         |------'
-Total: 28 non-data bytes                                 `----.----'
-                                                              |
-       .- 'Frame data' expands to <---------------------------'
-       |
-       V
-      ,---------------------------------------------------.
-Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
-      |------|------|---------|----------|------|---------|
-Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
-      | DSAP | SSAP |         |          |      | Packet  |
-      | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
-      `-----------------------------------------|         |
-Total: 8 non-data bytes                         `----.----'
-                                                     |
-       .- 'IP Packet' expands, if WEP enabled, to <--'
-       |
-       V
-      ,-----------------------.
-Bytes |  4  |   0-2296  |  4  |
-      |-----|-----------|-----|
-Desc. | IV  | Encrypted | ICV |
-      |     | IP Packet |     |
-      `-----------------------'
-Total: 8 non-data bytes
-
-
-802.3 Ethernet Data Frame
-
-      ,-----------------------------------------.
-Bytes |   6   |   6   |  2   |  Variable |   4  |
-      |-------|-------|------|-----------|------|
-Desc. | Dest. | Source| Type | IP Packet |  fcs |
-      |  MAC  |  MAC  |      |           |      |
-      `-----------------------------------------'
-Total: 18 non-data bytes
-
-In the event that fragmentation is required, the incoming payload is split into
-N parts of size ieee->fts.  The first fragment contains the SNAP header and the
-remaining packets are just data.
-
-If encryption is enabled, each fragment payload size is reduced by enough space
-to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
-So if you have 1500 bytes of payload with ieee->fts set to 500 without
-encryption it will take 3 frames.  With WEP it will take 4 frames as the
-payload of each frame is reduced to 492 bytes.
-
-* SKB visualization
-*
-*  ,- skb->data
-* |
-* |    ETHERNET HEADER        ,-<-- PAYLOAD
-* |                           |     14 bytes from skb->data
-* |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
-* |                       | | |
-* |,-Dest.--. ,--Src.---. | | |
-* |  6 bytes| | 6 bytes | | | |
-* v         | |         | | | |
-* 0         | v       1 | v | v           2
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-*     ^     | ^         | ^ |
-*     |     | |         | | |
-*     |     | |         | `T' <---- 2 bytes for Type
-*     |     | |         |
-*     |     | '---SNAP--' <-------- 6 bytes for SNAP
-*     |     |
-*     `-IV--' <-------------------- 4 bytes for IV (WEP)
-*
-*      SNAP HEADER
-*
-*/
-
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
-{
-	struct ieee80211_snap_hdr *snap;
-	u8 *oui;
-
-	snap = (struct ieee80211_snap_hdr *)data;
-	snap->dsap = 0xaa;
-	snap->ssap = 0xaa;
-	snap->ctrl = 0x03;
-
-	if (h_proto == 0x8137 || h_proto == 0x80f3)
-		oui = P802_1H_OUI;
-	else
-		oui = RFC1042_OUI;
-	snap->oui[0] = oui[0];
-	snap->oui[1] = oui[1];
-	snap->oui[2] = oui[2];
-
-	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
-
-	return SNAP_SIZE + sizeof(u16);
-}
-
-int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
-			       struct sk_buff *frag, int hdr_len)
-{
-	struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
-	int res;
-
-	/*
-	 * added to care about null crypt condition, to solve that system hangs
-	 * when shared keys error
-	 */
-	if (!crypt || !crypt->ops)
-		return -1;
-
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
-	struct ieee80211_hdr_4addr *header;
-
-	if (ieee->tkip_countermeasures &&
-	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
-		header = (struct ieee80211_hdr_4addr *)frag->data;
-		if (net_ratelimit()) {
-			netdev_dbg(ieee->dev, "TKIP countermeasures: dropped "
-			       "TX packet to %pM\n", header->addr1);
-		}
-		return -1;
-	}
-#endif
-	/*
-	 * To encrypt, frame format is:
-	 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes)
-	 *
-	 * PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU
-	 * encryption.
-	 *
-	 * Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
-	 * call both MSDU and MPDU encryption functions from here.
-	 */
-	atomic_inc(&crypt->refcnt);
-	res = 0;
-	if (crypt->ops->encrypt_msdu)
-		res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
-	if (res == 0 && crypt->ops->encrypt_mpdu)
-		res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
-
-	atomic_dec(&crypt->refcnt);
-	if (res < 0) {
-		netdev_info(ieee->dev, "Encryption failed: len=%d.\n", frag->len);
-		ieee->ieee_stats.tx_discards++;
-		return -1;
-	}
-
-	return 0;
-}
-
-
-void ieee80211_txb_free(struct ieee80211_txb *txb)
-{
-	int i;
-	if (unlikely(!txb))
-		return;
-	for (i = 0; i < txb->nr_frags; i++)
-		if (txb->fragments[i])
-			dev_kfree_skb_any(txb->fragments[i]);
-	kfree(txb);
-}
-
-static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
-						 gfp_t gfp_mask)
-{
-	struct ieee80211_txb *txb;
-	int i;
-	txb = kmalloc(
-		sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
-		gfp_mask);
-	if (!txb)
-		return NULL;
-
-	memset(txb, 0, sizeof(struct ieee80211_txb));
-	txb->nr_frags = nr_frags;
-	txb->frag_size = txb_size;
-
-	for (i = 0; i < nr_frags; i++) {
-		txb->fragments[i] = dev_alloc_skb(txb_size);
-		if (unlikely(!txb->fragments[i])) {
-			i--;
-			break;
-		}
-	}
-	if (unlikely(i != nr_frags)) {
-		while (i >= 0)
-			dev_kfree_skb_any(txb->fragments[i--]);
-		kfree(txb);
-		return NULL;
-	}
-	return txb;
-}
-
-/*
- * Classify the to-be send data packet
- * Need to acquire the sent queue index.
- */
-static int ieee80211_classify(struct sk_buff *skb,
-			      struct ieee80211_network *network)
-{
-	struct ether_header *eh = (struct ether_header *)skb->data;
-	unsigned int wme_UP = 0;
-
-	if (!network->QoS_Enable) {
-		skb->priority = 0;
-		return(wme_UP);
-	}
-
-	if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
-		const struct iphdr *ih = (struct iphdr *)(skb->data +
-		    sizeof(struct ether_header));
-		wme_UP = (ih->tos >> 5)&0x07;
-	} else if (vlan_tx_tag_present(skb)) {/* vtag packet */
-#ifndef VLAN_PRI_SHIFT
-#define VLAN_PRI_SHIFT  13              /* Shift to find VLAN user priority */
-#define VLAN_PRI_MASK   7               /* Mask for user priority bits in VLAN */
-#endif
-		u32 tag = vlan_tx_tag_get(skb);
-		wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
-	} else if (ETH_P_PAE ==  ntohs(((struct ethhdr *)skb->data)->h_proto)) {
-		wme_UP = 7;
-	}
-
-	skb->priority = wme_UP;
-	return(wme_UP);
-}
-
-/* SKBs are added to the ieee->tx_queue. */
-int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct ieee80211_device *ieee = netdev_priv(dev);
-	struct ieee80211_txb *txb = NULL;
-	struct ieee80211_hdr_3addrqos *frag_hdr;
-	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
-	unsigned long flags;
-	struct net_device_stats *stats = &ieee->stats;
-	int ether_type, encrypt;
-	int bytes, fc, qos_ctl, hdr_len;
-	struct sk_buff *skb_frag;
-	struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
-		.duration_id = 0,
-		.seq_ctl = 0,
-		.qos_ctl = 0
-	};
-	u8 dest[ETH_ALEN], src[ETH_ALEN];
-
-	struct ieee80211_crypt_data* crypt;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	/*
-	 * If there is no driver handler to take the TXB, don't bother
-	 * creating it...
-	 */
-	if ((!ieee->hard_start_xmit &&
-	     !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) ||
-	    ((!ieee->softmac_data_hard_start_xmit &&
-	      (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
-		netdev_warn(ieee->dev, "No xmit handler.\n");
-		goto success;
-	}
-
-	ieee80211_classify(skb,&ieee->current_network);
-	if (likely(ieee->raw_tx == 0)){
-
-		if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
-			netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
-			goto success;
-		}
-
-		ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
-
-		crypt = ieee->crypt[ieee->tx_keyidx];
-
-		encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
-			ieee->host_encrypt && crypt && crypt->ops;
-
-		if (!encrypt && ieee->ieee802_1x &&
-		ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
-			stats->tx_dropped++;
-			goto success;
-		}
-
-	#ifdef CONFIG_IEEE80211_DEBUG
-		if (crypt && !encrypt && ether_type == ETH_P_PAE) {
-			struct eapol *eap = (struct eapol *)(skb->data +
-				sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
-			IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
-				eap_get_type(eap->type));
-		}
-	#endif
-
-		/* Save source and destination addresses */
-		memcpy(&dest, skb->data, ETH_ALEN);
-		memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
-
-		/* Advance the SKB to the start of the payload */
-		skb_pull(skb, sizeof(struct ethhdr));
-
-		/* Determine total amount of storage required for TXB packets */
-		bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
-		if (ieee->current_network.QoS_Enable) {
-			if (encrypt)
-				fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
-					IEEE80211_FCTL_WEP;
-			else
-				fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
-
-		} else {
-			if (encrypt)
-				fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
-					IEEE80211_FCTL_WEP;
-			else
-				fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
-		}
-
-		if (ieee->iw_mode == IW_MODE_INFRA) {
-			fc |= IEEE80211_FCTL_TODS;
-			/* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
-			memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
-			memcpy(&header.addr2, &src, ETH_ALEN);
-			memcpy(&header.addr3, &dest, ETH_ALEN);
-		} else if (ieee->iw_mode == IW_MODE_ADHOC) {
-			/*
-			 * not From/To DS: Addr1 = DA, Addr2 = SA,
-			 * Addr3 = BSSID
-			 */
-			memcpy(&header.addr1, dest, ETH_ALEN);
-			memcpy(&header.addr2, src, ETH_ALEN);
-			memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
-		}
-		header.frame_ctl = cpu_to_le16(fc);
-
-		/*
-		 * Determine fragmentation size based on destination (multicast
-		 * and broadcast are not fragmented)
-		 */
-		if (is_multicast_ether_addr(header.addr1)) {
-			frag_size = MAX_FRAG_THRESHOLD;
-			qos_ctl = QOS_CTL_NOTCONTAIN_ACK;
-		} else {
-			/* default:392 */
-			frag_size = ieee->fts;
-			qos_ctl = 0;
-		}
-
-		if (ieee->current_network.QoS_Enable)	{
-			hdr_len = IEEE80211_3ADDR_LEN + 2;
-			/* skb->priority is set in the ieee80211_classify() */
-			qos_ctl |= skb->priority;
-			header.qos_ctl = cpu_to_le16(qos_ctl);
-		} else {
-			hdr_len = IEEE80211_3ADDR_LEN;
-		}
-
-		/*
-		 * Determine amount of payload per fragment.  Regardless of if
-		 * this stack is providing the full 802.11 header, one will
-		 * eventually be affixed to this fragment -- so we must account
-		 * for it when determining the amount of payload space.
-		 */
-		bytes_per_frag = frag_size - hdr_len;
-		if (ieee->config &
-		(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
-			bytes_per_frag -= IEEE80211_FCS_LEN;
-
-		/* Each fragment may need to have room for encryption pre/postfix */
-		if (encrypt)
-			bytes_per_frag -= crypt->ops->extra_prefix_len +
-				crypt->ops->extra_postfix_len;
-
-		/*
-		 * Number of fragments is the total bytes_per_frag /
-		 * payload_per_fragment
-		 */
-		nr_frags = bytes / bytes_per_frag;
-		bytes_last_frag = bytes % bytes_per_frag;
-		if (bytes_last_frag)
-			nr_frags++;
-		else
-			bytes_last_frag = bytes_per_frag;
-
-		/*
-		 * When we allocate the TXB we allocate enough space for the 
-		 * reserve and full fragment bytes (bytes_per_frag doesn't
-		 * include prefix, postfix, header, FCS, etc.)
-		 */
-		txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
-		if (unlikely(!txb)) {
-			netdev_warn(ieee->dev, "Could not allocate TXB\n");
-			goto failed;
-		}
-		txb->encrypted = encrypt;
-		txb->payload_size = bytes;
-
-		for (i = 0; i < nr_frags; i++) {
-			skb_frag = txb->fragments[i];
-			skb_frag->priority = UP2AC(skb->priority);
-			if (encrypt)
-				skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
-
-			frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(
-				skb_frag, hdr_len);
-			memcpy(frag_hdr, &header, hdr_len);
-
-			/*
-			 * If this is not the last fragment, then add the MOREFRAGS
-			 * bit to the frame control
-			 */
-			if (i != nr_frags - 1) {
-				frag_hdr->frame_ctl = cpu_to_le16(
-					fc | IEEE80211_FCTL_MOREFRAGS);
-				bytes = bytes_per_frag;
-
-			} else {
-				/* The last fragment takes the remaining length */
-				bytes = bytes_last_frag;
-			}
-			if (ieee->current_network.QoS_Enable) {
-				/*
-				 * add 1 only indicate to corresponding seq
-				 * number control 2006/7/12
-				 */
-				frag_hdr->seq_ctl = cpu_to_le16(
-					ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
-			} else {
-				frag_hdr->seq_ctl = cpu_to_le16(
-					ieee->seq_ctrl[0]<<4 | i);
-			}
-
-			/* Put a SNAP header on the first fragment */
-			if (i == 0) {
-				ieee80211_put_snap(
-					skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
-					ether_type);
-				bytes -= SNAP_SIZE + sizeof(u16);
-			}
-
-			memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
-
-			/* Advance the SKB... */
-			skb_pull(skb, bytes);
-
-			/*
-			 * Encryption routine will move the header forward in
-			 * order to insert the IV between the header and the
-			 * payload
-			 */
-			if (encrypt)
-				ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
-			if (ieee->config &
-			(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
-				skb_put(skb_frag, 4);
-		}
-		/* Advance sequence number in data frame. */
-		if (ieee->current_network.QoS_Enable) {
-			if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
-				ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
-			else
-				ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
-		} else {
-			if (ieee->seq_ctrl[0] == 0xFFF)
-				ieee->seq_ctrl[0] = 0;
-			else
-				ieee->seq_ctrl[0]++;
-		}
-	} else {
-		if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
-			netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
-			goto success;
-		}
-
-		txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
-		if (!txb) {
-			netdev_warn(ieee->dev, "Could not allocate TXB\n");
-			goto failed;
-		}
-
-		txb->encrypted = 0;
-		txb->payload_size = skb->len;
-		memcpy(skb_put(txb->fragments[0], skb->len), skb->data, skb->len);
-	}
-
- success:
-	spin_unlock_irqrestore(&ieee->lock, flags);
-		dev_kfree_skb_any(skb);
-	if (txb) {
-		if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
-			ieee80211_softmac_xmit(txb, ieee);
-		} else {
-			if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
-				stats->tx_packets++;
-				stats->tx_bytes += txb->payload_size;
-				return NETDEV_TX_OK;
-			}
-			ieee80211_txb_free(txb);
-		}
-	}
-
-	return NETDEV_TX_OK;
-
- failed:
-	spin_unlock_irqrestore(&ieee->lock, flags);
-	netif_stop_queue(dev);
-	stats->tx_errors++;
-	return NETDEV_TX_BUSY;
-
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
deleted file mode 100644
index 07c3f71..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- *  Copyright(c) 2004 Intel Corporation. All rights reserved.
- *
- * Portions of this file are based on the WEP enablement code provided by the
- * Host AP project hostap-drivers v0.1.3
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- */
-
-#include <linux/wireless.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-
-#include "ieee80211.h"
-static const char *ieee80211_modes[] = {
-	"?", "a", "b", "ab", "g", "ag", "bg", "abg"
-};
-
-#define MAX_CUSTOM_LEN 64
-static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
-					   char *start, char *stop,
-					   struct ieee80211_network *network,
-					   struct iw_request_info *info)
-{
-	char custom[MAX_CUSTOM_LEN];
-	char *p;
-	struct iw_event iwe;
-	int i, j;
-	u8 max_rate, rate;
-
-	/* First entry *MUST* be the AP MAC address */
-	iwe.cmd = SIOCGIWAP;
-	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-	ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
-	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-
-	/* Remaining entries will be displayed in the order we provide them */
-
-	/* Add the ESSID */
-	iwe.cmd = SIOCGIWESSID;
-	iwe.u.data.flags = 1;
-	if (network->ssid_len == 0) {
-		iwe.u.data.length = sizeof("<hidden>");
-		start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
-	} else {
-		iwe.u.data.length = min_t(u8, network->ssid_len, 32);
-		start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-	}
-	/* Add the protocol name */
-	iwe.cmd = SIOCGIWNAME;
-	snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
-	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
-
-	/* Add mode */
-	iwe.cmd = SIOCGIWMODE;
-	if (network->capability &
-	    (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
-		if (network->capability & WLAN_CAPABILITY_BSS)
-			iwe.u.mode = IW_MODE_MASTER;
-		else
-			iwe.u.mode = IW_MODE_ADHOC;
-
-		start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
-	}
-
-	/* Add frequency/channel */
-	iwe.cmd = SIOCGIWFREQ;
-	iwe.u.freq.m = network->channel;
-	iwe.u.freq.e = 0;
-	iwe.u.freq.i = 0;
-	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-
-	/* Add encryption capability */
-	iwe.cmd = SIOCGIWENCODE;
-	if (network->capability & WLAN_CAPABILITY_PRIVACY)
-		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-	else
-		iwe.u.data.flags = IW_ENCODE_DISABLED;
-	iwe.u.data.length = 0;
-	start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-
-	/* Add basic and extended rates */
-	max_rate = 0;
-	p = custom;
-	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
-	for (i = 0, j = 0; i < network->rates_len; ) {
-		if (j < network->rates_ex_len &&
-		    ((network->rates_ex[j] & 0x7F) <
-		     (network->rates[i] & 0x7F)))
-			rate = network->rates_ex[j++] & 0x7F;
-		else
-			rate = network->rates[i++] & 0x7F;
-		if (rate > max_rate)
-			max_rate = rate;
-		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
-	}
-	for (; j < network->rates_ex_len; j++) {
-		rate = network->rates_ex[j] & 0x7F;
-		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
-		if (rate > max_rate)
-			max_rate = rate;
-	}
-
-	iwe.cmd = SIOCGIWRATE;
-	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-	iwe.u.bitrate.value = max_rate * 500000;
-	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
-
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = p - custom;
-	if (iwe.u.data.length)
-		start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
-	/* Add quality statistics */
-	/* TODO: Fix these values... */
-	if (network->stats.signal == 0 || network->stats.rssi == 0)
-		netdev_info(ieee->dev, "========>signal:%d, rssi:%d\n",
-			    network->stats.signal, network->stats.rssi);
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.qual = network->stats.signalstrength;
-	iwe.u.qual.level = network->stats.signal;
-	iwe.u.qual.noise = network->stats.noise;
-	iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
-	if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
-		iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
-	if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
-		iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
-	if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
-		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
-	iwe.u.qual.updated = 7;
-	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-
-	iwe.cmd = IWEVCUSTOM;
-	p = custom;
-
-	iwe.u.data.length = p - custom;
-	if (iwe.u.data.length)
-		start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
-	memset(&iwe, 0, sizeof(iwe));
-	if (network->wpa_ie_len) {
-		char buf[MAX_WPA_IE_LEN];
-		memcpy(buf, network->wpa_ie, network->wpa_ie_len);
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = network->wpa_ie_len;
-		start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-	}
-
-	memset(&iwe, 0, sizeof(iwe));
-	if (network->rsn_ie_len) {
-		char buf[MAX_WPA_IE_LEN];
-		memcpy(buf, network->rsn_ie, network->rsn_ie_len);
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = network->rsn_ie_len;
-		start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-	}
-
-	/* Add EXTRA: Age to display seconds since last beacon/probe response
-	 * for given network.
-	 */
-	iwe.cmd = IWEVCUSTOM;
-	p = custom;
-	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-		      " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
-	iwe.u.data.length = p - custom;
-	if (iwe.u.data.length)
-		start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
-	return start;
-}
-
-int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
-{
-	struct ieee80211_network *network;
-	unsigned long flags;
-	int err = 0;
-	char *ev = extra;
-	char *stop = ev + wrqu->data.length;
-	int i = 0;
-
-	IEEE80211_DEBUG_WX("Getting scan\n");
-	down(&ieee->wx_sem);
-	spin_lock_irqsave(&ieee->lock, flags);
-
-	if (!ieee->bHwRadioOff) {
-		list_for_each_entry(network, &ieee->network_list, list) {
-			i++;
-
-			if ((stop-ev) < 200) {
-				err = -E2BIG;
-				break;
-			}
-			if (ieee->scan_age == 0 ||
-			    time_after(network->last_scanned + ieee->scan_age, jiffies)) {
-				ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
-			} else
-				IEEE80211_DEBUG_SCAN(
-					"Not showing network '%s ("
-					"%pM)' due to age (%lums).\n",
-					escape_essid(network->ssid,
-						     network->ssid_len),
-					network->bssid,
-					(jiffies - network->last_scanned) / (HZ / 100));
-		}
-	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
-	up(&ieee->wx_sem);
-	wrqu->data.length = ev -  extra;
-	wrqu->data.flags = 0;
-	IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
-
-	return err;
-}
-
-int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *keybuf)
-{
-	struct iw_point *erq = &(wrqu->encoding);
-	struct net_device *dev = ieee->dev;
-	struct ieee80211_security sec = {
-		.flags = 0
-	};
-	int i, key, key_provided, len;
-	struct ieee80211_crypt_data **crypt;
-
-	IEEE80211_DEBUG_WX("SET_ENCODE\n");
-
-	key = erq->flags & IW_ENCODE_INDEX;
-	if (key) {
-		if (key > WEP_KEYS)
-			return -EINVAL;
-		key--;
-		key_provided = 1;
-	} else {
-		key_provided = 0;
-		key = ieee->tx_keyidx;
-	}
-
-	IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
-			   "provided" : "default");
-
-	crypt = &ieee->crypt[key];
-
-	if (erq->flags & IW_ENCODE_DISABLED) {
-		if (key_provided && *crypt) {
-			IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
-					   key);
-			ieee80211_crypt_delayed_deinit(ieee, crypt);
-		} else
-			IEEE80211_DEBUG_WX("Disabling encryption.\n");
-
-		/* Check all the keys to see if any are still configured,
-		 * and if no key index was provided, de-init them all.
-		 */
-		for (i = 0; i < WEP_KEYS; i++) {
-			if (ieee->crypt[i] != NULL) {
-				if (key_provided)
-					break;
-				ieee80211_crypt_delayed_deinit(
-					ieee, &ieee->crypt[i]);
-			}
-		}
-
-		if (i == WEP_KEYS) {
-			sec.enabled = 0;
-			sec.level = SEC_LEVEL_0;
-			sec.flags |= SEC_ENABLED | SEC_LEVEL;
-		}
-
-		goto done;
-	}
-
-	sec.enabled = 1;
-	sec.flags |= SEC_ENABLED;
-
-	if (*crypt != NULL && (*crypt)->ops != NULL &&
-	    strcmp((*crypt)->ops->name, "WEP") != 0) {
-		/* changing to use WEP; deinit previously used algorithm
-		 * on this key.
-		 */
-		ieee80211_crypt_delayed_deinit(ieee, crypt);
-	}
-
-	if (*crypt == NULL) {
-		struct ieee80211_crypt_data *new_crypt;
-
-		/* take WEP into use */
-		new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
-				    GFP_KERNEL);
-		if (new_crypt == NULL)
-			return -ENOMEM;
-		new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-		if (!new_crypt->ops)
-			new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-
-		if (new_crypt->ops)
-			new_crypt->priv = new_crypt->ops->init(key);
-
-		if (!new_crypt->ops || !new_crypt->priv) {
-			kfree(new_crypt);
-			new_crypt = NULL;
-
-			netdev_warn(ieee->dev,
-				    "could not initialize WEP: load module ieee80211_crypt_wep\n");
-			return -EOPNOTSUPP;
-		}
-		*crypt = new_crypt;
-	}
-
-	/* If a new key was provided, set it up */
-	if (erq->length > 0) {
-		len = erq->length <= 5 ? 5 : 13;
-		memcpy(sec.keys[key], keybuf, erq->length);
-		if (len > erq->length)
-			memset(sec.keys[key] + erq->length, 0,
-			       len - erq->length);
-		IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
-				   key, escape_essid(sec.keys[key], len),
-				   erq->length, len);
-		sec.key_sizes[key] = len;
-		(*crypt)->ops->set_key(sec.keys[key], len, NULL,
-				       (*crypt)->priv);
-		sec.flags |= (1 << key);
-		/* This ensures a key will be activated if no key is
-		 * explicitly set.
-		 */
-		if (key == sec.active_key)
-			sec.flags |= SEC_ACTIVE_KEY;
-		ieee->tx_keyidx = key;
-	} else {
-		len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
-					     NULL, (*crypt)->priv);
-		if (len == 0) {
-			/* Set a default key of all 0 */
-			IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
-					   key);
-			memset(sec.keys[key], 0, 13);
-			(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
-					       (*crypt)->priv);
-			sec.key_sizes[key] = 13;
-			sec.flags |= (1 << key);
-		}
-
-		/* No key data - just set the default TX key index */
-		if (key_provided) {
-			IEEE80211_DEBUG_WX(
-				"Setting key %d to default Tx key.\n", key);
-			ieee->tx_keyidx = key;
-			sec.active_key = key;
-			sec.flags |= SEC_ACTIVE_KEY;
-		}
-	}
-
- done:
-	ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
-	sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
-	sec.flags |= SEC_AUTH_MODE;
-	IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
-			   "OPEN" : "SHARED KEY");
-
-	/* For now we just support WEP, so only set that security level...
-	 * TODO: When WPA is added this is one place that needs to change
-	 */
-	sec.flags |= SEC_LEVEL;
-	sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
-
-	if (ieee->set_security)
-		ieee->set_security(dev, &sec);
-
-	/* Do not reset port if card is in Managed mode since resetting will
-	 * generate new IEEE 802.11 authentication which may end up in looping
-	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
-	 * configuration (for example... Prism2), implement the reset_port in
-	 * the callbacks structures used to initialize the 802.11 stack.
-	 */
-	if (ieee->reset_on_keychange &&
-	    ieee->iw_mode != IW_MODE_INFRA &&
-	    ieee->reset_port && ieee->reset_port(dev)) {
-		netdev_dbg(ieee->dev, "reset_port failed\n");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *keybuf)
-{
-	struct iw_point *erq = &(wrqu->encoding);
-	int len, key;
-	struct ieee80211_crypt_data *crypt;
-
-	IEEE80211_DEBUG_WX("GET_ENCODE\n");
-
-	if (ieee->iw_mode == IW_MODE_MONITOR)
-		return -1;
-
-	key = erq->flags & IW_ENCODE_INDEX;
-	if (key) {
-		if (key > WEP_KEYS)
-			return -EINVAL;
-		key--;
-	} else
-		key = ieee->tx_keyidx;
-
-	crypt = ieee->crypt[key];
-	erq->flags = key + 1;
-
-	if (crypt == NULL || crypt->ops == NULL) {
-		erq->length = 0;
-		erq->flags |= IW_ENCODE_DISABLED;
-		return 0;
-	}
-
-	if (strcmp(crypt->ops->name, "WEP") != 0) {
-		/* only WEP is supported with wireless extensions, so just
-		 * report that encryption is used.
-		 */
-		erq->length = 0;
-		erq->flags |= IW_ENCODE_ENABLED;
-		return 0;
-	}
-
-	len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
-	erq->length = (len >= 0 ? len : 0);
-
-	erq->flags |= IW_ENCODE_ENABLED;
-
-	if (ieee->open_wep)
-		erq->flags |= IW_ENCODE_OPEN;
-	else
-		erq->flags |= IW_ENCODE_RESTRICTED;
-
-	return 0;
-}
-
-int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
-{
-	struct net_device *dev = ieee->dev;
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	int i, idx, ret = 0;
-	int group_key = 0;
-	const char *alg;
-	struct ieee80211_crypto_ops *ops;
-	struct ieee80211_crypt_data **crypt;
-
-	struct ieee80211_security sec = {
-		.flags = 0,
-	};
-	idx = encoding->flags & IW_ENCODE_INDEX;
-	if (idx) {
-		if (idx < 1 || idx > WEP_KEYS)
-			return -EINVAL;
-		idx--;
-	} else
-		idx = ieee->tx_keyidx;
-
-	if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-		crypt = &ieee->crypt[idx];
-		group_key = 1;
-	} else {
-		/* some Cisco APs use idx>0 for unicast in dynamic WEP */
-		if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
-			return -EINVAL;
-		if (ieee->iw_mode == IW_MODE_INFRA)
-			crypt = &ieee->crypt[idx];
-		else
-			return -EINVAL;
-	}
-
-	sec.flags |= SEC_ENABLED;
-	if ((encoding->flags & IW_ENCODE_DISABLED) ||
-	    ext->alg == IW_ENCODE_ALG_NONE) {
-		if (*crypt)
-			ieee80211_crypt_delayed_deinit(ieee, crypt);
-
-		for (i = 0; i < WEP_KEYS; i++)
-			if (ieee->crypt[i] != NULL)
-				break;
-
-		if (i == WEP_KEYS) {
-			sec.enabled = 0;
-			sec.level = SEC_LEVEL_0;
-			sec.flags |= SEC_LEVEL;
-		}
-		goto done;
-	}
-
-	sec.enabled = 1;
-
-	switch (ext->alg) {
-	case IW_ENCODE_ALG_WEP:
-		alg = "WEP";
-		break;
-	case IW_ENCODE_ALG_TKIP:
-		alg = "TKIP";
-		break;
-	case IW_ENCODE_ALG_CCMP:
-		alg = "CCMP";
-		break;
-	default:
-		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
-				   dev->name, ext->alg);
-		ret = -EINVAL;
-		goto done;
-	}
-
-	ops = ieee80211_get_crypto_ops(alg);
-	if (ops == NULL)
-		ops = ieee80211_get_crypto_ops(alg);
-	if (ops == NULL) {
-		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
-				   dev->name, ext->alg);
-		netdev_err(ieee->dev, "========>unknown crypto alg %d\n",
-			   ext->alg);
-		ret = -EINVAL;
-		goto done;
-	}
-
-	if (*crypt == NULL || (*crypt)->ops != ops) {
-		struct ieee80211_crypt_data *new_crypt;
-
-		ieee80211_crypt_delayed_deinit(ieee, crypt);
-
-		new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
-		if (new_crypt == NULL) {
-			ret = -ENOMEM;
-			goto done;
-		}
-		new_crypt->ops = ops;
-		if (new_crypt->ops)
-			new_crypt->priv = new_crypt->ops->init(idx);
-		if (new_crypt->priv == NULL) {
-			kfree(new_crypt);
-			ret = -EINVAL;
-			goto done;
-		}
-		*crypt = new_crypt;
-
-	}
-
-	if (ext->key_len > 0 && (*crypt)->ops->set_key &&
-	    (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
-				   (*crypt)->priv) < 0) {
-		IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
-		netdev_err(ieee->dev, "key setting failed\n");
-		ret = -EINVAL;
-		goto done;
-	}
-#if 1
-	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-		ieee->tx_keyidx = idx;
-		sec.active_key = idx;
-		sec.flags |= SEC_ACTIVE_KEY;
-	}
-
-	if (ext->alg != IW_ENCODE_ALG_NONE) {
-		memcpy(sec.keys[idx], ext->key, ext->key_len);
-		sec.key_sizes[idx] = ext->key_len;
-		sec.flags |= (1 << idx);
-		if (ext->alg == IW_ENCODE_ALG_WEP) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_1;
-		} else if (ext->alg == IW_ENCODE_ALG_TKIP) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_2;
-		} else if (ext->alg == IW_ENCODE_ALG_CCMP) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_3;
-		}
-		/* Don't set sec level for group keys. */
-		if (group_key)
-			sec.flags &= ~SEC_LEVEL;
-	}
-#endif
-done:
-	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
-
-	if (ieee->reset_on_keychange &&
-	    ieee->iw_mode != IW_MODE_INFRA &&
-	    ieee->reset_port && ieee->reset_port(dev)) {
-		IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
-{
-	struct iw_mlme *mlme = (struct iw_mlme *) extra;
-#if 1
-	switch (mlme->cmd) {
-	case IW_MLME_DEAUTH:
-	case IW_MLME_DISASSOC:
-		ieee80211_disassociate(ieee);
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-#endif
-	return 0;
-}
-
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
-			  struct iw_request_info *info,
-			  struct iw_param *data, char *extra)
-{
-	switch (data->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-		/* need to support wpa2 here */
-		break;
-	case IW_AUTH_CIPHER_PAIRWISE:
-	case IW_AUTH_CIPHER_GROUP:
-	case IW_AUTH_KEY_MGMT:
-		/* Host AP driver does not use these parameters and allows
-		 * wpa_supplicant to control them internally.
-		 */
-		break;
-	case IW_AUTH_TKIP_COUNTERMEASURES:
-		ieee->tkip_countermeasures = data->value;
-		break;
-	case IW_AUTH_DROP_UNENCRYPTED:
-		ieee->drop_unencrypted = data->value;
-		break;
-
-	case IW_AUTH_80211_AUTH_ALG:
-		ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM) ? 1 : 0;
-		break;
-
-#if 1
-	case IW_AUTH_WPA_ENABLED:
-		ieee->wpa_enabled = (data->value) ? 1 : 0;
-		break;
-
-#endif
-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-		ieee->ieee802_1x = data->value;
-		break;
-	case IW_AUTH_PRIVACY_INVOKED:
-		ieee->privacy_invoked = data->value;
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-	return 0;
-}
-
-#if 1
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
-{
-	u8 *buf = NULL;
-
-	if (len > MAX_WPA_IE_LEN || (len && ie == NULL)) {
-		netdev_err(ieee->dev, "return error out, len:%zu\n", len);
-	return -EINVAL;
-	}
-
-	if (len) {
-		if (len != ie[1]+2) {
-			netdev_err(ieee->dev, "len:%zu, ie:%d\n", len, ie[1]);
-			return -EINVAL;
-		}
-		buf = kmemdup(ie, len, GFP_KERNEL);
-		if (buf == NULL)
-			return -ENOMEM;
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = buf;
-		ieee->wpa_ie_len = len;
-	} else {
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = NULL;
-		ieee->wpa_ie_len = 0;
-	}
-
-	return 0;
-
-}
-#endif
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
deleted file mode 100644
index 9f931db..0000000
--- a/drivers/staging/rtl8187se/r8180.h
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * This is part of rtl8180 OpenSource driver.
- * Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
- * Released under the terms of GPL (General Public Licence)
- *
- * Parts of this driver are based on the GPL part of the official realtek driver
- *
- * Parts of this driver are based on the rtl8180 driver skeleton from Patric
- * Schenke & Andres Salomon
- *
- * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
- *
- * We want to thanks the Authors of those projects and the Ndiswrapper project
- * Authors.
- */
-
-#ifndef R8180H
-#define R8180H
-
-#include <linux/interrupt.h>
-
-#define RTL8180_MODULE_NAME "r8180"
-#define DMESG(x, a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a)
-#define DMESGW(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a)
-#define DMESGE(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a)
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/rtnetlink.h> /* for rtnl_lock() */
-#include <linux/wireless.h>
-#include <linux/timer.h>
-#include <linux/proc_fs.h> /* Necessary because we use the proc fs. */
-#include <linux/if_arp.h>
-#include "ieee80211/ieee80211.h"
-#include <asm/io.h>
-
-#define EPROM_93c46 0
-#define EPROM_93c56 1
-
-#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
-
-#define DEFAULT_FRAG_THRESHOLD 2342U
-#define MIN_FRAG_THRESHOLD 256U
-#define DEFAULT_RTS_THRESHOLD 2342U
-#define MIN_RTS_THRESHOLD 0U
-#define MAX_RTS_THRESHOLD 2342U
-#define DEFAULT_BEACONINTERVAL 0x64U
-
-#define DEFAULT_RETRY_RTS 7
-#define DEFAULT_RETRY_DATA 7
-
-#define BEACON_QUEUE 6
-
-#define aSifsTime 10
-
-#define sCrcLng 4
-#define sAckCtsLng 112 /* bits in ACK and CTS frames. */
-/* +by amy 080312. */
-#define RATE_ADAPTIVE_TIMER_PERIOD 300
-
-enum wireless_mode {
-	WIRELESS_MODE_UNKNOWN = 0x00,
-	WIRELESS_MODE_A = 0x01,
-	WIRELESS_MODE_B = 0x02,
-	WIRELESS_MODE_G = 0x04,
-	WIRELESS_MODE_AUTO = 0x08,
-};
-
-struct chnl_access_setting {
-	u16 sifs_timer;
-	u16 difs_timer;
-	u16 slot_time_timer;
-	u16 eifs_timer;
-	u16 cwmin_index;
-	u16 cwmax_index;
-};
-
-enum nic_t {
-	NIC_8185 = 1,
-	NIC_8185B
-};
-
-typedef u32 AC_CODING;
-#define AC0_BE	0 /* ACI: 0x00 */ /* Best Effort. */
-#define AC1_BK	1 /* ACI: 0x01 */ /* Background. */
-#define AC2_VI	2 /* ACI: 0x10 */ /* Video. */
-#define AC3_VO	3 /* ACI: 0x11 */ /* Voice. */
-#define AC_MAX	4 /* Max: define total number; Should not to be used as a real
-		   * enum.
-		   */
-
-/*
- * ECWmin/ECWmax field.
- * Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
- */
-typedef union _ECW {
-	u8 charData;
-	struct {
-		u8 ECWmin:4;
-		u8 ECWmax:4;
-	} f;	/* Field */
-} ECW, *PECW;
-
-/*
- * ACI/AIFSN Field. Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- */
-typedef union _ACI_AIFSN {
-	u8 charData;
-
-	struct {
-		u8 AIFSN:4;
-		u8 ACM:1;
-		u8 ACI:2;
-		u8 Reserved:1;
-	} f;	/* Field */
-} ACI_AIFSN, *PACI_AIFSN;
-
-/*
- * AC Parameters Record Format.
- * Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- */
-typedef union _AC_PARAM {
-	u32 longData;
-	u8 charData[4];
-
-	struct {
-		ACI_AIFSN AciAifsn;
-		ECW Ecw;
-		u16 TXOPLimit;
-	} f;	/* Field */
-} AC_PARAM, *PAC_PARAM;
-
-struct buffer {
-	struct buffer *next;
-	u32 *buf;
-	dma_addr_t dma;
-};
-
-/* YJ,modified,080828. */
-struct stats {
-	unsigned long txrdu;
-	unsigned long rxrdu;
-	unsigned long rxnolast;
-	unsigned long rxnodata;
-	unsigned long rxnopointer;
-	unsigned long txnperr;
-	unsigned long txresumed;
-	unsigned long rxerr;
-	unsigned long rxoverflow;
-	unsigned long rxint;
-	unsigned long txbkpokint;
-	unsigned long txbepoking;
-	unsigned long txbkperr;
-	unsigned long txbeperr;
-	unsigned long txnpokint;
-	unsigned long txhpokint;
-	unsigned long txhperr;
-	unsigned long ints;
-	unsigned long shints;
-	unsigned long txoverflow;
-	unsigned long rxdmafail;
-	unsigned long txbeacon;
-	unsigned long txbeaconerr;
-	unsigned long txlpokint;
-	unsigned long txlperr;
-	unsigned long txretry; /* retry number tony 20060601 */
-	unsigned long rxcrcerrmin; /* crc error (0-500) */
-	unsigned long rxcrcerrmid; /* crc error (500-1000) */
-	unsigned long rxcrcerrmax; /* crc error (>1000) */
-	unsigned long rxicverr; /* ICV error */
-};
-
-#define MAX_LD_SLOT_NUM 10
-#define KEEP_ALIVE_INTERVAL 20 /* in seconds. */
-#define CHECK_FOR_HANG_PERIOD 2 /* be equal to watchdog check time. */
-#define DEFAULT_KEEP_ALIVE_LEVEL 1
-#define DEFAULT_SLOT_NUM 2
-#define POWER_PROFILE_AC 0
-#define POWER_PROFILE_BATTERY 1
-
-struct link_detect_t {
-	u32 rx_frame_num[MAX_LD_SLOT_NUM]; /* number of Rx Frame.
-					    * CheckForHang_period  to determine
-					    * link status.
-					    */
-	u16 slot_num; /* number of CheckForHang period to determine link status,
-		       * default is 2.
-		       */
-	u16 slot_index;
-	u32 num_tx_ok_in_period; /* number of packet transmitted during
-				  * CheckForHang.
-				  */
-	u32 num_rx_ok_in_period; /* number of packet received during
-				  * CheckForHang.
-				  */
-	u8 idle_count; /* (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD) */
-	u32 last_num_tx_unicast;
-	u32 last_num_rx_unicast;
-
-	bool b_busy_traffic; /* when it is set to 1, UI cann't scan at will. */
-};
-
-/* YJ,modified,080828,end */
-
-/* by amy for led
- * ==========================================================================
- * LED customization.
- * ==========================================================================
- */
-enum led_strategy_8185 {
-	SW_LED_MODE0,
-	SW_LED_MODE1,
-	HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different
-		 * control modes). */
-};
-
-enum rt_rf_power_state {
-	RF_ON,
-	RF_SLEEP,
-	RF_OFF
-};
-
-enum _ReasonCode {
-	unspec_reason = 0x1,
-	auth_not_valid = 0x2,
-	deauth_lv_ss = 0x3,
-	inactivity = 0x4,
-	ap_overload = 0x5,
-	class2_err = 0x6,
-	class3_err = 0x7,
-	disas_lv_ss = 0x8,
-	asoc_not_auth = 0x9,
-
-	/* ----MIC_CHECK */
-	mic_failure = 0xe,
-	/* ----END MIC_CHECK */
-
-	/* Reason code defined in 802.11i D10.0 p.28. */
-	invalid_IE = 0x0d,
-	four_way_tmout = 0x0f,
-	two_way_tmout = 0x10,
-	IE_dismatch = 0x11,
-	invalid_Gcipher	= 0x12,
-	invalid_Pcipher	= 0x13,
-	invalid_AKMP = 0x14,
-	unsup_RSNIEver = 0x15,
-	invalid_RSNIE = 0x16,
-	auth_802_1x_fail = 0x17,
-	ciper_reject = 0x18,
-
-	/* Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie,
-	 * 2005-11-15.
-	 */
-	QoS_unspec = 0x20, /* 32 */
-	QAP_bandwidth = 0x21, /* 33 */
-	poor_condition = 0x22, /* 34 */
-	no_facility = 0x23, /* 35 */
-	/* Where is 36??? */
-	req_declined = 0x25, /* 37 */
-	invalid_param = 0x26, /* 38 */
-	req_not_honored = 0x27, /* 39 */
-	TS_not_created = 0x2F, /* 47 */
-	DL_not_allowed = 0x30, /* 48 */
-	dest_not_exist = 0x31, /* 49 */
-	dest_not_QSTA = 0x32, /* 50 */
-};
-
-enum rt_ps_mode {
-	ACTIVE, /* Active/Continuous access. */
-	MAX_PS,	/* Max power save mode. */
-	FAST_PS /* Fast power save mode. */
-};
-
-/* by amy for power save. */
-struct r8180_priv {
-	struct pci_dev *pdev;
-
-	short epromtype;
-	int irq;
-	struct ieee80211_device *ieee80211;
-
-	short plcp_preamble_mode; /* 0:auto 1:short 2:long */
-
-	spinlock_t irq_th_lock;
-	spinlock_t tx_lock;
-	spinlock_t ps_lock;
-	spinlock_t rf_ps_lock;
-
-	u16 irq_mask;
-	short irq_enabled;
-	struct net_device *dev;
-	short chan;
-	short sens;
-	short max_sens;
-	u8 chtxpwr[15]; /* channels from 1 to 14, 0 not used. */
-	u8 chtxpwr_ofdm[15]; /* channels from 1 to 14, 0 not used. */
-	u8 channel_plan;  /* it's the channel plan index. */
-	short up;
-	short crcmon; /* if 1 allow bad crc frame reception in monitor mode. */
-
-	struct timer_list scan_timer;
-	spinlock_t scan_lock;
-	u8 active_probe;
-	struct semaphore wx_sem;
-	short hw_wep;
-
-	short digphy;
-	short antb;
-	short diversity;
-	u32 key0[4];
-	short (*rf_set_sens)(struct net_device *dev, short sens);
-	void (*rf_set_chan)(struct net_device *dev, short ch);
-	void (*rf_close)(struct net_device *dev);
-	void (*rf_init)(struct net_device *dev);
-	void (*rf_sleep)(struct net_device *dev);
-	void (*rf_wakeup)(struct net_device *dev);
-	/* short rate; */
-	short promisc;
-	/* stats */
-	struct stats stats;
-	struct link_detect_t link_detect; /* YJ,add,080828 */
-	struct iw_statistics wstats;
-
-	/* RX stuff. */
-	u32 *rxring;
-	u32 *rxringtail;
-	dma_addr_t rxringdma;
-	struct buffer *rxbuffer;
-	struct buffer *rxbufferhead;
-	int rxringcount;
-	u16 rxbuffersize;
-
-	struct sk_buff *rx_skb;
-
-	short rx_skb_complete;
-
-	u32 rx_prevlen;
-
-	u32 *txmapring;
-	u32 *txbkpring;
-	u32 *txbepring;
-	u32 *txvipring;
-	u32 *txvopring;
-	u32 *txhpring;
-	dma_addr_t txmapringdma;
-	dma_addr_t txbkpringdma;
-	dma_addr_t txbepringdma;
-	dma_addr_t txvipringdma;
-	dma_addr_t txvopringdma;
-	dma_addr_t txhpringdma;
-	u32 *txmapringtail;
-	u32 *txbkpringtail;
-	u32 *txbepringtail;
-	u32 *txvipringtail;
-	u32 *txvopringtail;
-	u32 *txhpringtail;
-	u32 *txmapringhead;
-	u32 *txbkpringhead;
-	u32 *txbepringhead;
-	u32 *txvipringhead;
-	u32 *txvopringhead;
-	u32 *txhpringhead;
-	struct buffer *txmapbufs;
-	struct buffer *txbkpbufs;
-	struct buffer *txbepbufs;
-	struct buffer *txvipbufs;
-	struct buffer *txvopbufs;
-	struct buffer *txhpbufs;
-	struct buffer *txmapbufstail;
-	struct buffer *txbkpbufstail;
-	struct buffer *txbepbufstail;
-	struct buffer *txvipbufstail;
-	struct buffer *txvopbufstail;
-	struct buffer *txhpbufstail;
-
-	int txringcount;
-	int txbuffsize;
-	struct tasklet_struct irq_rx_tasklet;
-	u8 dma_poll_mask;
-
-	/* adhoc/master mode stuff. */
-	u32 *txbeaconringtail;
-	dma_addr_t txbeaconringdma;
-	u32 *txbeaconring;
-	int txbeaconcount;
-	struct buffer *txbeaconbufs;
-	struct buffer *txbeaconbufstail;
-
-	u8 retry_data;
-	u8 retry_rts;
-	u16 rts;
-
-	/* by amy for led. */
-	enum led_strategy_8185 led_strategy;
-	/* by amy for led. */
-
-	/* by amy for power save. */
-	struct timer_list watch_dog_timer;
-	bool bInactivePs;
-	bool bSwRfProcessing;
-	enum rt_rf_power_state eInactivePowerState;
-	enum rt_rf_power_state eRFPowerState;
-	u32 RfOffReason;
-	bool RFChangeInProgress;
-	bool SetRFPowerStateInProgress;
-	u8 RFProgType;
-	bool bLeisurePs;
-	enum rt_ps_mode dot11PowerSaveMode;
-	u8 TxPollingTimes;
-
-	bool bApBufOurFrame; /* TRUE if AP buffer our unicast data , we will
-			      * keep eAwake until receive data or timeout.
-			      */
-	u8 WaitBufDataBcnCount;
-	u8 WaitBufDataTimeOut;
-
-	/* by amy for power save. */
-	/* by amy for antenna. */
-	u8 EEPROMSwAntennaDiversity;
-	bool EEPROMDefaultAntenna1;
-	u8 RegSwAntennaDiversityMechanism;
-	bool bSwAntennaDiverity;
-	u8 RegDefaultAntenna;
-	bool bDefaultAntenna1;
-	u8 SignalStrength;
-	long Stats_SignalStrength;
-	long LastSignalStrengthInPercent; /* In percentage, used for smoothing,
-					   * e.g. Moving Average.
-					   */
-	u8 SignalQuality; /* in 0-100 index. */
-	long Stats_SignalQuality;
-	long RecvSignalPower; /* in dBm. */
-	long Stats_RecvSignalPower;
-	u8 LastRxPktAntenna; /* +by amy 080312 Antenna which received the lasted
-			      * packet. 0: Aux, 1:Main. Added by Roger,
-			      * 2008.01.25.
-			      */
-	u32 AdRxOkCnt;
-	long AdRxSignalStrength;
-	u8 CurrAntennaIndex; /* Index to current Antenna (both Tx and Rx). */
-	u8 AdTickCount; /* Times of SwAntennaDiversityTimer happened. */
-	u8 AdCheckPeriod; /* # of period SwAntennaDiversityTimer to check Rx
-			   * signal strength for SW Antenna Diversity.
-			   */
-	u8 AdMinCheckPeriod; /* Min value of AdCheckPeriod. */
-	u8 AdMaxCheckPeriod; /* Max value of AdCheckPeriod. */
-	long AdRxSsThreshold; /* Signal strength threshold to switch antenna. */
-	long AdMaxRxSsThreshold; /* Max value of AdRxSsThreshold. */
-	bool bAdSwitchedChecking; /* TRUE if we shall shall check Rx signal
-				   * strength for last time switching antenna.
-				   */
-	long AdRxSsBeforeSwitched; /* Rx signal strength before we switched
-				    * antenna.
-				    */
-	struct timer_list SwAntennaDiversityTimer;
-	/* by amy for antenna {by amy 080312 */
-
-	/* Crystal calibration. Added by Roger, 2007.12.11. */
-
-	bool bXtalCalibration; /* Crystal calibration.*/
-	u8 XtalCal_Xin; /* Crystal calibration for Xin. 0~7.5pF */
-	u8 XtalCal_Xout; /* Crystal calibration for Xout. 0~7.5pF */
-
-	/* Tx power tracking with thermal meter indication.
-	 * Added by Roger, 2007.12.11.
-	 */
-
-	bool bTxPowerTrack; /* Tx Power tracking. */
-	u8 ThermalMeter; /* Thermal meter reference indication. */
-
-	/* Dynamic Initial Gain Adjustment Mechanism. Added by Bruce,
-	 * 2007-02-14.
-	 */
-	bool bDigMechanism; /* TRUE if DIG is enabled, FALSE ow. */
-	bool bRegHighPowerMechanism; /* For High Power Mechanism. 061010,
-				      * by rcnjko.
-				      */
-	u32 FalseAlarmRegValue;
-	u8 RegDigOfdmFaUpTh; /* Upper threshold of OFDM false alarm, which is
-			      * used in DIG.
-			      */
-	u8 DIG_NumberFallbackVote;
-	u8 DIG_NumberUpgradeVote;
-	/* For HW antenna diversity, added by Roger, 2008.01.30. */
-	u32 AdMainAntennaRxOkCnt; /* Main antenna Rx OK count. */
-	u32 AdAuxAntennaRxOkCnt; /* Aux antenna Rx OK count. */
-	bool bHWAdSwitched; /* TRUE if we has switched default antenna by HW
-			     * evaluation.
-			     */
-	/* RF High Power upper/lower threshold. */
-	u8 RegHiPwrUpperTh;
-	u8 RegHiPwrLowerTh;
-	/* RF RSSI High Power upper/lower Threshold. */
-	u8 RegRSSIHiPwrUpperTh;
-	u8 RegRSSIHiPwrLowerTh;
-	/* Current CCK RSSI value to determine CCK high power, asked by SD3 DZ,
-	 * by Bruce, 2007-04-12.
-	 */
-	u8 CurCCKRSSI;
-	bool bCurCCKPkt;
-	/* High Power Mechanism. Added by amy, 080312. */
-	bool bToUpdateTxPwr;
-	long UndecoratedSmoothedSS;
-	long UndecoratedSmoothedRxPower;
-	u8 RSSI;
-	char RxPower;
-	u8 InitialGain;
-	/* For adjust Dig Threshold during Legacy/Leisure Power Save Mode. */
-	u32 DozePeriodInPast2Sec;
-	/* Don't access BB/RF under disable PLL situation. */
-	u8 InitialGainBackUp;
-	u8 RegBModeGainStage;
-	/* by amy for rate adaptive */
-	struct timer_list rateadapter_timer;
-	u32 RateAdaptivePeriod;
-	bool bEnhanceTxPwr;
-	bool bUpdateARFR;
-	int ForcedDataRate; /* Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M.)
-			     */
-	u32 NumTxUnicast; /* YJ,add,080828,for keep alive. */
-	u8 keepAliveLevel; /*YJ,add,080828,for KeepAlive. */
-	unsigned long NumTxOkTotal;
-	u16 LastRetryCnt;
-	u16 LastRetryRate;
-	unsigned long LastTxokCnt;
-	unsigned long LastRxokCnt;
-	u16 CurrRetryCnt;
-	unsigned long LastTxOKBytes;
-	unsigned long NumTxOkBytesTotal;
-	u8 LastFailTxRate;
-	long LastFailTxRateSS;
-	u8 FailTxRateCount;
-	u32 LastTxThroughput;
-	/* for up rate. */
-	unsigned short bTryuping;
-	u8 CurrTxRate; /* the rate before up. */
-	u16 CurrRetryRate;
-	u16 TryupingCount;
-	u8 TryDownCountLowData;
-	u8 TryupingCountNoData;
-
-	u8 CurrentOperaRate;
-	struct work_struct reset_wq;
-	struct work_struct watch_dog_wq;
-	short ack_tx_to_ieee;
-
-	u8 dma_poll_stop_mask;
-
-	u16 ShortRetryLimit;
-	u16 LongRetryLimit;
-	u16 EarlyRxThreshold;
-	u32 TransmitConfig;
-	u32 ReceiveConfig;
-	u32 IntrMask;
-
-	struct chnl_access_setting ChannelAccessSetting;
-};
-
-#define MANAGE_PRIORITY 0
-#define BK_PRIORITY 1
-#define BE_PRIORITY 2
-#define VI_PRIORITY 3
-#define VO_PRIORITY 4
-#define HI_PRIORITY 5
-#define BEACON_PRIORITY 6
-
-#define LOW_PRIORITY VI_PRIORITY
-#define NORM_PRIORITY VO_PRIORITY
-/* AC2Queue mapping. */
-#define AC2Q(_ac) (((_ac) == WME_AC_VO) ? VO_PRIORITY : \
-		((_ac) == WME_AC_VI) ? VI_PRIORITY : \
-		((_ac) == WME_AC_BK) ? BK_PRIORITY : \
-		BE_PRIORITY)
-
-short rtl8180_tx(struct net_device *dev, u8 *skbuf, int len, int priority,
-		 bool morefrag, short fragdesc, int rate);
-
-u8 read_nic_byte(struct net_device *dev, int x);
-u32 read_nic_dword(struct net_device *dev, int x);
-u16 read_nic_word(struct net_device *dev, int x);
-void write_nic_byte(struct net_device *dev, int x, u8 y);
-void write_nic_word(struct net_device *dev, int x, u16 y);
-void write_nic_dword(struct net_device *dev, int x, u32 y);
-void force_pci_posting(struct net_device *dev);
-
-void rtl8180_rtx_disable(struct net_device *);
-void rtl8180_set_anaparam(struct net_device *dev, u32 a);
-void rtl8185_set_anaparam2(struct net_device *dev, u32 a);
-void rtl8180_set_hw_wep(struct net_device *dev);
-void rtl8180_no_hw_wep(struct net_device *dev);
-void rtl8180_update_msr(struct net_device *dev);
-void rtl8180_beacon_tx_disable(struct net_device *dev);
-void rtl8180_beacon_rx_disable(struct net_device *dev);
-int rtl8180_down(struct net_device *dev);
-int rtl8180_up(struct net_device *dev);
-void rtl8180_commit(struct net_device *dev);
-void rtl8180_set_chan(struct net_device *dev, short ch);
-void write_phy(struct net_device *dev, u8 adr, u8 data);
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
-void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
-void rtl8185_rf_pins_enable(struct net_device *dev);
-void IPSEnter(struct net_device *dev);
-void IPSLeave(struct net_device *dev);
-int get_curr_tx_free_desc(struct net_device *dev, int priority);
-void UpdateInitialGain(struct net_device *dev);
-bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt,
-			  bool bAntDiversity);
-
-void rtl8185b_adapter_start(struct net_device *dev);
-void rtl8185b_rx_enable(struct net_device *dev);
-void rtl8185b_tx_enable(struct net_device *dev);
-void rtl8180_reset(struct net_device *dev);
-void rtl8185b_irq_enable(struct net_device *dev);
-void fix_rx_fifo(struct net_device *dev);
-void fix_tx_fifo(struct net_device *dev);
-void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
-void rtl8180_rate_adapter(struct work_struct *work);
-bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet,
-			 u32 ChangeSource);
-
-#endif
-
-/* fun with the built-in ieee80211 stack... */
-extern int ieee80211_crypto_init(void);
-extern void ieee80211_crypto_deinit(void);
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-extern int ieee80211_crypto_ccmp_init(void);
-extern void ieee80211_crypto_ccmp_exit(void);
-extern int ieee80211_crypto_wep_init(void);
-extern void ieee80211_crypto_wep_exit(void);
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h
deleted file mode 100644
index b52b5b0..0000000
--- a/drivers/staging/rtl8187se/r8180_93cx6.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-	This is part of rtl8180 OpenSource driver
-	Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the official realtek driver
-	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
-	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
-	We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/*This files contains card eeprom (93c46 or 93c56) programming routines*/
-/*memory is addressed by WORDS*/
-
-#include "r8180.h"
-#include "r8180_hw.h"
-
-#define EPROM_DELAY 10
-
-#define EPROM_ANAPARAM_ADDRLWORD 0xd
-#define EPROM_ANAPARAM_ADDRHWORD 0xe
-
-#define RFCHIPID 0x6
-#define	RFCHIPID_INTERSIL 1
-#define	RFCHIPID_RFMD 2
-#define	RFCHIPID_PHILIPS 3
-#define	RFCHIPID_MAXIM 4
-#define	RFCHIPID_GCT 5
-#define RFCHIPID_RTL8225 9
-#define RF_ZEBRA2 11
-#define EPROM_TXPW_BASE 0x05
-#define RF_ZEBRA4 12
-#define RFCHIPID_RTL8255 0xa
-#define RF_PARAM 0x19
-#define RF_PARAM_DIGPHY_SHIFT 0
-#define RF_PARAM_ANTBDEFAULT_SHIFT 1
-#define RF_PARAM_CARRIERSENSE_SHIFT 2
-#define RF_PARAM_CARRIERSENSE_MASK (3<<2)
-#define ENERGY_TRESHOLD 0x17
-#define EPROM_VERSION 0x1E
-#define MAC_ADR 0x7
-
-#define CIS 0x18
-
-#define	EPROM_TXPW_OFDM_CH1_2 0x20
-
-#define	EPROM_TXPW_CH1_2 0x30
-
-#define RTL818X_EEPROM_CMD_READ		(1 << 0)
-#define RTL818X_EEPROM_CMD_WRITE	(1 << 1)
-#define RTL818X_EEPROM_CMD_CK		(1 << 2)
-#define RTL818X_EEPROM_CMD_CS		(1 << 3)
-
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
deleted file mode 100644
index a6022d4..0000000
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ /dev/null
@@ -1,3775 +0,0 @@
-/*
- * This is part of rtl818x pci OpenSource driver - v 0.1
- * Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
- * Released under the terms of GPL (General Public License)
- *
- * Parts of this driver are based on the GPL part of the official
- * Realtek driver.
- *
- * Parts of this driver are based on the rtl8180 driver skeleton
- * from Patric Schenke & Andres Salomon.
- *
- * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
- *
- * Parts of BB/RF code are derived from David Young rtl8180 netbsd driver.
- *
- * RSSI calc function from 'The Deuce'
- *
- * Some ideas borrowed from the 8139too.c driver included in linux kernel.
- *
- * We (I?) want to thanks the Authors of those projecs and also the
- * Ndiswrapper's project Authors.
- *
- * A big big thanks goes also to Realtek corp. for their help in my attempt to
- * add RTL8185 and RTL8225 support, and to David Young also.
- *
- * Power management interface routines.
- * Written by Mariusz Matuszek.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#undef RX_DONT_PASS_UL
-#undef DUMMY_RX
-
-#include <linux/slab.h>
-#include <linux/syscalls.h>
-#include <linux/eeprom_93cx6.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "r8180_hw.h"
-#include "r8180.h"
-#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_93cx6.h"   /* Card EEPROM */
-#include "r8180_wx.h"
-#include "r8180_dm.h"
-
-#include "ieee80211/dot11d.h"
-
-static struct pci_device_id rtl8180_pci_id_tbl[] = {
-	{
-		.vendor = PCI_VENDOR_ID_REALTEK,
-		.device = 0x8199,
-		.subvendor = PCI_ANY_ID,
-		.subdevice = PCI_ANY_ID,
-		.driver_data = 0,
-	},
-	{
-		.vendor = 0,
-		.device = 0,
-		.subvendor = 0,
-		.subdevice = 0,
-		.driver_data = 0,
-	}
-};
-
-static char ifname[IFNAMSIZ] = "wlan%d";
-static int hwwep;
-
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
-MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>");
-MODULE_DESCRIPTION("Linux driver for Realtek RTL8187SE WiFi cards");
-
-module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
-module_param(hwwep, int, S_IRUGO|S_IWUSR);
-
-MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards");
-
-static int rtl8180_pci_probe(struct pci_dev *pdev,
-			     const struct pci_device_id *id);
-
-static void rtl8180_pci_remove(struct pci_dev *pdev);
-
-static void rtl8180_shutdown(struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	if (dev->netdev_ops->ndo_stop)
-		dev->netdev_ops->ndo_stop(dev);
-	pci_disable_device(pdev);
-}
-
-static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-
-	if (!netif_running(dev))
-		goto out_pci_suspend;
-
-	if (dev->netdev_ops->ndo_stop)
-		dev->netdev_ops->ndo_stop(dev);
-
-	netif_device_detach(dev);
-
-out_pci_suspend:
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-	return 0;
-}
-
-static int rtl8180_resume(struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	int err;
-	u32 val;
-
-	pci_set_power_state(pdev, PCI_D0);
-
-	err = pci_enable_device(pdev);
-	if (err) {
-		dev_err(&pdev->dev, "pci_enable_device failed on resume\n");
-
-		return err;
-	}
-
-	pci_restore_state(pdev);
-
-	/*
-	 * Suspend/Resume resets the PCI configuration space, so we have to
-	 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
-	 * from interfering with C3 CPU state. pci_restore_state won't help
-	 * here since it only restores the first 64 bytes pci config header.
-	 */
-	pci_read_config_dword(pdev, 0x40, &val);
-	if ((val & 0x0000ff00) != 0)
-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
-	if (!netif_running(dev))
-		goto out;
-
-	if (dev->netdev_ops->ndo_open)
-		dev->netdev_ops->ndo_open(dev);
-
-	netif_device_attach(dev);
-out:
-	return 0;
-}
-
-static struct pci_driver rtl8180_pci_driver = {
-	.name		= RTL8180_MODULE_NAME,
-	.id_table	= rtl8180_pci_id_tbl,
-	.probe		= rtl8180_pci_probe,
-	.remove		= rtl8180_pci_remove,
-	.suspend	= rtl8180_suspend,
-	.resume		= rtl8180_resume,
-	.shutdown	= rtl8180_shutdown,
-};
-
-u8 read_nic_byte(struct net_device *dev, int x)
-{
-	return 0xff&readb((u8 __iomem *)dev->mem_start + x);
-}
-
-u32 read_nic_dword(struct net_device *dev, int x)
-{
-	return readl((u8 __iomem *)dev->mem_start + x);
-}
-
-u16 read_nic_word(struct net_device *dev, int x)
-{
-	return readw((u8 __iomem *)dev->mem_start + x);
-}
-
-void write_nic_byte(struct net_device *dev, int x, u8 y)
-{
-	writeb(y, (u8 __iomem *)dev->mem_start + x);
-	udelay(20);
-}
-
-void write_nic_dword(struct net_device *dev, int x, u32 y)
-{
-	writel(y, (u8 __iomem *)dev->mem_start + x);
-	udelay(20);
-}
-
-void write_nic_word(struct net_device *dev, int x, u16 y)
-{
-	writew(y, (u8 __iomem *)dev->mem_start + x);
-	udelay(20);
-}
-
-inline void force_pci_posting(struct net_device *dev)
-{
-	read_nic_byte(dev, EPROM_CMD);
-	mb();
-}
-
-static irqreturn_t rtl8180_interrupt(int irq, void *netdev);
-void set_nic_rxring(struct net_device *dev);
-void set_nic_txring(struct net_device *dev);
-static struct net_device_stats *rtl8180_stats(struct net_device *dev);
-void rtl8180_commit(struct net_device *dev);
-void rtl8180_start_tx_beacon(struct net_device *dev);
-
-static struct proc_dir_entry *rtl8180_proc;
-
-static int proc_get_registers(struct seq_file *m, void *v)
-{
-	struct net_device *dev = m->private;
-	int i, n, max = 0xff;
-
-	/* This dump the current register page */
-	for (n = 0; n <= max;) {
-		seq_printf(m, "\nD:  %2x > ", n);
-
-		for (i = 0; i < 16 && n <= max; i++, n++)
-			seq_printf(m, "%2x ", read_nic_byte(dev, n));
-	}
-	seq_putc(m, '\n');
-	return 0;
-}
-
-int get_curr_tx_free_desc(struct net_device *dev, int priority);
-
-static int proc_get_stats_hw(struct seq_file *m, void *v)
-{
-	return 0;
-}
-
-static int proc_get_stats_rx(struct seq_file *m, void *v)
-{
-	struct net_device *dev = m->private;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	seq_printf(m,
-		"RX OK: %lu\n"
-		"RX Retry: %lu\n"
-		"RX CRC Error(0-500): %lu\n"
-		"RX CRC Error(500-1000): %lu\n"
-		"RX CRC Error(>1000): %lu\n"
-		"RX ICV Error: %lu\n",
-		priv->stats.rxint,
-		priv->stats.rxerr,
-		priv->stats.rxcrcerrmin,
-		priv->stats.rxcrcerrmid,
-		priv->stats.rxcrcerrmax,
-		priv->stats.rxicverr
-		);
-
-	return 0;
-}
-
-static int proc_get_stats_tx(struct seq_file *m, void *v)
-{
-	struct net_device *dev = m->private;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	unsigned long totalOK;
-
-	totalOK = priv->stats.txnpokint + priv->stats.txhpokint +
-		priv->stats.txlpokint;
-
-	seq_printf(m,
-		"TX OK: %lu\n"
-		"TX Error: %lu\n"
-		"TX Retry: %lu\n"
-		"TX beacon OK: %lu\n"
-		"TX beacon error: %lu\n",
-		totalOK,
-		priv->stats.txnperr+priv->stats.txhperr+priv->stats.txlperr,
-		priv->stats.txretry,
-		priv->stats.txbeacon,
-		priv->stats.txbeaconerr
-	);
-
-	return 0;
-}
-
-static void rtl8180_proc_module_init(void)
-{
-	DMESG("Initializing proc filesystem");
-	rtl8180_proc = proc_mkdir(RTL8180_MODULE_NAME, init_net.proc_net);
-}
-
-static void rtl8180_proc_module_remove(void)
-{
-	remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
-}
-
-static void rtl8180_proc_remove_one(struct net_device *dev)
-{
-	remove_proc_subtree(dev->name, rtl8180_proc);
-}
-
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int rtl8180_proc_open(struct inode *inode, struct file *file)
-{
-	struct net_device *dev = proc_get_parent_data(inode);
-	int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
-
-	return single_open(file, show, dev);
-}
-
-static const struct file_operations rtl8180_proc_fops = {
-	.open		= rtl8180_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-/*
- * Table of proc files we need to create.
- */
-struct rtl8180_proc_file {
-	char name[12];
-	int (*show)(struct seq_file *, void *);
-};
-
-static const struct rtl8180_proc_file rtl8180_proc_files[] = {
-	{ "stats-hw",	&proc_get_stats_hw },
-	{ "stats-rx",	&proc_get_stats_rx },
-	{ "stats-tx",	&proc_get_stats_tx },
-	{ "registers",	&proc_get_registers },
-	{ "" }
-};
-
-static void rtl8180_proc_init_one(struct net_device *dev)
-{
-	const struct rtl8180_proc_file *f;
-	struct proc_dir_entry *dir;
-
-	dir = proc_mkdir_data(dev->name, 0, rtl8180_proc, dev);
-	if (!dir) {
-		DMESGE("Unable to initialize /proc/net/r8180/%s\n", dev->name);
-		return;
-	}
-
-	for (f = rtl8180_proc_files; f->name[0]; f++) {
-		if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
-				      &rtl8180_proc_fops, f->show)) {
-			DMESGE("Unable to initialize /proc/net/r8180/%s/%s\n",
-			       dev->name, f->name);
-			return;
-		}
-	}
-}
-
-/*
- * FIXME: check if we can use some standard already-existent
- * data type+functions in kernel.
- */
-
-static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
-			struct buffer **bufferhead)
-{
-	struct buffer *tmp;
-
-	if (!*buffer) {
-
-		*buffer = kmalloc(sizeof(struct buffer), GFP_KERNEL);
-
-		if (*buffer == NULL) {
-			DMESGE("Failed to kmalloc head of TX/RX struct");
-			return -1;
-		}
-		(*buffer)->next = *buffer;
-		(*buffer)->buf = buf;
-		(*buffer)->dma = dma;
-		if (bufferhead != NULL)
-			(*bufferhead) = (*buffer);
-		return 0;
-	}
-	tmp = *buffer;
-
-	while (tmp->next != (*buffer))
-		tmp = tmp->next;
-	tmp->next = kmalloc(sizeof(struct buffer), GFP_KERNEL);
-	if (tmp->next == NULL) {
-		DMESGE("Failed to kmalloc TX/RX struct");
-		return -1;
-	}
-	tmp->next->buf = buf;
-	tmp->next->dma = dma;
-	tmp->next->next = *buffer;
-
-	return 0;
-}
-
-static void buffer_free(struct net_device *dev, struct buffer **buffer, int len,
-		 short consistent)
-{
-
-	struct buffer *tmp, *next;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct pci_dev *pdev = priv->pdev;
-
-	if (!*buffer)
-		return;
-
-	tmp = *buffer;
-
-	do {
-		next = tmp->next;
-		if (consistent) {
-			pci_free_consistent(pdev, len,
-				    tmp->buf, tmp->dma);
-		} else {
-			pci_unmap_single(pdev, tmp->dma,
-			len, PCI_DMA_FROMDEVICE);
-			kfree(tmp->buf);
-		}
-		kfree(tmp);
-		tmp = next;
-	} while (next != *buffer);
-
-	*buffer = NULL;
-}
-
-int get_curr_tx_free_desc(struct net_device *dev, int priority)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 *tail;
-	u32 *head;
-	int ret;
-
-	switch (priority) {
-	case MANAGE_PRIORITY:
-		head = priv->txmapringhead;
-		tail = priv->txmapringtail;
-		break;
-	case BK_PRIORITY:
-		head = priv->txbkpringhead;
-		tail = priv->txbkpringtail;
-		break;
-	case BE_PRIORITY:
-		head = priv->txbepringhead;
-		tail = priv->txbepringtail;
-		break;
-	case VI_PRIORITY:
-		head = priv->txvipringhead;
-		tail = priv->txvipringtail;
-		break;
-	case VO_PRIORITY:
-		head = priv->txvopringhead;
-		tail = priv->txvopringtail;
-		break;
-	case HI_PRIORITY:
-		head = priv->txhpringhead;
-		tail = priv->txhpringtail;
-		break;
-	default:
-		return -1;
-	}
-
-	if (head <= tail)
-		ret = priv->txringcount - (tail - head)/8;
-	else
-		ret = (head - tail)/8;
-
-	if (ret > priv->txringcount)
-		DMESG("BUG");
-
-	return ret;
-}
-
-static short check_nic_enought_desc(struct net_device *dev, int priority)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = netdev_priv(dev);
-	int requiredbyte;
-	int required;
-
-	requiredbyte = priv->ieee80211->fts +
-		sizeof(struct ieee80211_header_data);
-
-	if (ieee->current_network.QoS_Enable)
-		requiredbyte += 2;
-
-	required = requiredbyte / (priv->txbuffsize-4);
-
-	if (requiredbyte % priv->txbuffsize)
-		required++;
-
-	/* for now we keep two free descriptor as a safety boundary
-	 * between the tail and the head
-	 */
-
-	return required + 2 < get_curr_tx_free_desc(dev, priority);
-}
-
-void fix_tx_fifo(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u32 *tmp;
-	int i;
-
-	for (tmp = priv->txmapring, i = 0;
-	     i < priv->txringcount;
-	     tmp += 8, i++) {
-		*tmp = *tmp & ~(1<<31);
-	}
-
-	for (tmp = priv->txbkpring, i = 0;
-	     i < priv->txringcount;
-	     tmp += 8, i++) {
-		*tmp = *tmp & ~(1<<31);
-	}
-
-	for (tmp = priv->txbepring, i = 0;
-	     i < priv->txringcount;
-	     tmp += 8, i++) {
-		*tmp = *tmp & ~(1<<31);
-	}
-	for (tmp = priv->txvipring, i = 0;
-	     i < priv->txringcount;
-	     tmp += 8, i++) {
-		*tmp = *tmp & ~(1<<31);
-	}
-
-	for (tmp = priv->txvopring, i = 0;
-	     i < priv->txringcount;
-	     tmp += 8, i++) {
-		*tmp = *tmp & ~(1<<31);
-	}
-
-	for (tmp = priv->txhpring, i = 0;
-	     i < priv->txringcount;
-	     tmp += 8, i++) {
-		*tmp = *tmp & ~(1<<31);
-	}
-
-	for (tmp = priv->txbeaconring, i = 0;
-	     i < priv->txbeaconcount;
-	     tmp += 8, i++) {
-		*tmp = *tmp & ~(1<<31);
-	}
-
-	priv->txmapringtail = priv->txmapring;
-	priv->txmapringhead = priv->txmapring;
-	priv->txmapbufstail = priv->txmapbufs;
-
-	priv->txbkpringtail = priv->txbkpring;
-	priv->txbkpringhead = priv->txbkpring;
-	priv->txbkpbufstail = priv->txbkpbufs;
-
-	priv->txbepringtail = priv->txbepring;
-	priv->txbepringhead = priv->txbepring;
-	priv->txbepbufstail = priv->txbepbufs;
-
-	priv->txvipringtail = priv->txvipring;
-	priv->txvipringhead = priv->txvipring;
-	priv->txvipbufstail = priv->txvipbufs;
-
-	priv->txvopringtail = priv->txvopring;
-	priv->txvopringhead = priv->txvopring;
-	priv->txvopbufstail = priv->txvopbufs;
-
-	priv->txhpringtail = priv->txhpring;
-	priv->txhpringhead = priv->txhpring;
-	priv->txhpbufstail = priv->txhpbufs;
-
-	priv->txbeaconringtail = priv->txbeaconring;
-	priv->txbeaconbufstail = priv->txbeaconbufs;
-	set_nic_txring(dev);
-
-	ieee80211_reset_queue(priv->ieee80211);
-	priv->ack_tx_to_ieee = 0;
-}
-
-void fix_rx_fifo(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u32 *tmp;
-	struct buffer *rxbuf;
-	u8 rx_desc_size;
-
-	rx_desc_size = 8; /* 4*8 = 32 bytes */
-
-	for (tmp = priv->rxring, rxbuf = priv->rxbufferhead;
-	     (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size);
-	     tmp += rx_desc_size, rxbuf = rxbuf->next) {
-		*(tmp+2) = rxbuf->dma;
-		*tmp = *tmp & ~0xfff;
-		*tmp = *tmp | priv->rxbuffersize;
-		*tmp |= (1<<31);
-	}
-
-	priv->rxringtail = priv->rxring;
-	priv->rxbuffer = priv->rxbufferhead;
-	priv->rx_skb_complete = 1;
-	set_nic_rxring(dev);
-}
-
-static void rtl8180_irq_disable(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	write_nic_dword(dev, IMR, 0);
-	force_pci_posting(dev);
-	priv->irq_enabled = 0;
-}
-
-void rtl8180_set_mode(struct net_device *dev, int mode)
-{
-	u8 ecmd;
-
-	ecmd = read_nic_byte(dev, EPROM_CMD);
-	ecmd = ecmd & ~EPROM_CMD_OPERATING_MODE_MASK;
-	ecmd = ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
-	ecmd = ecmd & ~(1<<EPROM_CS_SHIFT);
-	ecmd = ecmd & ~(1<<EPROM_CK_SHIFT);
-	write_nic_byte(dev, EPROM_CMD, ecmd);
-}
-
-void rtl8180_beacon_tx_enable(struct net_device *dev);
-
-void rtl8180_update_msr(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 msr;
-	u32 rxconf;
-
-	msr  = read_nic_byte(dev, MSR);
-	msr &= ~MSR_LINK_MASK;
-
-	rxconf = read_nic_dword(dev, RX_CONF);
-
-	if (priv->ieee80211->state == IEEE80211_LINKED)	{
-		if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
-			msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
-		else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
-			msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
-		else if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
-			msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
-		else
-			msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
-		rxconf |= (1<<RX_CHECK_BSSID_SHIFT);
-
-	} else {
-		msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
-		rxconf &= ~(1<<RX_CHECK_BSSID_SHIFT);
-	}
-
-	write_nic_byte(dev, MSR, msr);
-	write_nic_dword(dev, RX_CONF, rxconf);
-}
-
-void rtl8180_set_chan(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	if ((ch > 14) || (ch < 1)) {
-		netdev_err(dev, "In %s: Invalid channel %d\n", __func__, ch);
-		return;
-	}
-
-	priv->chan = ch;
-	priv->rf_set_chan(dev, priv->chan);
-}
-
-void set_nic_txring(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	write_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR, priv->txmapringdma);
-	write_nic_dword(dev, TX_BKPRIORITY_RING_ADDR, priv->txbkpringdma);
-	write_nic_dword(dev, TX_BEPRIORITY_RING_ADDR, priv->txbepringdma);
-	write_nic_dword(dev, TX_VIPRIORITY_RING_ADDR, priv->txvipringdma);
-	write_nic_dword(dev, TX_VOPRIORITY_RING_ADDR, priv->txvopringdma);
-	write_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR, priv->txhpringdma);
-	write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
-}
-
-void rtl8180_beacon_tx_enable(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);
-	write_nic_byte(dev, TPPollStop, priv->dma_poll_mask);
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8180_beacon_tx_disable(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ;
-	write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
-}
-
-void rtl8180_rtx_disable(struct net_device *dev)
-{
-	u8 cmd;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	cmd = read_nic_byte(dev, CMD);
-	write_nic_byte(dev, CMD, cmd &
-		       ~((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
-	force_pci_posting(dev);
-	mdelay(10);
-
-	if (!priv->rx_skb_complete)
-		dev_kfree_skb_any(priv->rx_skb);
-}
-
-static short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
-				int addr)
-{
-	int i;
-	u32 *desc;
-	u32 *tmp;
-	dma_addr_t dma_desc, dma_tmp;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct pci_dev *pdev = priv->pdev;
-	void *buf;
-
-	if ((bufsize & 0xfff) != bufsize) {
-		DMESGE("TX buffer allocation too large");
-		return 0;
-	}
-	desc = (u32 *)pci_alloc_consistent(pdev,
-					  sizeof(u32)*8*count+256, &dma_desc);
-	if (desc == NULL)
-		return -1;
-
-	if (dma_desc & 0xff)
-		/*
-		 * descriptor's buffer must be 256 byte aligned
-		 * we shouldn't be here, since we set DMA mask !
-		 */
-		WARN(1, "DMA buffer is not aligned\n");
-
-	tmp = desc;
-
-	for (i = 0; i < count; i++) {
-		buf = (void *)pci_alloc_consistent(pdev, bufsize, &dma_tmp);
-		if (buf == NULL)
-			return -ENOMEM;
-
-		switch (addr) {
-		case TX_MANAGEPRIORITY_RING_ADDR:
-			if (-1 == buffer_add(&priv->txmapbufs,
-				buf, dma_tmp, NULL)) {
-				DMESGE("Unable to allocate mem for buffer NP");
-				return -ENOMEM;
-			}
-			break;
-		case TX_BKPRIORITY_RING_ADDR:
-			if (-1 == buffer_add(&priv->txbkpbufs,
-				buf, dma_tmp, NULL)) {
-				DMESGE("Unable to allocate mem for buffer LP");
-				return -ENOMEM;
-			}
-			break;
-		case TX_BEPRIORITY_RING_ADDR:
-			if (-1 == buffer_add(&priv->txbepbufs,
-				buf, dma_tmp, NULL)) {
-				DMESGE("Unable to allocate mem for buffer NP");
-				return -ENOMEM;
-			}
-			break;
-		case TX_VIPRIORITY_RING_ADDR:
-			if (-1 == buffer_add(&priv->txvipbufs,
-				buf, dma_tmp, NULL)) {
-				DMESGE("Unable to allocate mem for buffer LP");
-				return -ENOMEM;
-			}
-			break;
-		case TX_VOPRIORITY_RING_ADDR:
-			if (-1 == buffer_add(&priv->txvopbufs,
-				buf, dma_tmp, NULL)) {
-				DMESGE("Unable to allocate mem for buffer NP");
-				return -ENOMEM;
-			}
-			break;
-		case TX_HIGHPRIORITY_RING_ADDR:
-			if (-1 == buffer_add(&priv->txhpbufs,
-				buf, dma_tmp, NULL)) {
-				DMESGE("Unable to allocate mem for buffer HP");
-				return -ENOMEM;
-			}
-			break;
-		case TX_BEACON_RING_ADDR:
-			if (-1 == buffer_add(&priv->txbeaconbufs,
-				buf, dma_tmp, NULL)) {
-				DMESGE("Unable to allocate mem for buffer BP");
-				return -ENOMEM;
-			}
-			break;
-		}
-		*tmp = *tmp & ~(1<<31); /* descriptor empty, owned by the drv */
-		*(tmp+2) = (u32)dma_tmp;
-		*(tmp+3) = bufsize;
-
-		if (i+1 < count)
-			*(tmp+4) = (u32)dma_desc+((i+1)*8*4);
-		else
-			*(tmp+4) = (u32)dma_desc;
-
-		tmp = tmp+8;
-	}
-
-	switch (addr) {
-	case TX_MANAGEPRIORITY_RING_ADDR:
-		priv->txmapringdma = dma_desc;
-		priv->txmapring = desc;
-		break;
-	case TX_BKPRIORITY_RING_ADDR:
-		priv->txbkpringdma = dma_desc;
-		priv->txbkpring = desc;
-		break;
-	case TX_BEPRIORITY_RING_ADDR:
-		priv->txbepringdma = dma_desc;
-		priv->txbepring = desc;
-		break;
-	case TX_VIPRIORITY_RING_ADDR:
-		priv->txvipringdma = dma_desc;
-		priv->txvipring = desc;
-		break;
-	case TX_VOPRIORITY_RING_ADDR:
-		priv->txvopringdma = dma_desc;
-		priv->txvopring = desc;
-		break;
-	case TX_HIGHPRIORITY_RING_ADDR:
-		priv->txhpringdma = dma_desc;
-		priv->txhpring = desc;
-		break;
-	case TX_BEACON_RING_ADDR:
-		priv->txbeaconringdma = dma_desc;
-		priv->txbeaconring = desc;
-		break;
-
-	}
-
-	return 0;
-}
-
-static void free_tx_desc_rings(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct pci_dev *pdev = priv->pdev;
-	int count = priv->txringcount;
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txmapring, priv->txmapringdma);
-	buffer_free(dev, &(priv->txmapbufs), priv->txbuffsize, 1);
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txbkpring, priv->txbkpringdma);
-	buffer_free(dev, &(priv->txbkpbufs), priv->txbuffsize, 1);
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txbepring, priv->txbepringdma);
-	buffer_free(dev, &(priv->txbepbufs), priv->txbuffsize, 1);
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txvipring, priv->txvipringdma);
-	buffer_free(dev, &(priv->txvipbufs), priv->txbuffsize, 1);
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txvopring, priv->txvopringdma);
-	buffer_free(dev, &(priv->txvopbufs), priv->txbuffsize, 1);
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txhpring, priv->txhpringdma);
-	buffer_free(dev, &(priv->txhpbufs), priv->txbuffsize, 1);
-
-	count = priv->txbeaconcount;
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txbeaconring, priv->txbeaconringdma);
-	buffer_free(dev, &(priv->txbeaconbufs), priv->txbuffsize, 1);
-}
-
-static void free_rx_desc_ring(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct pci_dev *pdev = priv->pdev;
-	int count = priv->rxringcount;
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->rxring, priv->rxringdma);
-
-	buffer_free(dev, &(priv->rxbuffer), priv->rxbuffersize, 0);
-}
-
-static short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
-{
-	int i;
-	u32 *desc;
-	u32 *tmp;
-	dma_addr_t dma_desc, dma_tmp;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct pci_dev *pdev = priv->pdev;
-	void *buf;
-	u8 rx_desc_size;
-
-	rx_desc_size = 8; /* 4*8 = 32 bytes */
-
-	if ((bufsize & 0xfff) != bufsize) {
-		DMESGE("RX buffer allocation too large");
-		return -1;
-	}
-
-	desc = (u32 *)pci_alloc_consistent(pdev,
-		sizeof(u32) * rx_desc_size * count + 256, &dma_desc);
-
-	if (dma_desc & 0xff)
-		/*
-		 * descriptor's buffer must be 256 byte aligned
-		 * should never happen since we specify the DMA mask
-		 */
-		WARN(1, "DMA buffer is not aligned\n");
-
-	priv->rxring = desc;
-	priv->rxringdma = dma_desc;
-	tmp = desc;
-
-	for (i = 0; i < count; i++) {
-		buf = kmalloc(bufsize * sizeof(u8), GFP_ATOMIC);
-		if (buf == NULL) {
-			DMESGE("Failed to kmalloc RX buffer");
-			return -1;
-		}
-
-		dma_tmp = pci_map_single(pdev, buf, bufsize * sizeof(u8),
-					 PCI_DMA_FROMDEVICE);
-		if (pci_dma_mapping_error(pdev, dma_tmp))
-			return -1;
-		if (-1 == buffer_add(&(priv->rxbuffer), buf, dma_tmp,
-			   &(priv->rxbufferhead))) {
-			DMESGE("Unable to allocate mem RX buf");
-			return -1;
-		}
-		*tmp = 0; /* zero pads the header of the descriptor */
-		*tmp = *tmp | (bufsize&0xfff);
-		*(tmp+2) = (u32)dma_tmp;
-		*tmp = *tmp | (1<<31); /* descriptor void, owned by the NIC */
-
-		tmp = tmp+rx_desc_size;
-	}
-
-	/* this is the last descriptor */
-	*(tmp - rx_desc_size) = *(tmp - rx_desc_size) | (1 << 30);
-
-	return 0;
-}
-
-
-void set_nic_rxring(struct net_device *dev)
-{
-	u8 pgreg;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	pgreg = read_nic_byte(dev, PGSELECT);
-	write_nic_byte(dev, PGSELECT, pgreg & ~(1<<PGSELECT_PG_SHIFT));
-
-	write_nic_dword(dev, RXRING_ADDR, priv->rxringdma);
-}
-
-void rtl8180_reset(struct net_device *dev)
-{
-	u8 cr;
-
-	rtl8180_irq_disable(dev);
-
-	cr = read_nic_byte(dev, CMD);
-	cr = cr & 2;
-	cr = cr | (1<<CMD_RST_SHIFT);
-	write_nic_byte(dev, CMD, cr);
-
-	force_pci_posting(dev);
-
-	mdelay(200);
-
-	if (read_nic_byte(dev, CMD) & (1<<CMD_RST_SHIFT))
-		DMESGW("Card reset timeout!");
-	else
-		DMESG("Card successfully reset");
-
-	rtl8180_set_mode(dev, EPROM_CMD_LOAD);
-	force_pci_posting(dev);
-	mdelay(200);
-}
-
-inline u16 ieeerate2rtlrate(int rate)
-{
-	switch (rate) {
-	case 10:
-		return 0;
-	case 20:
-		return 1;
-	case 55:
-		return 2;
-	case 110:
-		return 3;
-	case 60:
-		return 4;
-	case 90:
-		return 5;
-	case 120:
-		return 6;
-	case 180:
-		return 7;
-	case 240:
-		return 8;
-	case 360:
-		return 9;
-	case 480:
-		return 10;
-	case 540:
-		return 11;
-	default:
-		return 3;
-	}
-}
-
-static u16 rtl_rate[] = {10, 20, 55, 110, 60,
-	90, 120, 180, 240, 360, 480, 540, 720};
-
-inline u16 rtl8180_rate2rate(short rate)
-{
-	if (rate > 12)
-		return 10;
-	return rtl_rate[rate];
-}
-
-inline u8 rtl8180_IsWirelessBMode(u16 rate)
-{
-	if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
-		return 1;
-	else
-		return 0;
-}
-
-u16 N_DBPSOfRate(u16 DataRate);
-
-static u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame,
-		  u8 bShortPreamble)
-{
-	u16	FrameTime;
-	u16	N_DBPS;
-	u16	Ceiling;
-
-	if (rtl8180_IsWirelessBMode(DataRate)) {
-		if (bManagementFrame || !bShortPreamble || DataRate == 10)
-			/* long preamble */
-			FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
-		else
-			/* short preamble */
-			FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
-
-		if ((FrameLength*8 % (DataRate/10)) != 0) /* get the ceilling */
-			FrameTime++;
-	} else {	/* 802.11g DSSS-OFDM PLCP length field calculation. */
-		N_DBPS = N_DBPSOfRate(DataRate);
-		Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
-				+ (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
-		FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
-	}
-	return FrameTime;
-}
-
-u16 N_DBPSOfRate(u16 DataRate)
-{
-	 u16 N_DBPS = 24;
-
-	switch (DataRate) {
-	case 60:
-		N_DBPS = 24;
-		break;
-	case 90:
-		N_DBPS = 36;
-		break;
-	case 120:
-		N_DBPS = 48;
-		break;
-	case 180:
-		N_DBPS = 72;
-		break;
-	case 240:
-		N_DBPS = 96;
-		break;
-	case 360:
-		N_DBPS = 144;
-		break;
-	case 480:
-		N_DBPS = 192;
-		break;
-	case 540:
-		N_DBPS = 216;
-		break;
-	default:
-		break;
-	}
-
-	return N_DBPS;
-}
-
-/*
- * For Netgear case, they want good-looking signal strength.
- */
-static long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
-{
-	long RetSS;
-
-	/* Step 1. Scale mapping. */
-	if (CurrSS >= 71 && CurrSS <= 100)
-		RetSS = 90 + ((CurrSS - 70) / 3);
-	else if (CurrSS >= 41 && CurrSS <= 70)
-		RetSS = 78 + ((CurrSS - 40) / 3);
-	else if (CurrSS >= 31 && CurrSS <= 40)
-		RetSS = 66 + (CurrSS - 30);
-	else if (CurrSS >= 21 && CurrSS <= 30)
-		RetSS = 54 + (CurrSS - 20);
-	else if (CurrSS >= 5 && CurrSS <= 20)
-		RetSS = 42 + (((CurrSS - 5) * 2) / 3);
-	else if (CurrSS == 4)
-		RetSS = 36;
-	else if (CurrSS == 3)
-		RetSS = 27;
-	else if (CurrSS == 2)
-		RetSS = 18;
-	else if (CurrSS == 1)
-		RetSS = 9;
-	else
-		RetSS = CurrSS;
-
-	/* Step 2. Smoothing. */
-	if (LastSS > 0)
-		RetSS = ((LastSS * 5) + (RetSS) + 5) / 6;
-
-	return RetSS;
-}
-
-/*
- * Translate 0-100 signal strength index into dBm.
- */
-static long TranslateToDbm8185(u8 SignalStrengthIndex)
-{
-	long SignalPower;
-
-	/* Translate to dBm (x=0.5y-95). */
-	SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
-	SignalPower -= 95;
-
-	return SignalPower;
-}
-
-/*
- * Perform signal smoothing for dynamic mechanism.
- * This is different with PerformSignalSmoothing8185 in smoothing formula.
- * No dramatic adjustment is applied because dynamic mechanism need some
- * degree of correctness. Ported from 8187B.
- */
-static void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
-						  bool bCckRate)
-{
-	long smoothedSS;
-	long smoothedRx;
-
-	/* Determine the current packet is CCK rate. */
-	priv->bCurCCKPkt = bCckRate;
-
-	smoothedSS = priv->SignalStrength * 10;
-
-	if (priv->UndecoratedSmoothedSS >= 0)
-		smoothedSS = ((priv->UndecoratedSmoothedSS * 5) +
-				smoothedSS) / 6;
-
-	priv->UndecoratedSmoothedSS = smoothedSS;
-
-	smoothedRx = ((priv->UndecoratedSmoothedRxPower * 50) +
-			(priv->RxPower * 11)) / 60;
-
-	priv->UndecoratedSmoothedRxPower = smoothedRx;
-
-	if (bCckRate)
-		priv->CurCCKRSSI = priv->RSSI;
-	else
-		priv->CurCCKRSSI = 0;
-}
-
-
-/*
- * This is rough RX isr handling routine
- */
-static void rtl8180_rx(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct sk_buff *tmp_skb;
-	short first, last;
-	u32 len;
-	int lastlen;
-	unsigned char quality, signal;
-	u8 rate;
-	u32 *tmp, *tmp2;
-	u8 rx_desc_size;
-	u8 padding;
-	char rxpower = 0;
-	u32 RXAGC = 0;
-	long RxAGC_dBm = 0;
-	u8	LNA = 0, BB = 0;
-	u8	LNA_gain[4] = {02, 17, 29, 39};
-	u8  Antenna = 0;
-	struct ieee80211_hdr_4addr *hdr;
-	u16 fc, type;
-	u8 bHwError = 0, bCRC = 0, bICV = 0;
-	bool	bCckRate = false;
-	u8     RSSI = 0;
-	long	SignalStrengthIndex = 0;
-	struct ieee80211_rx_stats stats = {
-		.signal = 0,
-		.noise = -98,
-		.rate = 0,
-		.freq = IEEE80211_24GHZ_BAND,
-	};
-
-	stats.nic_type = NIC_8185B;
-	rx_desc_size = 8;
-
-	if ((*(priv->rxringtail)) & (1<<31)) {
-		/* we have got an RX int, but the descriptor. we are pointing
-		 * is empty.
-		 */
-
-		priv->stats.rxnodata++;
-		priv->ieee80211->stats.rx_errors++;
-
-		tmp2 = NULL;
-		tmp = priv->rxringtail;
-		do {
-			if (tmp == priv->rxring)
-				tmp  = priv->rxring + (priv->rxringcount - 1) *
-					rx_desc_size;
-			else
-				tmp -= rx_desc_size;
-
-			if (!(*tmp & (1<<31)))
-				tmp2 = tmp;
-		} while (tmp != priv->rxring);
-
-		if (tmp2)
-			priv->rxringtail = tmp2;
-	}
-
-	/* while there are filled descriptors */
-	while (!(*(priv->rxringtail) & (1<<31))) {
-		if (*(priv->rxringtail) & (1<<26))
-			DMESGW("RX buffer overflow");
-		if (*(priv->rxringtail) & (1<<12))
-			priv->stats.rxicverr++;
-
-		if (*(priv->rxringtail) & (1<<27)) {
-			priv->stats.rxdmafail++;
-			goto drop;
-		}
-
-		pci_dma_sync_single_for_cpu(priv->pdev,
-				    priv->rxbuffer->dma,
-				    priv->rxbuffersize * sizeof(u8),
-				    PCI_DMA_FROMDEVICE);
-
-		first = *(priv->rxringtail) & (1<<29) ? 1 : 0;
-		if (first)
-			priv->rx_prevlen = 0;
-
-		last = *(priv->rxringtail) & (1<<28) ? 1 : 0;
-		if (last) {
-			lastlen = ((*priv->rxringtail) & 0xfff);
-
-			/* if the last descriptor (that should tell us the total
-			 * packet len) tell us something less than the
-			 * descriptors len we had until now, then there is some
-			 * problem..
-			 * workaround to prevent kernel panic
-			 */
-			if (lastlen < priv->rx_prevlen)
-				len = 0;
-			else
-				len = lastlen-priv->rx_prevlen;
-
-			if (*(priv->rxringtail) & (1<<13)) {
-				if ((*(priv->rxringtail) & 0xfff) < 500)
-					priv->stats.rxcrcerrmin++;
-				else if ((*(priv->rxringtail) & 0x0fff) > 1000)
-					priv->stats.rxcrcerrmax++;
-				else
-					priv->stats.rxcrcerrmid++;
-
-			}
-
-		} else {
-			len = priv->rxbuffersize;
-		}
-
-		if (first && last) {
-			padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
-		} else if (first) {
-			padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
-			if (padding)
-				len -= 2;
-		} else {
-			padding = 0;
-		}
-		padding = 0;
-		priv->rx_prevlen += len;
-
-		if (priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100) {
-			/* HW is probably passing several buggy frames without
-			 * FD or LD flag set.
-			 * Throw this garbage away to prevent skb memory
-			 * exhausting
-			 */
-			if (!priv->rx_skb_complete)
-				dev_kfree_skb_any(priv->rx_skb);
-			priv->rx_skb_complete = 1;
-		}
-
-		signal = (unsigned char)((*(priv->rxringtail + 3) &
-			0x00ff0000) >> 16);
-		signal = (signal & 0xfe) >> 1;
-
-		quality = (unsigned char)((*(priv->rxringtail+3)) & (0xff));
-
-		stats.mac_time[0] = *(priv->rxringtail+1);
-		stats.mac_time[1] = *(priv->rxringtail+2);
-
-		rxpower = ((char)((*(priv->rxringtail + 4) &
-			0x00ff0000) >> 16)) / 2 - 42;
-
-		RSSI = ((u8)((*(priv->rxringtail + 3) &
-			0x0000ff00) >> 8)) & 0x7f;
-
-		rate = ((*(priv->rxringtail)) &
-			((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
-
-		stats.rate = rtl8180_rate2rate(rate);
-		Antenna = (*(priv->rxringtail + 3) & 0x00008000) == 0 ? 0 : 1;
-		if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */
-			RxAGC_dBm = rxpower+1;	/* bias */
-		} else { /* CCK rate. */
-			RxAGC_dBm = signal; /* bit 0 discard */
-
-			LNA = (u8) (RxAGC_dBm & 0x60) >> 5; /* bit 6~ bit 5 */
-			BB  = (u8) (RxAGC_dBm & 0x1F); /* bit 4 ~ bit 0 */
-
-			/* Pin_11b=-(LNA_gain+BB_gain) (dBm) */
-			RxAGC_dBm = -(LNA_gain[LNA] + (BB * 2));
-
-			RxAGC_dBm += 4; /* bias */
-		}
-
-		if (RxAGC_dBm & 0x80) /* absolute value */
-			RXAGC = ~(RxAGC_dBm)+1;
-		bCckRate = rtl8180_IsWirelessBMode(stats.rate);
-		/* Translate RXAGC into 1-100. */
-		if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */
-			if (RXAGC > 90)
-				RXAGC = 90;
-			else if (RXAGC < 25)
-				RXAGC = 25;
-			RXAGC = (90-RXAGC)*100/65;
-		} else { /* CCK rate. */
-			if (RXAGC > 95)
-				RXAGC = 95;
-			else if (RXAGC < 30)
-				RXAGC = 30;
-			RXAGC = (95-RXAGC)*100/65;
-		}
-		priv->SignalStrength = (u8)RXAGC;
-		priv->RecvSignalPower = RxAGC_dBm;
-		priv->RxPower = rxpower;
-		priv->RSSI = RSSI;
-		/* SQ translation formula is provided by SD3 DZ. 2006.06.27 */
-		if (quality >= 127)
-			/* 0 causes epc to show signal zero, walk around now */
-			quality = 1;
-		else if (quality < 27)
-			quality = 100;
-		else
-			quality = 127 - quality;
-		priv->SignalQuality = quality;
-
-		stats.signal = (u8) quality;
-
-		stats.signalstrength = RXAGC;
-		if (stats.signalstrength > 100)
-			stats.signalstrength = 100;
-		stats.signalstrength = (stats.signalstrength * 70) / 100 + 30;
-		stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
-		stats.noise = priv->wstats.qual.noise =
-			100 - priv->wstats.qual.qual;
-		bHwError = (((*(priv->rxringtail)) & (0x00000fff)) == 4080) |
-			   (((*(priv->rxringtail)) & (0x04000000)) != 0) |
-			   (((*(priv->rxringtail)) & (0x08000000)) != 0) |
-			   (((~(*(priv->rxringtail))) & (0x10000000)) != 0) |
-			   (((~(*(priv->rxringtail))) & (0x20000000)) != 0);
-		bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
-		bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12;
-		hdr = (struct ieee80211_hdr_4addr *)priv->rxbuffer->buf;
-		    fc = le16_to_cpu(hdr->frame_ctl);
-		type = WLAN_FC_GET_TYPE(fc);
-
-		if (IEEE80211_FTYPE_CTL != type &&
-		    !bHwError && !bCRC && !bICV &&
-		    eqMacAddr(priv->ieee80211->current_network.bssid,
-			fc & IEEE80211_FCTL_TODS ? hdr->addr1 :
-			fc & IEEE80211_FCTL_FROMDS ? hdr->addr2 :
-			hdr->addr3)) {
-
-			/* Perform signal smoothing for dynamic
-			 * mechanism on demand. This is different
-			 * with PerformSignalSmoothing8185 in smoothing
-			 * fomula. No dramatic adjustion is apply
-			 * because dynamic mechanism need some degree
-			 * of correctness. */
-			PerformUndecoratedSignalSmoothing8185(priv, bCckRate);
-
-			/* For good-looking singal strength. */
-			SignalStrengthIndex = NetgearSignalStrengthTranslate(
-				priv->LastSignalStrengthInPercent,
-				priv->SignalStrength);
-
-			priv->LastSignalStrengthInPercent = SignalStrengthIndex;
-			priv->Stats_SignalStrength =
-				TranslateToDbm8185((u8)SignalStrengthIndex);
-
-			/*
-			 * We need more correct power of received packets and
-			 * the "SignalStrength" of RxStats is beautified, so we
-			 * record the correct power here.
-			 */
-
-			priv->Stats_SignalQuality = (long)(
-				priv->Stats_SignalQuality * 5 +
-				(long)priv->SignalQuality + 5) / 6;
-
-			priv->Stats_RecvSignalPower = (long)(
-				priv->Stats_RecvSignalPower * 5 +
-				priv->RecvSignalPower - 1) / 6;
-
-			/*
-			 * Figure out which antenna received the last packet.
-			 * 0: aux, 1: main
-			 */
-			priv->LastRxPktAntenna = Antenna ? 1 : 0;
-			SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
-		}
-
-		if (first) {
-			if (!priv->rx_skb_complete) {
-				/* seems that HW sometimes fails to receive and
-				 * doesn't provide the last descriptor.
-				 */
-				dev_kfree_skb_any(priv->rx_skb);
-				priv->stats.rxnolast++;
-			}
-			priv->rx_skb = dev_alloc_skb(len+2);
-			if (!priv->rx_skb)
-				goto drop;
-
-			priv->rx_skb_complete = 0;
-			priv->rx_skb->dev = dev;
-		} else {
-			/* if we are here we should have already RXed the first
-			 * frame.
-			 * If we get here and the skb is not allocated then
-			 * we have just throw out garbage (skb not allocated)
-			 * and we are still rxing garbage....
-			 */
-			if (!priv->rx_skb_complete) {
-
-				tmp_skb = dev_alloc_skb(
-					priv->rx_skb->len + len + 2);
-
-				if (!tmp_skb)
-					goto drop;
-
-				tmp_skb->dev = dev;
-
-				memcpy(skb_put(tmp_skb, priv->rx_skb->len),
-					priv->rx_skb->data,
-					priv->rx_skb->len);
-
-				dev_kfree_skb_any(priv->rx_skb);
-
-				priv->rx_skb = tmp_skb;
-			}
-		}
-
-		if (!priv->rx_skb_complete) {
-			memcpy(skb_put(priv->rx_skb, len), ((unsigned char *)
-				priv->rxbuffer->buf) + (padding ? 2 : 0), len);
-		}
-
-		if (last && !priv->rx_skb_complete) {
-			if (priv->rx_skb->len > 4)
-				skb_trim(priv->rx_skb, priv->rx_skb->len-4);
-			if (!ieee80211_rtl_rx(priv->ieee80211,
-					 priv->rx_skb, &stats))
-				dev_kfree_skb_any(priv->rx_skb);
-			priv->rx_skb_complete = 1;
-		}
-
-		pci_dma_sync_single_for_device(priv->pdev,
-				    priv->rxbuffer->dma,
-				    priv->rxbuffersize * sizeof(u8),
-				    PCI_DMA_FROMDEVICE);
-
-drop: /* this is used when we have not enough mem */
-		/* restore the descriptor */
-		*(priv->rxringtail+2) = priv->rxbuffer->dma;
-		*(priv->rxringtail) = *(priv->rxringtail) & ~0xfff;
-		*(priv->rxringtail) =
-			*(priv->rxringtail) | priv->rxbuffersize;
-
-		*(priv->rxringtail) =
-			*(priv->rxringtail) | (1<<31);
-
-		priv->rxringtail += rx_desc_size;
-		if (priv->rxringtail >=
-		   (priv->rxring)+(priv->rxringcount)*rx_desc_size)
-			priv->rxringtail = priv->rxring;
-
-		priv->rxbuffer = (priv->rxbuffer->next);
-	}
-}
-
-
-static void rtl8180_dma_kick(struct net_device *dev, int priority)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	write_nic_byte(dev, TX_DMA_POLLING,
-			(1 << (priority + 1)) | priv->dma_poll_mask);
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
-	force_pci_posting(dev);
-}
-
-static void rtl8180_data_hard_stop(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ;
-	write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-static void rtl8180_data_hard_resume(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ);
-	write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-/*
- * This function TX data frames when the ieee80211 stack requires this.
- * It checks also if we need to stop the ieee tx queue, eventually do it
- */
-static void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
-				   int rate)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	int mode;
-	struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *)skb->data;
-	bool morefrag = le16_to_cpu(h->frame_control) & IEEE80211_FCTL_MOREFRAGS;
-	unsigned long flags;
-	int priority;
-
-	mode = priv->ieee80211->iw_mode;
-
-	rate = ieeerate2rtlrate(rate);
-	/*
-	 * This function doesn't require lock because we make sure it's called
-	 * with the tx_lock already acquired.
-	 * This come from the kernel's hard_xmit callback (through the ieee
-	 * stack, or from the try_wake_queue (again through the ieee stack.
-	 */
-	priority = AC2Q(skb->priority);
-	spin_lock_irqsave(&priv->tx_lock, flags);
-
-	if (priv->ieee80211->bHwRadioOff) {
-		spin_unlock_irqrestore(&priv->tx_lock, flags);
-
-		return;
-	}
-
-	if (!check_nic_enought_desc(dev, priority)) {
-		DMESGW("Error: no descriptor left by previous TX (avail %d) ",
-			get_curr_tx_free_desc(dev, priority));
-		ieee80211_rtl_stop_queue(priv->ieee80211);
-	}
-	rtl8180_tx(dev, skb->data, skb->len, priority, morefrag, 0, rate);
-	if (!check_nic_enought_desc(dev, priority))
-		ieee80211_rtl_stop_queue(priv->ieee80211);
-
-	spin_unlock_irqrestore(&priv->tx_lock, flags);
-}
-
-/*
- * This is a rough attempt to TX a frame
- * This is called by the ieee 80211 stack to TX management frames.
- * If the ring is full packets are dropped (for data frame the queue
- * is stopped before this can happen). For this reason it is better
- * if the descriptors are larger than the largest management frame
- * we intend to TX: i'm unsure what the HW does if it will not find
- * the last fragment of a frame because it has been dropped...
- * Since queues for Management and Data frames are different we
- * might use a different lock than tx_lock (for example mgmt_tx_lock)
- */
-/* these function may loop if invoked with 0 descriptors or 0 len buffer */
-static int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	unsigned long flags;
-	int priority;
-
-	priority = MANAGE_PRIORITY;
-
-	spin_lock_irqsave(&priv->tx_lock, flags);
-
-	if (priv->ieee80211->bHwRadioOff) {
-		spin_unlock_irqrestore(&priv->tx_lock, flags);
-		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
-	}
-
-	rtl8180_tx(dev, skb->data, skb->len, priority,
-		0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
-
-	priv->ieee80211->stats.tx_bytes += skb->len;
-	priv->ieee80211->stats.tx_packets++;
-	spin_unlock_irqrestore(&priv->tx_lock, flags);
-
-	dev_kfree_skb_any(skb);
-	return NETDEV_TX_OK;
-}
-
-static void rtl8180_prepare_beacon(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct sk_buff *skb;
-
-	u16 word  = read_nic_word(dev, BcnItv);
-	word &= ~BcnItv_BcnItv; /* clear Bcn_Itv */
-
-	/* word |= 0x64; */
-	word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval);
-
-	write_nic_word(dev, BcnItv, word);
-
-	skb = ieee80211_get_beacon(priv->ieee80211);
-	if (skb) {
-		rtl8180_tx(dev, skb->data, skb->len, BEACON_PRIORITY,
-			0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
-		dev_kfree_skb_any(skb);
-	}
-}
-
-/*
- * This function do the real dirty work: it enqueues a TX command descriptor in
- * the ring buffer, copyes the frame in a TX buffer and kicks the NIC to ensure
- * it does the DMA transfer.
- */
-short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
-		 bool morefrag, short descfrag, int rate)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 *tail, *temp_tail;
-	u32 *begin;
-	u32 *buf;
-	int i;
-	int remain;
-	int buflen;
-	int count;
-	struct buffer *buflist;
-	struct ieee80211_hdr_3addr *frag_hdr =
-		(struct ieee80211_hdr_3addr *)txbuf;
-	u8 dest[ETH_ALEN];
-	u8 bUseShortPreamble = 0;
-	u8 bCTSEnable = 0;
-	u8 bRTSEnable = 0;
-	u16 Duration = 0;
-	u16 RtsDur = 0;
-	u16 ThisFrameTime = 0;
-	u16 TxDescDuration = 0;
-	bool ownbit_flag = false;
-
-	switch (priority) {
-	case MANAGE_PRIORITY:
-		tail = priv->txmapringtail;
-		begin = priv->txmapring;
-		buflist = priv->txmapbufstail;
-		count = priv->txringcount;
-		break;
-	case BK_PRIORITY:
-		tail = priv->txbkpringtail;
-		begin = priv->txbkpring;
-		buflist = priv->txbkpbufstail;
-		count = priv->txringcount;
-		break;
-	case BE_PRIORITY:
-		tail = priv->txbepringtail;
-		begin = priv->txbepring;
-		buflist = priv->txbepbufstail;
-		count = priv->txringcount;
-		break;
-	case VI_PRIORITY:
-		tail = priv->txvipringtail;
-		begin = priv->txvipring;
-		buflist = priv->txvipbufstail;
-		count = priv->txringcount;
-		break;
-	case VO_PRIORITY:
-		tail = priv->txvopringtail;
-		begin = priv->txvopring;
-		buflist = priv->txvopbufstail;
-		count = priv->txringcount;
-		break;
-	case HI_PRIORITY:
-		tail = priv->txhpringtail;
-		begin = priv->txhpring;
-		buflist = priv->txhpbufstail;
-		count = priv->txringcount;
-		break;
-	case BEACON_PRIORITY:
-		tail = priv->txbeaconringtail;
-		begin = priv->txbeaconring;
-		buflist = priv->txbeaconbufstail;
-		count = priv->txbeaconcount;
-		break;
-	default:
-		return -1;
-		break;
-	}
-
-	memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
-	if (is_multicast_ether_addr(dest)) {
-		Duration = 0;
-		RtsDur = 0;
-		bRTSEnable = 0;
-		bCTSEnable = 0;
-
-		ThisFrameTime = ComputeTxTime(len + sCrcLng,
-			rtl8180_rate2rate(rate), 0, bUseShortPreamble);
-		TxDescDuration = ThisFrameTime;
-	} else { /* Unicast packet */
-		u16 AckTime;
-
-		/* for Keep alive */
-		priv->NumTxUnicast++;
-
-		/* Figure out ACK rate according to BSS basic rate
-		 * and Tx rate.
-		 * AckCTSLng = 14 use 1M bps send
-		 */
-		AckTime = ComputeTxTime(14, 10, 0, 0);
-
-		if (((len + sCrcLng) > priv->rts) && priv->rts) { /* RTS/CTS. */
-			u16 RtsTime, CtsTime;
-			bRTSEnable = 1;
-			bCTSEnable = 0;
-
-			/* Rate and time required for RTS. */
-			RtsTime = ComputeTxTime(sAckCtsLng / 8,
-				priv->ieee80211->basic_rate, 0, 0);
-
-			/* Rate and time required for CTS.
-			 * AckCTSLng = 14 use 1M bps send
-			 */
-			CtsTime = ComputeTxTime(14, 10, 0, 0);
-
-			/* Figure out time required to transmit this frame. */
-			ThisFrameTime = ComputeTxTime(len + sCrcLng,
-				rtl8180_rate2rate(rate), 0,
-				bUseShortPreamble);
-
-			/* RTS-CTS-ThisFrame-ACK. */
-			RtsDur = CtsTime + ThisFrameTime +
-				AckTime + 3 * aSifsTime;
-
-			TxDescDuration = RtsTime + RtsDur;
-		} else { /* Normal case. */
-			bCTSEnable = 0;
-			bRTSEnable = 0;
-			RtsDur = 0;
-
-			ThisFrameTime = ComputeTxTime(len + sCrcLng,
-				rtl8180_rate2rate(rate), 0, bUseShortPreamble);
-			TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
-		}
-
-		if (!(le16_to_cpu(frag_hdr->frame_control) & IEEE80211_FCTL_MOREFRAGS)) {
-			/* ThisFrame-ACK. */
-			Duration = aSifsTime + AckTime;
-		} else { /* One or more fragments remained. */
-			u16 NextFragTime;
-
-			/* pretend following packet length = current packet */
-			NextFragTime = ComputeTxTime(len + sCrcLng,
-				rtl8180_rate2rate(rate), 0, bUseShortPreamble);
-
-			/* ThisFrag-ACk-NextFrag-ACK. */
-			Duration = NextFragTime + 3 * aSifsTime + 2 * AckTime;
-		}
-
-	} /* End of Unicast packet */
-
-	frag_hdr->duration_id = Duration;
-
-	buflen = priv->txbuffsize;
-	remain = len;
-	temp_tail = tail;
-
-	while (remain != 0) {
-		mb();
-		if (!buflist) {
-			DMESGE("TX buffer error, cannot TX frames. pri %d.",
-				priority);
-			return -1;
-		}
-		buf = buflist->buf;
-
-		if ((*tail & (1 << 31)) && (priority != BEACON_PRIORITY)) {
-			DMESGW("No more TX desc, returning %x of %x",
-			       remain, len);
-			priv->stats.txrdu++;
-			return remain;
-		}
-
-		*tail = 0; /* zeroes header */
-		*(tail+1) = 0;
-		*(tail+3) = 0;
-		*(tail+5) = 0;
-		*(tail+6) = 0;
-		*(tail+7) = 0;
-
-		/* FIXME: should be triggered by HW encryption parameters.*/
-		*tail |= (1<<15); /* no encrypt */
-
-		if (remain == len && !descfrag) {
-			ownbit_flag = false;
-			*tail = *tail | (1 << 29); /* first segment of packet */
-			*tail = *tail | (len);
-		} else {
-			ownbit_flag = true;
-		}
-
-		for (i = 0; i < buflen && remain > 0; i++, remain--) {
-			/* copy data into descriptor pointed DMAble buffer */
-			((u8 *)buf)[i] = txbuf[i];
-
-			if (remain == 4 && i+4 >= buflen)
-				break;
-			/* ensure the last desc has at least 4 bytes payload */
-		}
-		txbuf = txbuf + i;
-		*(tail+3) = *(tail+3) & ~0xfff;
-		*(tail+3) = *(tail+3) | i; /* buffer length */
-
-		if (bCTSEnable)
-			*tail |= (1<<18);
-
-		if (bRTSEnable) { /* rts enable */
-			/* RTS RATE */
-			*tail |= (ieeerate2rtlrate(
-				priv->ieee80211->basic_rate) << 19);
-
-			*tail |= (1<<23); /* rts enable */
-			*(tail+1) |= (RtsDur&0xffff); /* RTS Duration */
-		}
-		*(tail+3) |= ((TxDescDuration&0xffff)<<16); /* DURATION */
-
-		*(tail + 5) |= (11 << 8); /* retry lim; */
-
-		*tail = *tail | ((rate&0xf) << 24);
-
-		if (morefrag)
-			*tail = (*tail) | (1<<17); /* more fragment */
-		if (!remain)
-			*tail = (*tail) | (1<<28); /* last segment of frame */
-
-		*(tail+5) = *(tail+5)|(2<<27);
-		*(tail+7) = *(tail+7)|(1<<4);
-
-		wmb();
-		if (ownbit_flag)
-			/* descriptor ready to be txed */
-			*tail |= (1 << 31);
-
-		if ((tail - begin)/8 == count-1)
-			tail = begin;
-		else
-			tail = tail+8;
-
-		buflist = buflist->next;
-
-		mb();
-
-		switch (priority) {
-		case MANAGE_PRIORITY:
-			priv->txmapringtail = tail;
-			priv->txmapbufstail = buflist;
-			break;
-		case BK_PRIORITY:
-			priv->txbkpringtail = tail;
-			priv->txbkpbufstail = buflist;
-			break;
-		case BE_PRIORITY:
-			priv->txbepringtail = tail;
-			priv->txbepbufstail = buflist;
-			break;
-		case VI_PRIORITY:
-			priv->txvipringtail = tail;
-			priv->txvipbufstail = buflist;
-			break;
-		case VO_PRIORITY:
-			priv->txvopringtail = tail;
-			priv->txvopbufstail = buflist;
-			break;
-		case HI_PRIORITY:
-			priv->txhpringtail = tail;
-			priv->txhpbufstail = buflist;
-			break;
-		case BEACON_PRIORITY:
-			/*
-			 * The HW seems to be happy with the 1st
-			 * descriptor filled and the 2nd empty...
-			 * So always update descriptor 1 and never
-			 * touch 2nd
-			 */
-			break;
-		}
-	}
-	*temp_tail = *temp_tail | (1<<31); /* descriptor ready to be txed */
-	rtl8180_dma_kick(dev, priority);
-
-	return 0;
-}
-
-void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
-
-static void rtl8180_link_change(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u16 beacon_interval;
-	struct ieee80211_network *net = &priv->ieee80211->current_network;
-
-	rtl8180_update_msr(dev);
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
-	write_nic_dword(dev, BSSID, ((u32 *)net->bssid)[0]);
-	write_nic_word(dev, BSSID+4, ((u16 *)net->bssid)[2]);
-
-	beacon_interval  = read_nic_word(dev, BEACON_INTERVAL);
-	beacon_interval &= ~BEACON_INTERVAL_MASK;
-	beacon_interval |= net->beacon_interval;
-	write_nic_word(dev, BEACON_INTERVAL, beacon_interval);
-
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
-	rtl8180_set_chan(dev, priv->chan);
-}
-
-static void rtl8180_rq_tx_ack(struct net_device *dev)
-{
-
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	write_nic_byte(dev, CONFIG4,
-		read_nic_byte(dev, CONFIG4) | CONFIG4_PWRMGT);
-	priv->ack_tx_to_ieee = 1;
-}
-
-static short rtl8180_is_tx_queue_empty(struct net_device *dev)
-{
-
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 *d;
-
-	for (d = priv->txmapring;
-		d < priv->txmapring + priv->txringcount; d += 8)
-			if (*d & (1<<31))
-				return 0;
-
-	for (d = priv->txbkpring;
-		d < priv->txbkpring + priv->txringcount; d += 8)
-			if (*d & (1<<31))
-				return 0;
-
-	for (d = priv->txbepring;
-		d < priv->txbepring + priv->txringcount; d += 8)
-			if (*d & (1<<31))
-				return 0;
-
-	for (d = priv->txvipring;
-		d < priv->txvipring + priv->txringcount; d += 8)
-			if (*d & (1<<31))
-				return 0;
-
-	for (d = priv->txvopring;
-		d < priv->txvopring + priv->txringcount; d += 8)
-			if (*d & (1<<31))
-				return 0;
-
-	for (d = priv->txhpring;
-		d < priv->txhpring + priv->txringcount; d += 8)
-			if (*d & (1<<31))
-				return 0;
-	return 1;
-}
-
-static void rtl8180_hw_wakeup(struct net_device *dev)
-{
-	unsigned long flags;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	spin_lock_irqsave(&priv->ps_lock, flags);
-	write_nic_byte(dev, CONFIG4,
-		read_nic_byte(dev, CONFIG4) & ~CONFIG4_PWRMGT);
-	if (priv->rf_wakeup)
-		priv->rf_wakeup(dev);
-	spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_hw_sleep_down(struct net_device *dev)
-{
-	unsigned long flags;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	spin_lock_irqsave(&priv->ps_lock, flags);
-	if (priv->rf_sleep)
-		priv->rf_sleep(dev);
-	spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 rb = jiffies;
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->ps_lock, flags);
-
-	/*
-	 * Writing HW register with 0 equals to disable
-	 * the timer, that is not really what we want
-	 */
-	tl -= MSECS(4+16+7);
-
-	/*
-	 * If the interval in which we are requested to sleep is too
-	 * short then give up and remain awake
-	 */
-	if (((tl >= rb) && (tl-rb) <= MSECS(MIN_SLEEP_TIME))
-		|| ((rb > tl) && (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
-		spin_unlock_irqrestore(&priv->ps_lock, flags);
-		netdev_warn(dev, "too short to sleep\n");
-		return;
-	}
-
-	{
-		u32 tmp = (tl > rb) ? (tl-rb) : (rb-tl);
-
-		priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp);
-		/* as tl may be less than rb */
-		queue_delayed_work(priv->ieee80211->wq,
-			&priv->ieee80211->hw_wakeup_wq, tmp);
-	}
-	/*
-	 * If we suspect the TimerInt is gone beyond tl
-	 * while setting it, then give up
-	 */
-
-	if (((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME))) ||
-		((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
-		spin_unlock_irqrestore(&priv->ps_lock, flags);
-		return;
-	}
-
-	queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq);
-	spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_wmm_single_param_update(struct net_device *dev,
-	u8 mode, AC_CODING eACI, PAC_PARAM param)
-{
-	u8 u1bAIFS;
-	u32 u4bAcParam;
-
-	/* Retrieve parameters to update. */
-	/* Mode G/A: slotTimeTimer = 9; Mode B: 20 */
-	u1bAIFS = param->f.AciAifsn.f.AIFSN * ((mode & IEEE_G) == IEEE_G ?
-		9 : 20) + aSifsTime;
-	u4bAcParam = (((u32)param->f.TXOPLimit << AC_PARAM_TXOP_LIMIT_OFFSET) |
-		((u32)param->f.Ecw.f.ECWmax << AC_PARAM_ECW_MAX_OFFSET) |
-		((u32)param->f.Ecw.f.ECWmin << AC_PARAM_ECW_MIN_OFFSET) |
-		((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-
-	switch (eACI) {
-	case AC1_BK:
-		write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
-		return;
-	case AC0_BE:
-		write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
-		return;
-	case AC2_VI:
-		write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
-		return;
-	case AC3_VO:
-		write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
-		return;
-	default:
-		pr_warn("SetHwReg8185(): invalid ACI: %d!\n", eACI);
-		return;
-	}
-}
-
-static void rtl8180_wmm_param_update(struct work_struct *work)
-{
-	struct ieee80211_device *ieee = container_of(work,
-		struct ieee80211_device, wmm_param_update_wq);
-	struct net_device *dev = ieee->dev;
-	u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
-	u8 mode = ieee->current_network.mode;
-	AC_CODING eACI;
-	AC_PARAM AcParam;
-
-	if (!ieee->current_network.QoS_Enable) {
-		/* legacy ac_xx_param update */
-		AcParam.longData = 0;
-		AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */
-		AcParam.f.AciAifsn.f.ACM = 0;
-		AcParam.f.Ecw.f.ECWmin = 3; /* Follow 802.11 CWmin. */
-		AcParam.f.Ecw.f.ECWmax = 7; /* Follow 802.11 CWmax. */
-		AcParam.f.TXOPLimit = 0;
-
-		for (eACI = 0; eACI < AC_MAX; eACI++) {
-			AcParam.f.AciAifsn.f.ACI = (u8)eACI;
-
-			rtl8180_wmm_single_param_update(dev, mode, eACI,
-				(PAC_PARAM)&AcParam);
-		}
-		return;
-	}
-
-	for (eACI = 0; eACI < AC_MAX; eACI++) {
-		rtl8180_wmm_single_param_update(dev, mode,
-			((PAC_PARAM)ac_param)->f.AciAifsn.f.ACI,
-			(PAC_PARAM)ac_param);
-
-		ac_param += sizeof(AC_PARAM);
-	}
-}
-
-void rtl8180_restart_wq(struct work_struct *work);
-void rtl8180_watch_dog_wq(struct work_struct *work);
-void rtl8180_hw_wakeup_wq(struct work_struct *work);
-void rtl8180_hw_sleep_wq(struct work_struct *work);
-void rtl8180_sw_antenna_wq(struct work_struct *work);
-void rtl8180_watch_dog(struct net_device *dev);
-
-static void watch_dog_adaptive(unsigned long data)
-{
-	struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
-
-	if (!priv->up) {
-		DMESG("<----watch_dog_adaptive():driver is not up!\n");
-		return;
-	}
-
-	/* Tx High Power Mechanism. */
-	if (CheckHighPower((struct net_device *)data))
-		queue_work(priv->ieee80211->wq,
-			(void *)&priv->ieee80211->tx_pw_wq);
-
-	/* Tx Power Tracking on 87SE. */
-	if (CheckTxPwrTracking((struct net_device *)data))
-		TxPwrTracking87SE((struct net_device *)data);
-
-	/* Perform DIG immediately. */
-	if (CheckDig((struct net_device *)data))
-		queue_work(priv->ieee80211->wq,
-			(void *)&priv->ieee80211->hw_dig_wq);
-
-	rtl8180_watch_dog((struct net_device *)data);
-
-	queue_work(priv->ieee80211->wq,
-		(void *)&priv->ieee80211->GPIOChangeRFWorkItem);
-
-	priv->watch_dog_timer.expires = jiffies +
-		MSECS(IEEE80211_WATCH_DOG_TIME);
-
-	add_timer(&priv->watch_dog_timer);
-}
-
-static struct rtl8187se_channel_list channel_plan_list[] = {
-	/* FCC */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40,
-		44, 48, 52, 56, 60, 64}, 19},
-
-	/* IC */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
-
-	/* ETSI */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
-		44, 48, 52, 56, 60, 64}, 21},
-
-	/* Spain. Change to ETSI. */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
-		44, 48, 52, 56, 60, 64}, 21},
-
-	/* France. Change to ETSI. */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
-		44, 48, 52, 56, 60, 64}, 21},
-
-	/* MKK */
-	{{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9},
-
-	/* MKK1 */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36,
-		40, 44, 48, 52, 56, 60, 64}, 22},
-
-	/* Israel. */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
-		44, 48, 52, 56, 60, 64}, 21},
-
-	/* For 11a , TELEC */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17},
-
-	/* For Global Domain. 1-11 active, 12-14 passive. */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
-
-	/* world wide 13: ch1~ch11 active, ch12~13 passive */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}
-};
-
-static void rtl8180_set_channel_map(u8 channel_plan,
-				    struct ieee80211_device *ieee)
-{
-	int i;
-
-	ieee->MinPassiveChnlNum = MAX_CHANNEL_NUMBER+1;
-	ieee->IbssStartChnl = 0;
-
-	switch (channel_plan) {
-	case COUNTRY_CODE_FCC:
-	case COUNTRY_CODE_IC:
-	case COUNTRY_CODE_ETSI:
-	case COUNTRY_CODE_SPAIN:
-	case COUNTRY_CODE_FRANCE:
-	case COUNTRY_CODE_MKK:
-	case COUNTRY_CODE_MKK1:
-	case COUNTRY_CODE_ISRAEL:
-	case COUNTRY_CODE_TELEC:
-		{
-			Dot11d_Init(ieee);
-			ieee->bGlobalDomain = false;
-			if (channel_plan_list[channel_plan].len != 0) {
-				/* Clear old channel map */
-				memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
-				/* Set new channel map */
-				for (i = 0; i < channel_plan_list[channel_plan].len; i++) {
-					if (channel_plan_list[channel_plan].channel[i] <= 14)
-						GET_DOT11D_INFO(ieee)->channel_map[channel_plan_list[channel_plan].channel[i]] = 1;
-				}
-			}
-			break;
-		}
-	case COUNTRY_CODE_GLOBAL_DOMAIN:
-		{
-			GET_DOT11D_INFO(ieee)->bEnabled = false;
-			Dot11d_Reset(ieee);
-			ieee->bGlobalDomain = true;
-			break;
-		}
-	case COUNTRY_CODE_WORLD_WIDE_13_INDEX:
-		{
-			ieee->MinPassiveChnlNum = 12;
-			ieee->IbssStartChnl = 10;
-			break;
-		}
-	default:
-		{
-			Dot11d_Init(ieee);
-			ieee->bGlobalDomain = false;
-			memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
-			for (i = 1; i <= 14; i++)
-				GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
-			break;
-		}
-	}
-}
-
-void GPIOChangeRFWorkItemCallBack(struct work_struct *work);
-
-static void rtl8180_statistics_init(struct stats *pstats)
-{
-	memset(pstats, 0, sizeof(struct stats));
-}
-
-static void rtl8180_link_detect_init(struct link_detect_t *plink_detect)
-{
-	memset(plink_detect, 0, sizeof(struct link_detect_t));
-	plink_detect->slot_num = DEFAULT_SLOT_NUM;
-}
-
-static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom)
-{
-	struct net_device *dev = eeprom->data;
-	u8 reg = read_nic_byte(dev, EPROM_CMD);
-
-	eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
-	eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
-	eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
-	eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
-}
-
-static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom)
-{
-	struct net_device *dev = eeprom->data;
-	u8 reg = 2 << 6;
-
-	if (eeprom->reg_data_in)
-		reg |= RTL818X_EEPROM_CMD_WRITE;
-	if (eeprom->reg_data_out)
-		reg |= RTL818X_EEPROM_CMD_READ;
-	if (eeprom->reg_data_clock)
-		reg |= RTL818X_EEPROM_CMD_CK;
-	if (eeprom->reg_chip_select)
-		reg |= RTL818X_EEPROM_CMD_CS;
-
-	write_nic_byte(dev, EPROM_CMD, reg);
-	read_nic_byte(dev, EPROM_CMD);
-	udelay(10);
-}
-
-static short rtl8180_init(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u16 word;
-	u16 usValue;
-	u16 tmpu16;
-	int i, j;
-	struct eeprom_93cx6 eeprom;
-	u16 eeprom_val;
-
-	eeprom.data = dev;
-	eeprom.register_read = rtl8187se_eeprom_register_read;
-	eeprom.register_write = rtl8187se_eeprom_register_write;
-	eeprom.width = PCI_EEPROM_WIDTH_93C46;
-
-	eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val);
-	priv->channel_plan = eeprom_val & 0xFF;
-	if (priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN) {
-		netdev_err(dev, "rtl8180_init: Invalid channel plan! Set to default.\n");
-		priv->channel_plan = 0;
-	}
-
-	DMESG("Channel plan is %d\n", priv->channel_plan);
-	rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
-
-	/* FIXME: these constants are placed in a bad pleace. */
-	priv->txbuffsize = 2048;	/* 1024; */
-	priv->txringcount = 32;		/* 32; */
-	priv->rxbuffersize = 2048;	/* 1024; */
-	priv->rxringcount = 64;		/* 32; */
-	priv->txbeaconcount = 2;
-	priv->rx_skb_complete = 1;
-
-	priv->RFChangeInProgress = false;
-	priv->SetRFPowerStateInProgress = false;
-	priv->RFProgType = 0;
-
-	priv->irq_enabled = 0;
-
-	rtl8180_statistics_init(&priv->stats);
-	rtl8180_link_detect_init(&priv->link_detect);
-
-	priv->ack_tx_to_ieee = 0;
-	priv->ieee80211->current_network.beacon_interval =
-		DEFAULT_BEACONINTERVAL;
-	priv->ieee80211->iw_mode = IW_MODE_INFRA;
-	priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN |
-		IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
-		IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
-	priv->ieee80211->active_scan = 1;
-	priv->ieee80211->rate = 110; /* 11 mbps */
-	priv->ieee80211->modulation = IEEE80211_CCK_MODULATION;
-	priv->ieee80211->host_encrypt = 1;
-	priv->ieee80211->host_decrypt = 1;
-	priv->ieee80211->sta_wake_up = rtl8180_hw_wakeup;
-	priv->ieee80211->ps_request_tx_ack = rtl8180_rq_tx_ack;
-	priv->ieee80211->enter_sleep_state = rtl8180_hw_sleep;
-	priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty;
-
-	priv->hw_wep = hwwep;
-	priv->dev = dev;
-	priv->retry_rts = DEFAULT_RETRY_RTS;
-	priv->retry_data = DEFAULT_RETRY_DATA;
-	priv->RFChangeInProgress = false;
-	priv->SetRFPowerStateInProgress = false;
-	priv->RFProgType = 0;
-	priv->bInactivePs = true; /* false; */
-	priv->ieee80211->bInactivePs = priv->bInactivePs;
-	priv->bSwRfProcessing = false;
-	priv->eRFPowerState = RF_OFF;
-	priv->RfOffReason = 0;
-	priv->led_strategy = SW_LED_MODE0;
-	priv->TxPollingTimes = 0;
-	priv->bLeisurePs = true;
-	priv->dot11PowerSaveMode = ACTIVE;
-	priv->AdMinCheckPeriod = 5;
-	priv->AdMaxCheckPeriod = 10;
-	priv->AdMaxRxSsThreshold = 30;	/* 60->30 */
-	priv->AdRxSsThreshold = 20;	/* 50->20 */
-	priv->AdCheckPeriod = priv->AdMinCheckPeriod;
-	priv->AdTickCount = 0;
-	priv->AdRxSignalStrength = -1;
-	priv->RegSwAntennaDiversityMechanism = 0;
-	priv->RegDefaultAntenna = 0;
-	priv->SignalStrength = 0;
-	priv->AdRxOkCnt = 0;
-	priv->CurrAntennaIndex = 0;
-	priv->AdRxSsBeforeSwitched = 0;
-	init_timer(&priv->SwAntennaDiversityTimer);
-	priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
-	priv->SwAntennaDiversityTimer.function =
-		(void *)SwAntennaDiversityTimerCallback;
-	priv->bDigMechanism = true;
-	priv->InitialGain = 6;
-	priv->bXtalCalibration = false;
-	priv->XtalCal_Xin = 0;
-	priv->XtalCal_Xout = 0;
-	priv->bTxPowerTrack = false;
-	priv->ThermalMeter = 0;
-	priv->FalseAlarmRegValue = 0;
-	priv->RegDigOfdmFaUpTh = 0xc; /* Upper threshold of OFDM false alarm,
-					which is used in DIG. */
-	priv->DIG_NumberFallbackVote = 0;
-	priv->DIG_NumberUpgradeVote = 0;
-	priv->LastSignalStrengthInPercent = 0;
-	priv->Stats_SignalStrength = 0;
-	priv->LastRxPktAntenna = 0;
-	priv->SignalQuality = 0; /* in 0-100 index. */
-	priv->Stats_SignalQuality = 0;
-	priv->RecvSignalPower = 0; /* in dBm. */
-	priv->Stats_RecvSignalPower = 0;
-	priv->AdMainAntennaRxOkCnt = 0;
-	priv->AdAuxAntennaRxOkCnt = 0;
-	priv->bHWAdSwitched = false;
-	priv->bRegHighPowerMechanism = true;
-	priv->RegHiPwrUpperTh = 77;
-	priv->RegHiPwrLowerTh = 75;
-	priv->RegRSSIHiPwrUpperTh = 70;
-	priv->RegRSSIHiPwrLowerTh = 20;
-	priv->bCurCCKPkt = false;
-	priv->UndecoratedSmoothedSS = -1;
-	priv->bToUpdateTxPwr = false;
-	priv->CurCCKRSSI = 0;
-	priv->RxPower = 0;
-	priv->RSSI = 0;
-	priv->NumTxOkTotal = 0;
-	priv->NumTxUnicast = 0;
-	priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
-	priv->CurrRetryCnt = 0;
-	priv->LastRetryCnt = 0;
-	priv->LastTxokCnt = 0;
-	priv->LastRxokCnt = 0;
-	priv->LastRetryRate = 0;
-	priv->bTryuping = 0;
-	priv->CurrTxRate = 0;
-	priv->CurrRetryRate = 0;
-	priv->TryupingCount = 0;
-	priv->TryupingCountNoData = 0;
-	priv->TryDownCountLowData = 0;
-	priv->LastTxOKBytes = 0;
-	priv->LastFailTxRate = 0;
-	priv->LastFailTxRateSS = 0;
-	priv->FailTxRateCount = 0;
-	priv->LastTxThroughput = 0;
-	priv->NumTxOkBytesTotal = 0;
-	priv->ForcedDataRate = 0;
-	priv->RegBModeGainStage = 1;
-
-	priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
-	spin_lock_init(&priv->irq_th_lock);
-	spin_lock_init(&priv->tx_lock);
-	spin_lock_init(&priv->ps_lock);
-	spin_lock_init(&priv->rf_ps_lock);
-	sema_init(&priv->wx_sem, 1);
-	INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq);
-	INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,
-			  (void *)rtl8180_hw_wakeup_wq);
-	INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,
-			  (void *)rtl8180_hw_sleep_wq);
-	INIT_WORK(&priv->ieee80211->wmm_param_update_wq,
-		  (void *)rtl8180_wmm_param_update);
-	INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,
-			  (void *)rtl8180_rate_adapter);
-	INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,
-			 (void *)rtl8180_hw_dig_wq);
-	INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,
-			 (void *)rtl8180_tx_pw_wq);
-	INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,
-			 (void *) GPIOChangeRFWorkItemCallBack);
-	tasklet_init(&priv->irq_rx_tasklet,
-		     (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
-		     (unsigned long)priv);
-
-	init_timer(&priv->watch_dog_timer);
-	priv->watch_dog_timer.data = (unsigned long)dev;
-	priv->watch_dog_timer.function = watch_dog_adaptive;
-
-	init_timer(&priv->rateadapter_timer);
-	priv->rateadapter_timer.data = (unsigned long)dev;
-	priv->rateadapter_timer.function = timer_rate_adaptive;
-	priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
-	priv->bEnhanceTxPwr = false;
-
-	priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
-	priv->ieee80211->set_chan = rtl8180_set_chan;
-	priv->ieee80211->link_change = rtl8180_link_change;
-	priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
-	priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
-	priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
-
-	priv->ieee80211->init_wmmparam_flag = 0;
-
-	priv->ieee80211->start_send_beacons = rtl8180_start_tx_beacon;
-	priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable;
-	priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
-
-	priv->ShortRetryLimit = 7;
-	priv->LongRetryLimit = 7;
-	priv->EarlyRxThreshold = 7;
-
-	priv->TransmitConfig =	(1<<TCR_DurProcMode_OFFSET) |
-				(7<<TCR_MXDMA_OFFSET) |
-				(priv->ShortRetryLimit<<TCR_SRL_OFFSET) |
-				(priv->LongRetryLimit<<TCR_LRL_OFFSET);
-
-	priv->ReceiveConfig =	RCR_AMF | RCR_ADF | RCR_ACF |
-				RCR_AB | RCR_AM | RCR_APM |
-				(7<<RCR_MXDMA_OFFSET) |
-				(priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) |
-				(priv->EarlyRxThreshold == 7 ?
-					 RCR_ONLYERLPKT : 0);
-
-	priv->IntrMask		= IMR_TMGDOK | IMR_TBDER |
-				  IMR_THPDER | IMR_THPDOK |
-				  IMR_TVODER | IMR_TVODOK |
-				  IMR_TVIDER | IMR_TVIDOK |
-				  IMR_TBEDER | IMR_TBEDOK |
-				  IMR_TBKDER | IMR_TBKDOK |
-				  IMR_RDU |
-				  IMR_RER | IMR_ROK |
-				  IMR_RQoSOK;
-
-	priv->InitialGain = 6;
-
-	DMESG("MAC controller is a RTL8187SE b/g");
-
-	priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
-	priv->ieee80211->short_slot = 1;
-
-	eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &usValue);
-	DMESG("usValue is %#hx\n", usValue);
-	/* 3Read AntennaDiversity */
-
-	/* SW Antenna Diversity. */
-	priv->EEPROMSwAntennaDiversity = (usValue & EEPROM_SW_AD_MASK) ==
-		EEPROM_SW_AD_ENABLE;
-
-	/* Default Antenna to use. */
-	priv->EEPROMDefaultAntenna1 = (usValue & EEPROM_DEF_ANT_MASK) ==
-		EEPROM_DEF_ANT_1;
-
-	if (priv->RegSwAntennaDiversityMechanism == 0) /* Auto */
-		/* 0: default from EEPROM. */
-		priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
-	else
-		/* 1:disable antenna diversity, 2: enable antenna diversity. */
-		priv->bSwAntennaDiverity =
-			priv->RegSwAntennaDiversityMechanism == 2;
-
-	if (priv->RegDefaultAntenna == 0)
-		/* 0: default from EEPROM. */
-		priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
-	else
-		/* 1: main, 2: aux. */
-		priv->bDefaultAntenna1 = priv->RegDefaultAntenna == 2;
-
-	priv->plcp_preamble_mode = 2;
-	/* the eeprom type is stored in RCR register bit #6 */
-	if (RCR_9356SEL & read_nic_dword(dev, RCR))
-		priv->epromtype = EPROM_93c56;
-	else
-		priv->epromtype = EPROM_93c46;
-
-	eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)
-			       dev->dev_addr, 3);
-
-	for (i = 1, j = 0; i < 14; i += 2, j++) {
-		eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word);
-		priv->chtxpwr[i] = word & 0xff;
-		priv->chtxpwr[i+1] = (word & 0xff00)>>8;
-	}
-	for (i = 1, j = 0; i < 14; i += 2, j++) {
-		eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word);
-		priv->chtxpwr_ofdm[i] = word & 0xff;
-		priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8;
-	}
-
-	/* 3Read crystal calibration and thermal meter indication on 87SE. */
-	eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16);
-
-	/* Crystal calibration for Xin and Xout resp. */
-	priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK;
-	priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4;
-	if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12)
-		priv->bXtalCalibration = true;
-
-	/* Thermal meter reference indication. */
-	priv->ThermalMeter =  (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8);
-	if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13)
-		priv->bTxPowerTrack = true;
-
-	priv->rf_sleep = rtl8225z4_rf_sleep;
-	priv->rf_wakeup = rtl8225z4_rf_wakeup;
-	DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
-
-	priv->rf_close = rtl8225z2_rf_close;
-	priv->rf_init = rtl8225z2_rf_init;
-	priv->rf_set_chan = rtl8225z2_rf_set_chan;
-	priv->rf_set_sens = NULL;
-
-	if (0 != alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
-		return -ENOMEM;
-
-	if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
-				  TX_MANAGEPRIORITY_RING_ADDR))
-		return -ENOMEM;
-
-	if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
-				 TX_BKPRIORITY_RING_ADDR))
-		return -ENOMEM;
-
-	if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
-				 TX_BEPRIORITY_RING_ADDR))
-		return -ENOMEM;
-
-	if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
-				  TX_VIPRIORITY_RING_ADDR))
-		return -ENOMEM;
-
-	if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
-				  TX_VOPRIORITY_RING_ADDR))
-		return -ENOMEM;
-
-	if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
-				  TX_HIGHPRIORITY_RING_ADDR))
-		return -ENOMEM;
-
-	if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount,
-				  TX_BEACON_RING_ADDR))
-		return -ENOMEM;
-
-	if (request_irq(dev->irq, rtl8180_interrupt,
-		IRQF_SHARED, dev->name, dev)) {
-		DMESGE("Error allocating IRQ %d", dev->irq);
-		return -1;
-	} else {
-		priv->irq = dev->irq;
-		DMESG("IRQ %d", dev->irq);
-	}
-
-	return 0;
-}
-
-void rtl8180_no_hw_wep(struct net_device *dev)
-{
-}
-
-void rtl8180_set_hw_wep(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 pgreg;
-	u8 security;
-	u32 key0_word4;
-
-	pgreg = read_nic_byte(dev, PGSELECT);
-	write_nic_byte(dev, PGSELECT, pgreg & ~(1<<PGSELECT_PG_SHIFT));
-
-	key0_word4 = read_nic_dword(dev, KEY0+4+4+4);
-	key0_word4 &= ~0xff;
-	key0_word4 |= priv->key0[3] & 0xff;
-	write_nic_dword(dev, KEY0, (priv->key0[0]));
-	write_nic_dword(dev, KEY0+4, (priv->key0[1]));
-	write_nic_dword(dev, KEY0+4+4, (priv->key0[2]));
-	write_nic_dword(dev, KEY0+4+4+4, (key0_word4));
-
-	security  = read_nic_byte(dev, SECURITY);
-	security |= (1<<SECURITY_WEP_TX_ENABLE_SHIFT);
-	security |= (1<<SECURITY_WEP_RX_ENABLE_SHIFT);
-	security &= ~SECURITY_ENCRYP_MASK;
-	security |= (SECURITY_ENCRYP_104<<SECURITY_ENCRYP_SHIFT);
-
-	write_nic_byte(dev, SECURITY, security);
-
-	DMESG("key %x %x %x %x", read_nic_dword(dev, KEY0+4+4+4),
-	      read_nic_dword(dev, KEY0+4+4), read_nic_dword(dev, KEY0+4),
-	      read_nic_dword(dev, KEY0));
-}
-
-
-void rtl8185_rf_pins_enable(struct net_device *dev)
-{
-	write_nic_word(dev, RFPinsEnable, 0x1fff); /* | tmp); */
-}
-
-void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
-{
-	u8 conf3;
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
-	conf3 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
-	write_nic_dword(dev, ANAPARAM2, a);
-
-	conf3 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, conf3 & ~(1<<CONFIG3_ANAPARAM_W_SHIFT));
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8180_set_anaparam(struct net_device *dev, u32 a)
-{
-	u8 conf3;
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
-	conf3 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
-	write_nic_dword(dev, ANAPARAM, a);
-
-	conf3 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, conf3 & ~(1<<CONFIG3_ANAPARAM_W_SHIFT));
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
-{
-	write_nic_byte(dev, TX_ANTENNA, ant);
-	force_pci_posting(dev);
-	mdelay(1);
-}
-
-static void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
-{
-	u32 phyw;
-
-	adr |= 0x80;
-
-	phyw = ((data<<8) | adr);
-
-	/* Note: we must write 0xff7c after 0x7d-0x7f to write BB register. */
-	write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
-	write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
-	write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
-	write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff)));
-}
-
-inline void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data)
-{
-	data = data & 0xff;
-	rtl8185_write_phy(dev, adr, data);
-}
-
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data)
-{
-	data = data & 0xff;
-	rtl8185_write_phy(dev, adr, data | 0x10000);
-}
-
-/*
- * This configures registers for beacon tx and enables it via
- * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
- * be used to stop beacon transmission
- */
-void rtl8180_start_tx_beacon(struct net_device *dev)
-{
-	u16 word;
-
-	DMESG("Enabling beacon TX");
-	rtl8180_prepare_beacon(dev);
-	rtl8180_irq_disable(dev);
-	rtl8180_beacon_tx_enable(dev);
-
-	word = read_nic_word(dev, AtimWnd) & ~AtimWnd_AtimWnd;
-	write_nic_word(dev, AtimWnd, word); /* word |= */
-
-	word  = read_nic_word(dev, BintrItv);
-	word &= ~BintrItv_BintrItv;
-	word |= 1000; /* priv->ieee80211->current_network.beacon_interval *
-		       * ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
-		       * FIXME: check if correct ^^ worked with 0x3e8;
-		       */
-	write_nic_word(dev, BintrItv, word);
-
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
-	rtl8185b_irq_enable(dev);
-}
-
-static struct net_device_stats *rtl8180_stats(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	return &priv->ieee80211->stats;
-}
-
-/*
- * Change current and default preamble mode.
- */
-static bool MgntActSet_802_11_PowerSaveMode(struct r8180_priv *priv,
-				     enum rt_ps_mode rtPsMode)
-{
-	/* Currently, we do not change power save mode on IBSS mode. */
-	if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
-		return false;
-
-	priv->ieee80211->ps = rtPsMode;
-
-	return true;
-}
-
-static void LeisurePSEnter(struct r8180_priv *priv)
-{
-	if (priv->bLeisurePs)
-		if (priv->ieee80211->ps == IEEE80211_PS_DISABLED)
-			/* IEEE80211_PS_ENABLE */
-			MgntActSet_802_11_PowerSaveMode(priv,
-				IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST);
-}
-
-static void LeisurePSLeave(struct r8180_priv *priv)
-{
-	if (priv->bLeisurePs)
-		if (priv->ieee80211->ps != IEEE80211_PS_DISABLED)
-			MgntActSet_802_11_PowerSaveMode(
-				priv, IEEE80211_PS_DISABLED);
-}
-
-void rtl8180_hw_wakeup_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(
-		dwork, struct ieee80211_device, hw_wakeup_wq);
-	struct net_device *dev = ieee->dev;
-
-	rtl8180_hw_wakeup(dev);
-}
-
-void rtl8180_hw_sleep_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(
-		dwork, struct ieee80211_device, hw_sleep_wq);
-	struct net_device *dev = ieee->dev;
-
-	rtl8180_hw_sleep_down(dev);
-}
-
-static void MgntLinkKeepAlive(struct r8180_priv *priv)
-{
-	if (priv->keepAliveLevel == 0)
-		return;
-
-	if (priv->ieee80211->state == IEEE80211_LINKED) {
-		/*
-		 * Keep-Alive.
-		 */
-
-		if ((priv->keepAliveLevel == 2) ||
-			(priv->link_detect.last_num_tx_unicast ==
-				priv->NumTxUnicast &&
-			priv->link_detect.last_num_rx_unicast ==
-				priv->ieee80211->NumRxUnicast)
-			) {
-			priv->link_detect.idle_count++;
-
-			/*
-			 * Send a Keep-Alive packet packet to AP if we had
-			 * been idle for a while.
-			 */
-			if (priv->link_detect.idle_count >=
-				KEEP_ALIVE_INTERVAL /
-				CHECK_FOR_HANG_PERIOD - 1) {
-				priv->link_detect.idle_count = 0;
-				ieee80211_sta_ps_send_null_frame(
-					priv->ieee80211, false);
-			}
-		} else {
-			priv->link_detect.idle_count = 0;
-		}
-		priv->link_detect.last_num_tx_unicast = priv->NumTxUnicast;
-		priv->link_detect.last_num_rx_unicast =
-			priv->ieee80211->NumRxUnicast;
-	}
-}
-
-void rtl8180_watch_dog(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	bool bEnterPS = false;
-	bool bBusyTraffic = false;
-	u32 TotalRxNum = 0;
-	u16 SlotIndex = 0;
-	u16 i = 0;
-	if (priv->ieee80211->actscanning == false) {
-		if ((priv->ieee80211->iw_mode != IW_MODE_ADHOC) &&
-		    (priv->ieee80211->state == IEEE80211_NOLINK) &&
-		    (priv->ieee80211->beinretry == false) &&
-		    (priv->eRFPowerState == RF_ON))
-			IPSEnter(dev);
-	}
-	if ((priv->ieee80211->state == IEEE80211_LINKED) &&
-		(priv->ieee80211->iw_mode == IW_MODE_INFRA)) {
-		SlotIndex = (priv->link_detect.slot_index++) %
-			priv->link_detect.slot_num;
-
-		priv->link_detect.rx_frame_num[SlotIndex] =
-			priv->ieee80211->NumRxDataInPeriod +
-			priv->ieee80211->NumRxBcnInPeriod;
-
-		for (i = 0; i < priv->link_detect.slot_num; i++)
-			TotalRxNum += priv->link_detect.rx_frame_num[i];
-
-		if (TotalRxNum == 0) {
-			priv->ieee80211->state = IEEE80211_ASSOCIATING;
-			queue_work(priv->ieee80211->wq,
-				&priv->ieee80211->associate_procedure_wq);
-		}
-	}
-
-	MgntLinkKeepAlive(priv);
-
-	LeisurePSLeave(priv);
-
-	if (priv->ieee80211->state == IEEE80211_LINKED) {
-		priv->link_detect.num_rx_ok_in_period =
-			priv->ieee80211->NumRxDataInPeriod;
-		if (priv->link_detect.num_rx_ok_in_period > 666 ||
-			priv->link_detect.num_tx_ok_in_period > 666) {
-			bBusyTraffic = true;
-		}
-		if ((priv->link_detect.num_rx_ok_in_period +
-			priv->link_detect.num_tx_ok_in_period > 8)
-			|| (priv->link_detect.num_rx_ok_in_period > 2)) {
-			bEnterPS = false;
-		} else
-			bEnterPS = true;
-
-		if (bEnterPS)
-			LeisurePSEnter(priv);
-		else
-			LeisurePSLeave(priv);
-	} else
-		LeisurePSLeave(priv);
-	priv->link_detect.b_busy_traffic = bBusyTraffic;
-	priv->link_detect.num_rx_ok_in_period = 0;
-	priv->link_detect.num_tx_ok_in_period = 0;
-	priv->ieee80211->NumRxDataInPeriod = 0;
-	priv->ieee80211->NumRxBcnInPeriod = 0;
-}
-
-static int _rtl8180_up(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	priv->up = 1;
-
-	DMESG("Bringing up iface");
-	rtl8185b_adapter_start(dev);
-	rtl8185b_rx_enable(dev);
-	rtl8185b_tx_enable(dev);
-	if (priv->bInactivePs) {
-		if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
-			IPSLeave(dev);
-	}
-	timer_rate_adaptive((unsigned long)dev);
-	watch_dog_adaptive((unsigned long)dev);
-	if (priv->bSwAntennaDiverity)
-			SwAntennaDiversityTimerCallback(dev);
-	ieee80211_softmac_start_protocol(priv->ieee80211);
-	return 0;
-}
-
-static int rtl8180_open(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-
-	down(&priv->wx_sem);
-	ret = rtl8180_up(dev);
-	up(&priv->wx_sem);
-	return ret;
-}
-
-int rtl8180_up(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->up == 1)
-		return -1;
-
-	return _rtl8180_up(dev);
-}
-
-static int rtl8180_close(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-
-	down(&priv->wx_sem);
-	ret = rtl8180_down(dev);
-	up(&priv->wx_sem);
-
-	return ret;
-}
-
-int rtl8180_down(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->up == 0)
-		return -1;
-
-	priv->up = 0;
-
-	ieee80211_softmac_stop_protocol(priv->ieee80211);
-	/* FIXME */
-	if (!netif_queue_stopped(dev))
-		netif_stop_queue(dev);
-	rtl8180_rtx_disable(dev);
-	rtl8180_irq_disable(dev);
-	del_timer_sync(&priv->watch_dog_timer);
-	del_timer_sync(&priv->rateadapter_timer);
-	cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
-	cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
-	del_timer_sync(&priv->SwAntennaDiversityTimer);
-	SetZebraRFPowerState8185(dev, RF_OFF);
-	memset(&priv->ieee80211->current_network,
-		0, sizeof(struct ieee80211_network));
-	priv->ieee80211->state = IEEE80211_NOLINK;
-	return 0;
-}
-
-void rtl8180_restart_wq(struct work_struct *work)
-{
-	struct r8180_priv *priv = container_of(
-		work, struct r8180_priv, reset_wq);
-	struct net_device *dev = priv->dev;
-
-	down(&priv->wx_sem);
-
-	rtl8180_commit(dev);
-
-	up(&priv->wx_sem);
-}
-
-static void rtl8180_restart(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	schedule_work(&priv->reset_wq);
-}
-
-void rtl8180_commit(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->up == 0)
-		return;
-
-	del_timer_sync(&priv->watch_dog_timer);
-	del_timer_sync(&priv->rateadapter_timer);
-	cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
-	cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
-	del_timer_sync(&priv->SwAntennaDiversityTimer);
-	ieee80211_softmac_stop_protocol(priv->ieee80211);
-	rtl8180_irq_disable(dev);
-	rtl8180_rtx_disable(dev);
-	_rtl8180_up(dev);
-}
-
-static void r8180_set_multicast(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	short promisc;
-
-	promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
-
-	if (promisc != priv->promisc)
-		rtl8180_restart(dev);
-
-	priv->promisc = promisc;
-}
-
-static int r8180_set_mac_adr(struct net_device *dev, void *mac)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct sockaddr *addr = mac;
-
-	down(&priv->wx_sem);
-
-	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-
-	if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
-		memcpy(priv->ieee80211->current_network.bssid,
-			dev->dev_addr, ETH_ALEN);
-
-	if (priv->up) {
-		rtl8180_down(dev);
-		rtl8180_up(dev);
-	}
-
-	up(&priv->wx_sem);
-
-	return 0;
-}
-
-/* based on ipw2200 driver */
-static int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct iwreq *wrq = (struct iwreq *) rq;
-	int ret = -1;
-
-	switch (cmd) {
-	case RTL_IOCTL_WPA_SUPPLICANT:
-		ret = ieee80211_wpa_supplicant_ioctl(
-			priv->ieee80211, &wrq->u.data);
-		return ret;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-static const struct net_device_ops rtl8180_netdev_ops = {
-	.ndo_open		= rtl8180_open,
-	.ndo_stop		= rtl8180_close,
-	.ndo_get_stats		= rtl8180_stats,
-	.ndo_tx_timeout		= rtl8180_restart,
-	.ndo_do_ioctl		= rtl8180_ioctl,
-	.ndo_set_rx_mode	= r8180_set_multicast,
-	.ndo_set_mac_address	= r8180_set_mac_adr,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_start_xmit		= ieee80211_rtl_xmit,
-};
-
-static int rtl8180_pci_probe(struct pci_dev *pdev,
-			     const struct pci_device_id *id)
-{
-	unsigned long ioaddr = 0;
-	struct net_device *dev = NULL;
-	struct r8180_priv *priv = NULL;
-	u8 unit = 0;
-	int ret = -ENODEV;
-
-	unsigned long pmem_start, pmem_len, pmem_flags;
-
-	DMESG("Configuring chip resources");
-
-	if (pci_enable_device(pdev)) {
-		DMESG("Failed to enable PCI device");
-		return -EIO;
-	}
-
-	pci_set_master(pdev);
-	pci_set_dma_mask(pdev, 0xffffff00ULL);
-	pci_set_consistent_dma_mask(pdev, 0xffffff00ULL);
-	dev = alloc_ieee80211(sizeof(struct r8180_priv));
-	if (!dev) {
-		ret = -ENOMEM;
-		goto fail_free;
-	}
-	priv = ieee80211_priv(dev);
-	priv->ieee80211 = netdev_priv(dev);
-
-	pci_set_drvdata(pdev, dev);
-	SET_NETDEV_DEV(dev, &pdev->dev);
-
-	priv = ieee80211_priv(dev);
-	priv->pdev = pdev;
-
-	pmem_start = pci_resource_start(pdev, 1);
-	pmem_len = pci_resource_len(pdev, 1);
-	pmem_flags = pci_resource_flags(pdev, 1);
-
-	if (!(pmem_flags & IORESOURCE_MEM)) {
-		DMESG("region #1 not a MMIO resource, aborting");
-		goto fail;
-	}
-
-	if (!request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) {
-		DMESG("request_mem_region failed!");
-		goto fail;
-	}
-
-	ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len);
-	if (ioaddr == (unsigned long)NULL) {
-		DMESG("ioremap failed!");
-		goto fail1;
-	}
-
-	dev->mem_start = ioaddr; /* shared mem start */
-	dev->mem_end = ioaddr + pci_resource_len(pdev, 0); /* shared mem end */
-
-	pci_read_config_byte(pdev, 0x05, &unit);
-	pci_write_config_byte(pdev, 0x05, unit & (~0x04));
-
-	dev->irq = pdev->irq;
-	priv->irq = 0;
-
-	dev->netdev_ops = &rtl8180_netdev_ops;
-	dev->wireless_handlers = &r8180_wx_handlers_def;
-
-	dev->type = ARPHRD_ETHER;
-	dev->watchdog_timeo = HZ*3;
-
-	if (dev_alloc_name(dev, ifname) < 0) {
-		DMESG("Oops: devname already taken! Trying wlan%%d...\n");
-		strcpy(ifname, "wlan%d");
-		dev_alloc_name(dev, ifname);
-	}
-
-	if (rtl8180_init(dev) != 0) {
-		DMESG("Initialization failed");
-		goto fail1;
-	}
-
-	netif_carrier_off(dev);
-
-	if (register_netdev(dev))
-		goto fail1;
-
-	rtl8180_proc_init_one(dev);
-
-	DMESG("Driver probe completed\n");
-	return 0;
-fail1:
-	if (dev->mem_start != (unsigned long)NULL) {
-		iounmap((void __iomem *)dev->mem_start);
-		release_mem_region(pci_resource_start(pdev, 1),
-				   pci_resource_len(pdev, 1));
-	}
-fail:
-	if (dev) {
-		if (priv->irq) {
-			free_irq(dev->irq, dev);
-			dev->irq = 0;
-		}
-		free_ieee80211(dev);
-	}
-
-fail_free:
-	pci_disable_device(pdev);
-
-	DMESG("wlan driver load failed\n");
-	return ret;
-}
-
-static void rtl8180_pci_remove(struct pci_dev *pdev)
-{
-	struct r8180_priv *priv;
-	struct net_device *dev = pci_get_drvdata(pdev);
-
-	if (dev) {
-		unregister_netdev(dev);
-
-		priv = ieee80211_priv(dev);
-
-		rtl8180_proc_remove_one(dev);
-		rtl8180_down(dev);
-		priv->rf_close(dev);
-		rtl8180_reset(dev);
-		mdelay(10);
-
-		if (priv->irq) {
-			DMESG("Freeing irq %d", dev->irq);
-			free_irq(dev->irq, dev);
-			priv->irq = 0;
-		}
-
-		free_rx_desc_ring(dev);
-		free_tx_desc_rings(dev);
-
-		if (dev->mem_start != (unsigned long)NULL) {
-			iounmap((void __iomem *)dev->mem_start);
-			release_mem_region(pci_resource_start(pdev, 1),
-					   pci_resource_len(pdev, 1));
-		}
-
-		free_ieee80211(dev);
-	}
-	pci_disable_device(pdev);
-
-	DMESG("wlan driver removed\n");
-}
-
-static int __init rtl8180_pci_module_init(void)
-{
-	int ret;
-
-	ret = ieee80211_crypto_init();
-	if (ret) {
-		pr_err("ieee80211_crypto_init() failed %d\n", ret);
-		return ret;
-	}
-	ret = ieee80211_crypto_tkip_init();
-	if (ret) {
-		pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
-		return ret;
-	}
-	ret = ieee80211_crypto_ccmp_init();
-	if (ret) {
-		pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
-		return ret;
-	}
-	ret = ieee80211_crypto_wep_init();
-	if (ret) {
-		pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
-		return ret;
-	}
-
-	pr_info("\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
-	pr_info("Copyright (c) 2004-2005, Andrea Merello\n");
-	DMESG("Initializing module");
-	DMESG("Wireless extensions version %d", WIRELESS_EXT);
-	rtl8180_proc_module_init();
-
-	if (pci_register_driver(&rtl8180_pci_driver)) {
-		DMESG("No device found");
-		return -ENODEV;
-	}
-	return 0;
-}
-
-static void __exit rtl8180_pci_module_exit(void)
-{
-	pci_unregister_driver(&rtl8180_pci_driver);
-	rtl8180_proc_module_remove();
-	ieee80211_crypto_tkip_exit();
-	ieee80211_crypto_ccmp_exit();
-	ieee80211_crypto_wep_exit();
-	ieee80211_crypto_deinit();
-	DMESG("Exiting");
-}
-
-static void rtl8180_try_wake_queue(struct net_device *dev, int pri)
-{
-	unsigned long flags;
-	short enough_desc;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	spin_lock_irqsave(&priv->tx_lock, flags);
-	enough_desc = check_nic_enought_desc(dev, pri);
-	spin_unlock_irqrestore(&priv->tx_lock, flags);
-
-	if (enough_desc)
-		ieee80211_rtl_wake_queue(priv->ieee80211);
-}
-
-static void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u32 *tail; /* tail virtual addr */
-	u32 *head; /* head virtual addr */
-	u32 *begin; /* start of ring virtual addr */
-	u32 *nicv; /* nic pointer virtual addr */
-	u32 nic; /* nic pointer physical addr */
-	u32 nicbegin; /* start of ring physical addr */
-	unsigned long flag;
-	/* physical addr are ok on 32 bits since we set DMA mask */
-	int offs;
-	int j, i;
-	int hd;
-	if (error)
-		priv->stats.txretry++;
-	spin_lock_irqsave(&priv->tx_lock, flag);
-	switch (pri) {
-	case MANAGE_PRIORITY:
-		tail = priv->txmapringtail;
-		begin = priv->txmapring;
-		head = priv->txmapringhead;
-		nic = read_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR);
-		nicbegin = priv->txmapringdma;
-		break;
-	case BK_PRIORITY:
-		tail = priv->txbkpringtail;
-		begin = priv->txbkpring;
-		head = priv->txbkpringhead;
-		nic = read_nic_dword(dev, TX_BKPRIORITY_RING_ADDR);
-		nicbegin = priv->txbkpringdma;
-		break;
-	case BE_PRIORITY:
-		tail = priv->txbepringtail;
-		begin = priv->txbepring;
-		head = priv->txbepringhead;
-		nic = read_nic_dword(dev, TX_BEPRIORITY_RING_ADDR);
-		nicbegin = priv->txbepringdma;
-		break;
-	case VI_PRIORITY:
-		tail = priv->txvipringtail;
-		begin = priv->txvipring;
-		head = priv->txvipringhead;
-		nic = read_nic_dword(dev, TX_VIPRIORITY_RING_ADDR);
-		nicbegin = priv->txvipringdma;
-		break;
-	case VO_PRIORITY:
-		tail = priv->txvopringtail;
-		begin = priv->txvopring;
-		head = priv->txvopringhead;
-		nic = read_nic_dword(dev, TX_VOPRIORITY_RING_ADDR);
-		nicbegin = priv->txvopringdma;
-		break;
-	case HI_PRIORITY:
-		tail = priv->txhpringtail;
-		begin = priv->txhpring;
-		head = priv->txhpringhead;
-		nic = read_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR);
-		nicbegin = priv->txhpringdma;
-		break;
-
-	default:
-		spin_unlock_irqrestore(&priv->tx_lock, flag);
-		return;
-	}
-
-	nicv = (u32 *)((nic - nicbegin) + (u8 *)begin);
-	if ((head <= tail && (nicv > tail || nicv < head)) ||
-		(head > tail && (nicv > tail && nicv < head))) {
-			DMESGW("nic has lost pointer");
-			spin_unlock_irqrestore(&priv->tx_lock, flag);
-			rtl8180_restart(dev);
-			return;
-		}
-
-	/*
-	 * We check all the descriptors between the head and the nic,
-	 * but not the currently pointed by the nic (the next to be txed)
-	 * and the previous of the pointed (might be in process ??)
-	 */
-	offs = (nic - nicbegin);
-	offs = offs / 8 / 4;
-	hd = (head - begin) / 8;
-
-	if (offs >= hd)
-		j = offs - hd;
-	else
-		j = offs + (priv->txringcount-1-hd);
-
-	j -= 2;
-	if (j < 0)
-		j = 0;
-
-	for (i = 0; i < j; i++) {
-		if ((*head) & (1<<31))
-			break;
-		if (((*head)&(0x10000000)) != 0) {
-			priv->CurrRetryCnt += (u16)((*head) & (0x000000ff));
-			if (!error)
-				priv->NumTxOkTotal++;
-		}
-
-		if (!error)
-			priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff);
-
-		*head = *head & ~(1<<31);
-
-		if ((head - begin)/8 == priv->txringcount-1)
-			head = begin;
-		else
-			head += 8;
-	}
-
-	/*
-	 * The head has been moved to the last certainly TXed
-	 * (or at least processed by the nic) packet.
-	 * The driver take forcefully owning of all these packets
-	 * If the packet previous of the nic pointer has been
-	 * processed this doesn't matter: it will be checked
-	 * here at the next round. Anyway if no more packet are
-	 * TXed no memory leak occur at all.
-	 */
-
-	switch (pri) {
-	case MANAGE_PRIORITY:
-		priv->txmapringhead = head;
-
-		if (priv->ack_tx_to_ieee) {
-			if (rtl8180_is_tx_queue_empty(dev)) {
-				priv->ack_tx_to_ieee = 0;
-				ieee80211_ps_tx_ack(priv->ieee80211, !error);
-			}
-		}
-		break;
-	case BK_PRIORITY:
-		priv->txbkpringhead = head;
-		break;
-	case BE_PRIORITY:
-		priv->txbepringhead = head;
-		break;
-	case VI_PRIORITY:
-		priv->txvipringhead = head;
-		break;
-	case VO_PRIORITY:
-		priv->txvopringhead = head;
-		break;
-	case HI_PRIORITY:
-		priv->txhpringhead = head;
-		break;
-	}
-
-	spin_unlock_irqrestore(&priv->tx_lock, flag);
-}
-
-static irqreturn_t rtl8180_interrupt(int irq, void *netdev)
-{
-	struct net_device *dev = (struct net_device *) netdev;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	unsigned long flags;
-	u32 inta;
-
-	/* We should return IRQ_NONE, but for now let me keep this */
-	if (priv->irq_enabled == 0)
-		return IRQ_HANDLED;
-
-	spin_lock_irqsave(&priv->irq_th_lock, flags);
-
-	/* ISR: 4bytes */
-	inta = read_nic_dword(dev, ISR);
-	write_nic_dword(dev, ISR, inta); /* reset int situation */
-
-	priv->stats.shints++;
-
-	if (!inta) {
-		spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-		return IRQ_HANDLED;
-	/*
-	 * most probably we can safely return IRQ_NONE,
-	 * but for now is better to avoid problems
-	 */
-	}
-
-	if (inta == 0xffff) {
-		/* HW disappeared */
-		spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-		return IRQ_HANDLED;
-	}
-
-	priv->stats.ints++;
-
-	if (!netif_running(dev)) {
-		spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-		return IRQ_HANDLED;
-	}
-
-	if (inta & ISR_TimeOut)
-		write_nic_dword(dev, TimerInt, 0);
-
-	if (inta & ISR_TBDOK)
-		priv->stats.txbeacon++;
-
-	if (inta & ISR_TBDER)
-		priv->stats.txbeaconerr++;
-
-	if (inta & IMR_TMGDOK)
-		rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0);
-
-	if (inta & ISR_THPDER) {
-		priv->stats.txhperr++;
-		rtl8180_tx_isr(dev, HI_PRIORITY, 1);
-		priv->ieee80211->stats.tx_errors++;
-	}
-
-	if (inta & ISR_THPDOK) { /* High priority tx ok */
-		priv->link_detect.num_tx_ok_in_period++;
-		priv->stats.txhpokint++;
-		rtl8180_tx_isr(dev, HI_PRIORITY, 0);
-	}
-
-	if (inta & ISR_RER)
-		priv->stats.rxerr++;
-
-	if (inta & ISR_TBKDER) { /* corresponding to BK_PRIORITY */
-		priv->stats.txbkperr++;
-		priv->ieee80211->stats.tx_errors++;
-		rtl8180_tx_isr(dev, BK_PRIORITY, 1);
-		rtl8180_try_wake_queue(dev, BK_PRIORITY);
-	}
-
-	if (inta & ISR_TBEDER) { /* corresponding to BE_PRIORITY */
-		priv->stats.txbeperr++;
-		priv->ieee80211->stats.tx_errors++;
-		rtl8180_tx_isr(dev, BE_PRIORITY, 1);
-		rtl8180_try_wake_queue(dev, BE_PRIORITY);
-	}
-	if (inta & ISR_TNPDER) { /* corresponding to VO_PRIORITY */
-		priv->stats.txnperr++;
-		priv->ieee80211->stats.tx_errors++;
-		rtl8180_tx_isr(dev, NORM_PRIORITY, 1);
-		rtl8180_try_wake_queue(dev, NORM_PRIORITY);
-	}
-
-	if (inta & ISR_TLPDER) { /* corresponding to VI_PRIORITY */
-		priv->stats.txlperr++;
-		priv->ieee80211->stats.tx_errors++;
-		rtl8180_tx_isr(dev, LOW_PRIORITY, 1);
-		rtl8180_try_wake_queue(dev, LOW_PRIORITY);
-	}
-
-	if (inta & ISR_ROK) {
-		priv->stats.rxint++;
-		tasklet_schedule(&priv->irq_rx_tasklet);
-	}
-
-	if (inta & ISR_RQoSOK) {
-		priv->stats.rxint++;
-		tasklet_schedule(&priv->irq_rx_tasklet);
-	}
-
-	if (inta & ISR_BcnInt)
-		rtl8180_prepare_beacon(dev);
-
-	if (inta & ISR_RDU) {
-		DMESGW("No RX descriptor available");
-		priv->stats.rxrdu++;
-		tasklet_schedule(&priv->irq_rx_tasklet);
-	}
-
-	if (inta & ISR_RXFOVW) {
-		priv->stats.rxoverflow++;
-		tasklet_schedule(&priv->irq_rx_tasklet);
-	}
-
-	if (inta & ISR_TXFOVW)
-		priv->stats.txoverflow++;
-
-	if (inta & ISR_TNPDOK) { /* Normal priority tx ok */
-		priv->link_detect.num_tx_ok_in_period++;
-		priv->stats.txnpokint++;
-		rtl8180_tx_isr(dev, NORM_PRIORITY, 0);
-		rtl8180_try_wake_queue(dev, NORM_PRIORITY);
-	}
-
-	if (inta & ISR_TLPDOK) { /* Low priority tx ok */
-		priv->link_detect.num_tx_ok_in_period++;
-		priv->stats.txlpokint++;
-		rtl8180_tx_isr(dev, LOW_PRIORITY, 0);
-		rtl8180_try_wake_queue(dev, LOW_PRIORITY);
-	}
-
-	if (inta & ISR_TBKDOK) { /* corresponding to BK_PRIORITY */
-		priv->stats.txbkpokint++;
-		priv->link_detect.num_tx_ok_in_period++;
-		rtl8180_tx_isr(dev, BK_PRIORITY, 0);
-		rtl8180_try_wake_queue(dev, BE_PRIORITY);
-	}
-
-	if (inta & ISR_TBEDOK) { /* corresponding to BE_PRIORITY */
-		priv->stats.txbeperr++;
-		priv->link_detect.num_tx_ok_in_period++;
-		rtl8180_tx_isr(dev, BE_PRIORITY, 0);
-		rtl8180_try_wake_queue(dev, BE_PRIORITY);
-	}
-	force_pci_posting(dev);
-	spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-
-	return IRQ_HANDLED;
-}
-
-void rtl8180_irq_rx_tasklet(struct r8180_priv *priv)
-{
-	rtl8180_rx(priv->dev);
-}
-
-void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
-{
-	struct ieee80211_device *ieee = container_of(
-		work, struct ieee80211_device, GPIOChangeRFWorkItem.work);
-	struct net_device *dev = ieee->dev;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 btPSR;
-	u8 btConfig0;
-	enum rt_rf_power_state eRfPowerStateToSet;
-	bool bActuallySet = false;
-
-	char *argv[3];
-	static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
-	static char *envp[] = {"HOME=/", "TERM=linux",
-		"PATH=/usr/bin:/bin", NULL};
-	static int readf_count;
-
-	readf_count = (readf_count+1)%0xffff;
-	/* We should turn off LED before polling FF51[4]. */
-
-	/* Turn off LED. */
-	btPSR = read_nic_byte(dev, PSR);
-	write_nic_byte(dev, PSR, (btPSR & ~BIT3));
-
-	/* It need to delay 4us suggested */
-	udelay(4);
-
-	/* HW radio On/Off according to the value of FF51[4](config0) */
-	btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
-
-	eRfPowerStateToSet = (btConfig0 & BIT4) ?  RF_ON : RF_OFF;
-
-	/* Turn LED back on when radio enabled */
-	if (eRfPowerStateToSet == RF_ON)
-		write_nic_byte(dev, PSR, btPSR | BIT3);
-
-	if ((priv->ieee80211->bHwRadioOff == true) &&
-	   (eRfPowerStateToSet == RF_ON)) {
-		priv->ieee80211->bHwRadioOff = false;
-		bActuallySet = true;
-	} else if ((priv->ieee80211->bHwRadioOff == false) &&
-		  (eRfPowerStateToSet == RF_OFF)) {
-		priv->ieee80211->bHwRadioOff = true;
-		bActuallySet = true;
-	}
-
-	if (bActuallySet) {
-		MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
-
-		/* To update the UI status for Power status changed */
-		if (priv->ieee80211->bHwRadioOff == true)
-			argv[1] = "RFOFF";
-		else
-			argv[1] = "RFON";
-		argv[0] = RadioPowerPath;
-		argv[2] = NULL;
-
-		call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
-	}
-}
-
-module_init(rtl8180_pci_module_init);
-module_exit(rtl8180_pci_module_exit);
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
deleted file mode 100644
index 8c020e0..0000000
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ /dev/null
@@ -1,1139 +0,0 @@
-#include "r8180_dm.h"
-#include "r8180_hw.h"
-#include "r8180_93cx6.h"
-
- /*	Return TRUE if we shall perform High Power Mechanism, FALSE otherwise. */
-#define RATE_ADAPTIVE_TIMER_PERIOD      300
-
-bool CheckHighPower(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee80211;
-
-	if (!priv->bRegHighPowerMechanism)
-		return false;
-
-	if (ieee->state == IEEE80211_LINKED_SCANNING)
-		return false;
-
-	return true;
-}
-
-/*
- *	Description:
- *		Update Tx power level if necessary.
- *		See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
- *
- *	Note:
- *		The reason why we udpate Tx power level here instead of DoRxHighPower()
- *		is the number of IO to change Tx power is much more than channel TR switch
- *		and they are related to OFDM and MAC registers.
- *		So, we don't want to update it so frequently in per-Rx packet base.
- */
-static void DoTxHighPower(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u16			HiPwrUpperTh = 0;
-	u16			HiPwrLowerTh = 0;
-	u8			RSSIHiPwrUpperTh;
-	u8			RSSIHiPwrLowerTh;
-	u8			u1bTmp;
-	char			OfdmTxPwrIdx, CckTxPwrIdx;
-
-	HiPwrUpperTh = priv->RegHiPwrUpperTh;
-	HiPwrLowerTh = priv->RegHiPwrLowerTh;
-
-	HiPwrUpperTh = HiPwrUpperTh * 10;
-	HiPwrLowerTh = HiPwrLowerTh * 10;
-	RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
-	RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
-
-	/* lzm add 080826 */
-	OfdmTxPwrIdx  = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
-	CckTxPwrIdx  = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
-	if ((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
-		(priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh))) {
-		/* Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah */
-
-		priv->bToUpdateTxPwr = true;
-		u1bTmp = read_nic_byte(dev, CCK_TXAGC);
-
-		/* If it never enter High Power. */
-		if (CckTxPwrIdx == u1bTmp) {
-			u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0;  /* 8dbm */
-			write_nic_byte(dev, CCK_TXAGC, u1bTmp);
-
-			u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
-			u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0;  /* 8dbm */
-			write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
-		}
-
-	} else if ((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
-		(!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh)) {
-		if (priv->bToUpdateTxPwr) {
-			priv->bToUpdateTxPwr = false;
-			/* SD3 required. */
-			u1bTmp = read_nic_byte(dev, CCK_TXAGC);
-			if (u1bTmp < CckTxPwrIdx) {
-				write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
-			}
-
-			u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
-			if (u1bTmp < OfdmTxPwrIdx) {
-				write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
-			}
-		}
-	}
-}
-
-
-/*
- *	Description:
- *		Callback function of UpdateTxPowerWorkItem.
- *		Because of some event happened, e.g. CCX TPC, High Power Mechanism,
- *		We update Tx power of current channel again.
- */
-void rtl8180_tx_pw_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, tx_pw_wq);
-	struct net_device *dev = ieee->dev;
-
-	DoTxHighPower(dev);
-}
-
-
-/*
- *	Return TRUE if we shall perform DIG Mechanism, FALSE otherwise.
- */
-bool CheckDig(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee80211;
-
-	if (!priv->bDigMechanism)
-		return false;
-
-	if (ieee->state != IEEE80211_LINKED)
-		return false;
-
-	if ((priv->ieee80211->rate / 5) < 36) /* Schedule Dig under all OFDM rates. By Bruce, 2007-06-01. */
-		return false;
-	return true;
-}
-/*
- *	Implementation of DIG for Zebra and Zebra2.
- */
-static void DIG_Zebra(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u16			CCKFalseAlarm, OFDMFalseAlarm;
-	u16			OfdmFA1, OfdmFA2;
-	int			InitialGainStep = 7; /* The number of initial gain stages. */
-	int			LowestGainStage = 4; /* The capable lowest stage of performing dig workitem. */
-	u32			AwakePeriodIn2Sec = 0;
-
-	CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
-	OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
-	OfdmFA1 =  0x15;
-	OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
-
-	/* The number of initial gain steps is different, by Bruce, 2007-04-13. */
-	if (priv->InitialGain == 0) { /* autoDIG */
-		/* Advised from SD3 DZ */
-		priv->InitialGain = 4; /* In 87B, m74dBm means State 4 (m82dBm) */
-	}
-	/* Advised from SD3 DZ */
-	OfdmFA1 = 0x20;
-
-#if 1 /* lzm reserved 080826 */
-	AwakePeriodIn2Sec = (2000 - priv->DozePeriodInPast2Sec);
-	priv->DozePeriodInPast2Sec = 0;
-
-	if (AwakePeriodIn2Sec) {
-		OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000);
-		OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000);
-	} else {
-		;
-	}
-#endif
-
-	InitialGainStep = 8;
-	LowestGainStage = priv->RegBModeGainStage; /* Lowest gain stage. */
-
-	if (OFDMFalseAlarm > OfdmFA1) {
-		if (OFDMFalseAlarm > OfdmFA2) {
-			priv->DIG_NumberFallbackVote++;
-			if (priv->DIG_NumberFallbackVote > 1) {
-				/* serious OFDM  False Alarm, need fallback */
-				if (priv->InitialGain < InitialGainStep) {
-					priv->InitialGainBackUp = priv->InitialGain;
-
-					priv->InitialGain = (priv->InitialGain + 1);
-					UpdateInitialGain(dev);
-				}
-				priv->DIG_NumberFallbackVote = 0;
-				priv->DIG_NumberUpgradeVote = 0;
-			}
-		} else {
-			if (priv->DIG_NumberFallbackVote)
-				priv->DIG_NumberFallbackVote--;
-		}
-		priv->DIG_NumberUpgradeVote = 0;
-	} else {
-		if (priv->DIG_NumberFallbackVote)
-			priv->DIG_NumberFallbackVote--;
-		priv->DIG_NumberUpgradeVote++;
-
-		if (priv->DIG_NumberUpgradeVote > 9) {
-			if (priv->InitialGain > LowestGainStage) { /* In 87B, m78dBm means State 4 (m864dBm) */
-				priv->InitialGainBackUp = priv->InitialGain;
-
-				priv->InitialGain = (priv->InitialGain - 1);
-				UpdateInitialGain(dev);
-			}
-			priv->DIG_NumberFallbackVote = 0;
-			priv->DIG_NumberUpgradeVote = 0;
-		}
-	}
-}
-
-/*
- *	Dispatch DIG implementation according to RF.
- */
-static void DynamicInitGain(struct net_device *dev)
-{
-	DIG_Zebra(dev);
-}
-
-void rtl8180_hw_dig_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_dig_wq);
-	struct net_device *dev = ieee->dev;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	/* Read CCK and OFDM False Alarm. */
-	priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
-
-
-	/* Adjust Initial Gain dynamically. */
-	DynamicInitGain(dev);
-
-}
-
-static int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
-{
-	u8 rate_len;
-	u8 rate_ex_len;
-	u8                      RateMask = 0x7F;
-	u8                      idx;
-	unsigned short          Found = 0;
-	u8                      NaiveTxRate = TxRate&RateMask;
-
-	rate_len = priv->ieee80211->current_network.rates_len;
-	rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
-	for (idx = 0; idx < rate_len; idx++) {
-		if ((priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate) {
-			Found = 1;
-			goto found_rate;
-		}
-	}
-	for (idx = 0; idx < rate_ex_len; idx++) {
-		if ((priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate) {
-			Found = 1;
-			goto found_rate;
-		}
-	}
-	return Found;
-found_rate:
-	return Found;
-}
-
-/*
- *	Get the Tx rate one degree up form the input rate in the supported rates.
- *	Return the upgrade rate if it is successed, otherwise return the input rate.
- */
-static u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8                      UpRate;
-
-	/* Upgrade 1 degree. */
-	switch (rate) {
-	case 108: /* Up to 54Mbps. */
-		UpRate = 108;
-		break;
-
-	case 96: /* Up to 54Mbps. */
-		UpRate = 108;
-		break;
-
-	case 72: /* Up to 48Mbps. */
-		UpRate = 96;
-		break;
-
-	case 48: /* Up to 36Mbps. */
-		UpRate = 72;
-		break;
-
-	case 36: /* Up to 24Mbps. */
-		UpRate = 48;
-		break;
-
-	case 22: /* Up to 18Mbps. */
-		UpRate = 36;
-		break;
-
-	case 11: /* Up to 11Mbps. */
-		UpRate = 22;
-		break;
-
-	case 4: /* Up to 5.5Mbps. */
-		UpRate = 11;
-		break;
-
-	case 2: /* Up to 2Mbps. */
-		UpRate = 4;
-		break;
-
-	default:
-		printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
-		return rate;
-	}
-	/* Check if the rate is valid. */
-	if (IncludedInSupportedRates(priv, UpRate)) {
-		return UpRate;
-	} else {
-		return rate;
-	}
-	return rate;
-}
-/*
- *	Get the Tx rate one degree down form the input rate in the supported rates.
- *	Return the degrade rate if it is successed, otherwise return the input rate.
- */
-
-static u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8                      DownRate;
-
-	/* Upgrade 1 degree. */
-	switch (rate) {
-	case 108: /* Down to 48Mbps. */
-		DownRate = 96;
-		break;
-
-	case 96: /* Down to 36Mbps. */
-		DownRate = 72;
-		break;
-
-	case 72: /* Down to 24Mbps. */
-		DownRate = 48;
-		break;
-
-	case 48: /* Down to 18Mbps. */
-		DownRate = 36;
-		break;
-
-	case 36: /* Down to 11Mbps. */
-		DownRate = 22;
-		break;
-
-	case 22: /* Down to 5.5Mbps. */
-		DownRate = 11;
-		break;
-
-	case 11: /* Down to 2Mbps. */
-		DownRate = 4;
-		break;
-
-	case 4: /* Down to 1Mbps. */
-		DownRate = 2;
-		break;
-
-	case 2: /* Down to 1Mbps. */
-		DownRate = 2;
-		break;
-
-	default:
-		printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
-		return rate;
-	}
-	/* Check if the rate is valid. */
-	if (IncludedInSupportedRates(priv, DownRate)) {
-		return DownRate;
-	} else {
-		return rate;
-	}
-	return rate;
-}
-/*
- *      Helper function to determine if specified data rate is
- *      CCK rate.
- */
-
-static bool MgntIsCckRate(u16 rate)
-{
-	bool bReturn = false;
-
-	if ((rate <= 22) && (rate != 12) && (rate != 18)) {
-		bReturn = true;
-	}
-
-	return bReturn;
-}
-/*
- *	Description:
- *		Tx Power tracking mechanism routine on 87SE.
- */
-void TxPwrTracking87SE(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u8	tmpu1Byte, CurrentThermal, Idx;
-	char	CckTxPwrIdx, OfdmTxPwrIdx;
-
-	tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
-	CurrentThermal = (tmpu1Byte & 0xf0) >> 4; /*[ 7:4]: thermal meter indication. */
-	CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c : CurrentThermal;/* lzm add 080826 */
-
-	if (CurrentThermal != priv->ThermalMeter) {
-		/* Update Tx Power level on each channel. */
-		for (Idx = 1; Idx < 15; Idx++) {
-			CckTxPwrIdx = priv->chtxpwr[Idx];
-			OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
-
-			if (CurrentThermal > priv->ThermalMeter) {
-				/* higher thermal meter. */
-				CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
-				OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
-
-				if (CckTxPwrIdx > 35)
-					CckTxPwrIdx = 35; /* Force TxPower to maximal index. */
-				if (OfdmTxPwrIdx > 35)
-					OfdmTxPwrIdx = 35;
-			} else {
-				/* lower thermal meter. */
-				CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
-				OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
-
-				if (CckTxPwrIdx < 0)
-					CckTxPwrIdx = 0;
-				if (OfdmTxPwrIdx < 0)
-					OfdmTxPwrIdx = 0;
-			}
-
-			/* Update TxPower level on CCK and OFDM resp. */
-			priv->chtxpwr[Idx] = CckTxPwrIdx;
-			priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
-		}
-
-		/* Update TxPower level immediately. */
-		rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
-	}
-	priv->ThermalMeter = CurrentThermal;
-}
-static void StaRateAdaptive87SE(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	unsigned long	CurrTxokCnt;
-	u16		CurrRetryCnt;
-	u16		CurrRetryRate;
-	unsigned long	CurrRxokCnt;
-	bool		bTryUp = false;
-	bool		bTryDown = false;
-	u8		TryUpTh = 1;
-	u8		TryDownTh = 2;
-	u32		TxThroughput;
-	long		CurrSignalStrength;
-	bool		bUpdateInitialGain = false;
-	u8		u1bOfdm = 0, u1bCck = 0;
-	char		OfdmTxPwrIdx, CckTxPwrIdx;
-
-	priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
-
-
-	CurrRetryCnt	= priv->CurrRetryCnt;
-	CurrTxokCnt	= priv->NumTxOkTotal - priv->LastTxokCnt;
-	CurrRxokCnt	= priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
-	CurrSignalStrength = priv->Stats_RecvSignalPower;
-	TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
-	priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
-	priv->CurrentOperaRate = priv->ieee80211->rate / 5;
-	/* 2 Compute retry ratio. */
-	if (CurrTxokCnt > 0) {
-		CurrRetryRate = (u16)(CurrRetryCnt * 100 / CurrTxokCnt);
-	} else {
-	/* It may be serious retry. To distinguish serious retry or no packets modified by Bruce */
-		CurrRetryRate = (u16)(CurrRetryCnt * 100 / 1);
-	}
-
-	priv->LastRetryCnt = priv->CurrRetryCnt;
-	priv->LastTxokCnt = priv->NumTxOkTotal;
-	priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
-	priv->CurrRetryCnt = 0;
-
-	/* 2No Tx packets, return to init_rate or not? */
-	if (CurrRetryRate == 0 && CurrTxokCnt == 0) {
-		/*
-		 * After 9 (30*300ms) seconds in this condition, we try to raise rate.
-		 */
-		priv->TryupingCountNoData++;
-
-		/* [TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00 */
-		if (priv->TryupingCountNoData > 30) {
-			priv->TryupingCountNoData = 0;
-			priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
-			/* Reset Fail Record */
-			priv->LastFailTxRate = 0;
-			priv->LastFailTxRateSS = -200;
-			priv->FailTxRateCount = 0;
-		}
-		goto SetInitialGain;
-	} else {
-		priv->TryupingCountNoData = 0; /*Reset trying up times. */
-	}
-
-
-	/*
-	 * For Netgear case, I comment out the following signal strength estimation,
-	 * which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
-	 *
-	 * Restructure rate adaptive as the following main stages:
-	 * (1) Add retry threshold in 54M upgrading condition with signal strength.
-	 * (2) Add the mechanism to degrade to CCK rate according to signal strength
-	 *		and retry rate.
-	 * (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
-	 *		situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
-	 * (4) Add the mechanism of trying to upgrade tx rate.
-	 * (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
-	 *
-	 */
-
-	/*
-	 * 11Mbps or 36Mbps
-	 * Check more times in these rate(key rates).
-	 */
-	if (priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
-		TryUpTh += 9;
-	/*
-	 * Let these rates down more difficult.
-	 */
-	if (MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
-		TryDownTh += 1;
-
-	/* 1 Adjust Rate. */
-	if (priv->bTryuping == true) {
-		/* 2 For Test Upgrading mechanism
-		 * Note:
-		 *	Sometimes the throughput is upon on the capability between the AP and NIC,
-		 *	thus the low data rate does not improve the performance.
-		 *	We randomly upgrade the data rate and check if the retry rate is improved.
-		 */
-
-		/* Upgrading rate did not improve the retry rate, fallback to the original rate. */
-		if ((CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput) {
-			/*Not necessary raising rate, fall back rate. */
-			bTryDown = true;
-		} else {
-			priv->bTryuping = false;
-		}
-	} else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) {
-		/*
-		 * 2For High Power
-		 *
-		 * Return to highest data rate, if signal strength is good enough.
-		 * SignalStrength threshold(-50dbm) is for RTL8186.
-		 * Revise SignalStrength threshold to -51dbm.
-		 */
-		/* Also need to check retry rate for safety, by Bruce, 2007-06-05. */
-		if (priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate) {
-			bTryUp = true;
-			/* Upgrade Tx Rate directly. */
-			priv->TryupingCount += TryUpTh;
-		}
-
-	} else if (CurrTxokCnt > 9 && CurrTxokCnt < 100 && CurrRetryRate >= 600) {
-		/*
-		 *2 For Serious Retry
-		 *
-		 * Traffic is not busy but our Tx retry is serious.
-		 */
-		bTryDown = true;
-		/* Let Rate Mechanism to degrade tx rate directly. */
-		priv->TryDownCountLowData += TryDownTh;
-	} else if (priv->CurrentOperaRate == 108) {
-		/* 2For 54Mbps */
-		/* Air Link */
-		if ((CurrRetryRate > 26) && (priv->LastRetryRate > 25)) {
-			bTryDown = true;
-		}
-		/* Cable Link */
-		else if ((CurrRetryRate > 17) && (priv->LastRetryRate > 16) && (CurrSignalStrength > -72)) {
-			bTryDown = true;
-		}
-
-		if (bTryDown && (CurrSignalStrength < -75)) /* cable link */
-			priv->TryDownCountLowData += TryDownTh;
-	} else if (priv->CurrentOperaRate == 96) {
-		/* 2For 48Mbps */
-		/* Air Link */
-		if (((CurrRetryRate > 48) && (priv->LastRetryRate > 47))) {
-			bTryDown = true;
-		} else if (((CurrRetryRate > 21) && (priv->LastRetryRate > 20)) && (CurrSignalStrength > -74)) { /* Cable Link */
-			/* Down to rate 36Mbps. */
-			bTryDown = true;
-		} else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
-			bTryDown = true;
-			priv->TryDownCountLowData += TryDownTh;
-		} else if ((CurrRetryRate < 8) && (priv->LastRetryRate < 8)) { /* TO DO: need to consider (RSSI) */
-			bTryUp = true;
-		}
-
-		if (bTryDown && (CurrSignalStrength < -75)) {
-			priv->TryDownCountLowData += TryDownTh;
-		}
-	} else if (priv->CurrentOperaRate == 72) {
-		/* 2For 36Mbps */
-		if ((CurrRetryRate > 43) && (priv->LastRetryRate > 41)) {
-			/* Down to rate 24Mbps. */
-			bTryDown = true;
-		} else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
-			bTryDown = true;
-			priv->TryDownCountLowData += TryDownTh;
-		} else if ((CurrRetryRate < 15) &&  (priv->LastRetryRate < 16)) { /* TO DO: need to consider (RSSI) */
-			bTryUp = true;
-		}
-
-		if (bTryDown && (CurrSignalStrength < -80))
-			priv->TryDownCountLowData += TryDownTh;
-
-	} else if (priv->CurrentOperaRate == 48) {
-		/* 2For 24Mbps */
-		/* Air Link */
-		if (((CurrRetryRate > 63) && (priv->LastRetryRate > 62))) {
-			bTryDown = true;
-		} else if (((CurrRetryRate > 33) && (priv->LastRetryRate > 32)) && (CurrSignalStrength > -82)) { /* Cable Link */
-			bTryDown = true;
-		} else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
-			bTryDown = true;
-			priv->TryDownCountLowData += TryDownTh;
-		} else if ((CurrRetryRate < 20) && (priv->LastRetryRate < 21)) { /* TO DO: need to consider (RSSI) */
-			bTryUp = true;
-		}
-
-		if (bTryDown && (CurrSignalStrength < -82))
-			priv->TryDownCountLowData += TryDownTh;
-
-	} else if (priv->CurrentOperaRate == 36) {
-		if (((CurrRetryRate > 85) && (priv->LastRetryRate > 86))) {
-			bTryDown = true;
-		} else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
-			bTryDown = true;
-			priv->TryDownCountLowData += TryDownTh;
-		} else if ((CurrRetryRate < 22) && (priv->LastRetryRate < 23)) { /* TO DO: need to consider (RSSI) */
-			bTryUp = true;
-		}
-	} else if (priv->CurrentOperaRate == 22) {
-		/* 2For 11Mbps */
-		if (CurrRetryRate > 95) {
-			bTryDown = true;
-		} else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */
-			bTryUp = true;
-		}
-	} else if (priv->CurrentOperaRate == 11) {
-		/* 2For 5.5Mbps */
-		if (CurrRetryRate > 149) {
-			bTryDown = true;
-		} else if ((CurrRetryRate < 60) && (priv->LastRetryRate < 65)) {
-			bTryUp = true;
-		}
-	} else if (priv->CurrentOperaRate == 4) {
-		/* 2For 2 Mbps */
-		if ((CurrRetryRate > 99) && (priv->LastRetryRate > 99)) {
-			bTryDown = true;
-		} else if ((CurrRetryRate < 65) && (priv->LastRetryRate < 70)) {
-			bTryUp = true;
-		}
-	} else if (priv->CurrentOperaRate == 2) {
-		/* 2For 1 Mbps */
-		if ((CurrRetryRate < 70) && (priv->LastRetryRate < 75)) {
-			bTryUp = true;
-		}
-	}
-
-	if (bTryUp && bTryDown)
-		printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
-
-	/* 1 Test Upgrading Tx Rate
-	 * Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
-	 * To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
-	 */
-	if (!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
-		&& priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2) {
-		if (jiffies % (CurrRetryRate + 101) == 0) {
-			bTryUp = true;
-			priv->bTryuping = true;
-		}
-	}
-
-	/* 1 Rate Mechanism */
-	if (bTryUp) {
-		priv->TryupingCount++;
-		priv->TryDownCountLowData = 0;
-
-		/*
-		 * Check more times if we need to upgrade indeed.
-		 * Because the largest value of pHalData->TryupingCount is 0xFFFF and
-		 * the largest value of pHalData->FailTxRateCount is 0x14,
-		 * this condition will be satisfied at most every 2 min.
-		 */
-
-		if ((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
-			(CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping) {
-			priv->TryupingCount = 0;
-			/*
-			 * When transferring from CCK to OFDM, DIG is an important issue.
-			 */
-			if (priv->CurrentOperaRate == 22)
-				bUpdateInitialGain = true;
-
-			/*
-			 * The difference in throughput between 48Mbps and 36Mbps is 8M.
-			 * So, we must be careful in this rate scale. Isaiah 2008-02-15.
-			 */
-			if (((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
-				(priv->FailTxRateCount > 2))
-				priv->RateAdaptivePeriod = (RATE_ADAPTIVE_TIMER_PERIOD / 2);
-
-			/* (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold. */
-			/* (2)If the signal strength is increased, it may be able to upgrade. */
-
-			priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
-
-			if (priv->CurrentOperaRate == 36) {
-				priv->bUpdateARFR = true;
-				write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
-			} else if (priv->bUpdateARFR) {
-				priv->bUpdateARFR = false;
-				write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
-			}
-
-			/* Update Fail Tx rate and count. */
-			if (priv->LastFailTxRate != priv->CurrentOperaRate) {
-				priv->LastFailTxRate = priv->CurrentOperaRate;
-				priv->FailTxRateCount = 0;
-				priv->LastFailTxRateSS = -200; /* Set lowest power. */
-			}
-		}
-	} else {
-		if (priv->TryupingCount > 0)
-			priv->TryupingCount--;
-	}
-
-	if (bTryDown) {
-		priv->TryDownCountLowData++;
-		priv->TryupingCount = 0;
-
-		/* Check if Tx rate can be degraded or Test trying upgrading should fallback. */
-		if (priv->TryDownCountLowData > TryDownTh || priv->bTryuping) {
-			priv->TryDownCountLowData = 0;
-			priv->bTryuping = false;
-			/* Update fail information. */
-			if (priv->LastFailTxRate == priv->CurrentOperaRate) {
-				priv->FailTxRateCount++;
-				/* Record the Tx fail rate signal strength. */
-				if (CurrSignalStrength > priv->LastFailTxRateSS)
-					priv->LastFailTxRateSS = CurrSignalStrength;
-			} else {
-				priv->LastFailTxRate = priv->CurrentOperaRate;
-				priv->FailTxRateCount = 1;
-				priv->LastFailTxRateSS = CurrSignalStrength;
-			}
-			priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
-
-			/* Reduce chariot training time at weak signal strength situation. SD3 ED demand. */
-			if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72)) {
-				priv->CurrentOperaRate = 72;
-			}
-
-			if (priv->CurrentOperaRate == 36) {
-				priv->bUpdateARFR = true;
-				write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
-			} else if (priv->bUpdateARFR) {
-				priv->bUpdateARFR = false;
-				write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
-			}
-
-			/*
-			 * When it is CCK rate, it may need to update initial gain to receive lower power packets.
-			 */
-			if (MgntIsCckRate(priv->CurrentOperaRate)) {
-				bUpdateInitialGain = true;
-			}
-		}
-	} else {
-		if (priv->TryDownCountLowData > 0)
-			priv->TryDownCountLowData--;
-	}
-
-	/*
-	 * Keep the Tx fail rate count to equal to 0x15 at most.
-	 * Reduce the fail count at least to 10 sec if tx rate is tending stable.
-	 */
-	if (priv->FailTxRateCount >= 0x15 ||
-		(!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6)) {
-		priv->FailTxRateCount--;
-	}
-
-
-	OfdmTxPwrIdx  = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
-	CckTxPwrIdx  = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
-	/* Mac0x9e increase 2 level in 36M~18M situation */
-	if ((priv->CurrentOperaRate < 96) && (priv->CurrentOperaRate > 22)) {
-		u1bCck = read_nic_byte(dev, CCK_TXAGC);
-		u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
-		/* case 1: Never enter High power */
-		if (u1bCck == CckTxPwrIdx) {
-			if (u1bOfdm != (OfdmTxPwrIdx + 2)) {
-			priv->bEnhanceTxPwr = true;
-			u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
-			write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
-			}
-		} else if (u1bCck < CckTxPwrIdx) {
-		/* case 2: enter high power */
-			if (!priv->bEnhanceTxPwr) {
-				priv->bEnhanceTxPwr = true;
-				u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
-				write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
-			}
-		}
-	} else if (priv->bEnhanceTxPwr) {  /* 54/48/11/5.5/2/1 */
-		u1bCck = read_nic_byte(dev, CCK_TXAGC);
-		u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
-		/* case 1: Never enter High power */
-		if (u1bCck == CckTxPwrIdx) {
-			priv->bEnhanceTxPwr = false;
-			write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
-		}
-		/* case 2: enter high power */
-		else if (u1bCck < CckTxPwrIdx) {
-			priv->bEnhanceTxPwr = false;
-			u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2) : 0;
-			write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
-		}
-	}
-
-	/*
-	 * We need update initial gain when we set tx rate "from OFDM to CCK" or
-	 * "from CCK to OFDM".
-	 */
-SetInitialGain:
-	if (bUpdateInitialGain) {
-		if (MgntIsCckRate(priv->CurrentOperaRate)) { /* CCK */
-			if (priv->InitialGain > priv->RegBModeGainStage) {
-				priv->InitialGainBackUp = priv->InitialGain;
-
-				if (CurrSignalStrength < -85) /* Low power, OFDM [0x17] = 26. */
-					/* SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26. */
-					priv->InitialGain = priv->RegBModeGainStage;
-
-				else if (priv->InitialGain > priv->RegBModeGainStage + 1)
-					priv->InitialGain -= 2;
-
-				else
-					priv->InitialGain--;
-
-				printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
-				UpdateInitialGain(dev);
-			}
-		} else { /* OFDM */
-			if (priv->InitialGain < 4) {
-				priv->InitialGainBackUp = priv->InitialGain;
-
-				priv->InitialGain++;
-				printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
-				UpdateInitialGain(dev);
-			}
-		}
-	}
-
-	/* Record the related info */
-	priv->LastRetryRate = CurrRetryRate;
-	priv->LastTxThroughput = TxThroughput;
-	priv->ieee80211->rate = priv->CurrentOperaRate * 5;
-}
-
-void rtl8180_rate_adapter(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, rate_adapter_wq);
-	struct net_device *dev = ieee->dev;
-	StaRateAdaptive87SE(dev);
-}
-void timer_rate_adaptive(unsigned long data)
-{
-	struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
-	if (!priv->up) {
-		return;
-	}
-	if ((priv->ieee80211->iw_mode != IW_MODE_MASTER)
-			&& (priv->ieee80211->state == IEEE80211_LINKED) &&
-			(priv->ForcedDataRate == 0)) {
-		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
-	}
-	priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
-	add_timer(&priv->rateadapter_timer);
-}
-
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	priv->AdRxOkCnt++;
-
-	if (priv->AdRxSignalStrength != -1) {
-		priv->AdRxSignalStrength = ((priv->AdRxSignalStrength * 7) + (SignalStrength * 3)) / 10;
-	} else { /* Initialization case. */
-		priv->AdRxSignalStrength = SignalStrength;
-	}
-
-	if (priv->LastRxPktAntenna) /* Main antenna. */
-		priv->AdMainAntennaRxOkCnt++;
-	else	 /* Aux antenna. */
-		priv->AdAuxAntennaRxOkCnt++;
-}
- /*	Change Antenna Switch. */
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	bool bAntennaSwitched = false;
-
-	switch (u1bAntennaIndex) {
-	case 0:
-		/* Mac register, main antenna */
-		write_nic_byte(dev, ANTSEL, 0x03);
-		/* base band */
-		write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */
-		write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */
-
-		bAntennaSwitched = true;
-		break;
-
-	case 1:
-		/* Mac register, aux antenna */
-		write_nic_byte(dev, ANTSEL, 0x00);
-		/* base band */
-		write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */
-		write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */
-
-		bAntennaSwitched = true;
-
-		break;
-
-	default:
-		printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
-		break;
-	}
-
-	if (bAntennaSwitched)
-		priv->CurrAntennaIndex = u1bAntennaIndex;
-
-	return bAntennaSwitched;
-}
- /*	Toggle Antenna switch. */
-bool SwitchAntenna(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	bool		bResult;
-
-	if (priv->CurrAntennaIndex == 0) {
-		bResult = SetAntenna8185(dev, 1);
-	} else {
-		bResult = SetAntenna8185(dev, 0);
-	}
-
-	return bResult;
-}
-/*
- * Engine of SW Antenna Diversity mechanism.
- * Since 8187 has no Tx part information,
- * this implementation is only dependend on Rx part information.
- */
-void SwAntennaDiversity(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	bool   bSwCheckSS = false;
-	if (bSwCheckSS) {
-		priv->AdTickCount++;
-
-		printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
-			priv->AdTickCount, priv->AdCheckPeriod);
-		printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
-			priv->AdRxSignalStrength, priv->AdRxSsThreshold);
-	}
-
-	/* Case 1. No Link. */
-	if (priv->ieee80211->state != IEEE80211_LINKED) {
-		priv->bAdSwitchedChecking = false;
-		/* I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. */
-		SwitchAntenna(dev);
-
-	  /* Case 2. Linked but no packet receive.d */
-	} else if (priv->AdRxOkCnt == 0) {
-		priv->bAdSwitchedChecking = false;
-		SwitchAntenna(dev);
-
-	  /* Case 3. Evaluate last antenna switch action and undo it if necessary. */
-	} else if (priv->bAdSwitchedChecking == true) {
-		priv->bAdSwitchedChecking = false;
-
-		/* Adjust Rx signal strength threshold. */
-		priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
-
-		priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
-					priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;
-		if (priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) {
-		/* Rx signal strength is not improved after we swtiched antenna. => Swich back. */
-			/* Increase Antenna Diversity checking period due to bad decision. */
-			priv->AdCheckPeriod *= 2;
-			/* Increase Antenna Diversity checking period. */
-			if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
-				priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
-
-			/* Wrong decision => switch back. */
-			SwitchAntenna(dev);
-		} else {
-		/* Rx Signal Strength is improved. */
-
-			/* Reset Antenna Diversity checking period to its min value. */
-			priv->AdCheckPeriod = priv->AdMinCheckPeriod;
-		}
-
-	}
-	/* Case 4. Evaluate if we shall switch antenna now. */
-	/* Cause Table Speed is very fast in TRC Dell Lab, we check it every time. */
-	else {
-		priv->AdTickCount = 0;
-
-		/*
-		 * <Roger_Notes> We evaluate RxOk counts for each antenna first and than
-		 * evaluate signal strength.
-		 * The following operation can overcome the disability of CCA on both two antennas
-		 * When signal strength was extremely low or high.
-		 * 2008.01.30.
-		 */
-
-		/*
-		 * Evaluate RxOk count from each antenna if we shall switch default antenna now.
-		 */
-		if ((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
-			&& (priv->CurrAntennaIndex == 0)) {
-		/* We set Main antenna as default but RxOk count was less than Aux ones. */
-
-			/* Switch to Aux antenna. */
-			SwitchAntenna(dev);
-			priv->bHWAdSwitched = true;
-		} else if ((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
-			&& (priv->CurrAntennaIndex == 1)) {
-		/* We set Aux antenna as default but RxOk count was less than Main ones. */
-
-			/* Switch to Main antenna. */
-			SwitchAntenna(dev);
-			priv->bHWAdSwitched = true;
-		} else {
-		/* Default antenna is better. */
-
-			/* Still need to check current signal strength. */
-			priv->bHWAdSwitched = false;
-		}
-		/*
-		 * <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
-		 * didn't change by HW evaluation.
-		 * 2008.02.27.
-		 *
-		 * [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
-		 * For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
-		 * but AdRxSignalStrength is less than main.
-		 * Our guess is that main antenna have lower throughput and get many change
-		 * to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
-		 */
-		if ((!priv->bHWAdSwitched) && (bSwCheckSS)) {
-			/* Evaluate Rx signal strength if we shall switch antenna now. */
-			if (priv->AdRxSignalStrength < priv->AdRxSsThreshold) {
-			/* Rx signal strength is weak => Switch Antenna. */
-				priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
-				priv->bAdSwitchedChecking = true;
-
-				SwitchAntenna(dev);
-			} else {
-			/* Rx signal strength is OK. */
-				priv->bAdSwitchedChecking = false;
-				/* Increase Rx signal strength threshold if necessary. */
-				if ((priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && /* Signal is much stronger than current threshold */
-					priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) { /* Current threhold is not yet reach upper limit. */
-
-					priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
-					priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
-								priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;/* +by amy 080312 */
-				}
-
-				/* Reduce Antenna Diversity checking period if possible. */
-				if (priv->AdCheckPeriod > priv->AdMinCheckPeriod)
-					priv->AdCheckPeriod /= 2;
-			}
-		}
-	}
-	/* Reset antenna diversity Rx related statistics. */
-	priv->AdRxOkCnt = 0;
-	priv->AdMainAntennaRxOkCnt = 0;
-	priv->AdAuxAntennaRxOkCnt = 0;
-}
-
- /*	Return TRUE if we shall perform Tx Power Tracking Mechanism, FALSE otherwise. */
-bool CheckTxPwrTracking(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	if (!priv->bTxPowerTrack)
-		return false;
-
-	/* if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah */
-	if (priv->bToUpdateTxPwr)
-		return false;
-
-	return true;
-}
-
-
- /*	Timer callback function of SW Antenna Diversity. */
-void SwAntennaDiversityTimerCallback(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	enum rt_rf_power_state rtState;
-
-	 /* We do NOT need to switch antenna while RF is off. */
-	rtState = priv->eRFPowerState;
-	do {
-		if (rtState == RF_OFF) {
-			break;
-		} else if (rtState == RF_SLEEP) {
-			/* Don't access BB/RF under Disable PLL situation. */
-			break;
-		}
-		SwAntennaDiversity(dev);
-
-	} while (false);
-
-	if (priv->up) {
-		priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
-		add_timer(&priv->SwAntennaDiversityTimer);
-	}
-}
-
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
deleted file mode 100644
index cb4046f..0000000
--- a/drivers/staging/rtl8187se/r8180_dm.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef R8180_DM_H
-#define R8180_DM_H
-
-#include "r8180.h"
-/* #include "r8180_hw.h"	*/
-/* #include "r8180_93cx6.h"	*/
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
-bool SwitchAntenna(struct net_device *dev);
-void SwAntennaDiversity(struct net_device *dev);
-void SwAntennaDiversityTimerCallback(struct net_device *dev);
-bool CheckDig(struct net_device *dev);
-bool CheckHighPower(struct net_device *dev);
-void rtl8180_hw_dig_wq(struct work_struct *work);
-void rtl8180_tx_pw_wq(struct work_struct *work);
-void rtl8180_rate_adapter(struct work_struct *work);
-void TxPwrTracking87SE(struct net_device *dev);
-bool CheckTxPwrTracking(struct net_device *dev);
-void rtl8180_rate_adapter(struct work_struct *work);
-void timer_rate_adaptive(unsigned long data);
-
-
-#endif
diff --git a/drivers/staging/rtl8187se/r8180_hw.h b/drivers/staging/rtl8187se/r8180_hw.h
deleted file mode 100644
index e59d74f..0000000
--- a/drivers/staging/rtl8187se/r8180_hw.h
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
-	This is part of rtl8180 OpenSource driver.
-	Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the
-	official Realtek driver.
-	Parts of this driver are based on the rtl8180 driver skeleton
-	from Patric Schenke & Andres Salomon.
-	Parts of this driver are based on the Intel Pro Wireless
-	2100 GPL driver.
-
-	We want to tanks the Authors of those projects
-	and the Ndiswrapper project Authors.
-*/
-
-/* Mariusz Matuszek added full registers definition with Realtek's name */
-
-/* this file contains register definitions for the rtl8180 MAC controller */
-#ifndef R8180_HW
-#define R8180_HW
-
-
-#define BIT0	0x00000001
-#define BIT1	0x00000002
-#define BIT2	0x00000004
-#define BIT3	0x00000008
-#define BIT4	0x00000010
-#define BIT5	0x00000020
-#define BIT6	0x00000040
-#define BIT7	0x00000080
-#define BIT9	0x00000200
-#define BIT11	0x00000800
-#define BIT13	0x00002000
-#define BIT15	0x00008000
-#define BIT20	0x00100000
-#define BIT21	0x00200000
-#define BIT22	0x00400000
-#define BIT23	0x00800000
-#define BIT24	0x01000000
-#define BIT25	0x02000000
-#define BIT26	0x04000000
-#define BIT27	0x08000000
-#define BIT28	0x10000000
-#define BIT29	0x20000000
-#define BIT30	0x40000000
-#define BIT31	0x80000000
-
-#define MAX_SLEEP_TIME (10000)
-#define MIN_SLEEP_TIME (50)
-
-#define BB_HOST_BANG_EN (1<<2)
-#define BB_HOST_BANG_CLK (1<<1)
-
-#define MAC0 0
-#define MAC4 4
-
-#define CMD 0x37
-#define CMD_RST_SHIFT 4
-#define CMD_RX_ENABLE_SHIFT 3
-#define CMD_TX_ENABLE_SHIFT 2
-
-#define EPROM_CMD 0x50
-#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
-#define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
-#define EPROM_CMD_CONFIG 0x3
-#define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_LOAD 1
-#define EPROM_CMD_PROGRAM 2
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define EPROM_W_SHIFT 1
-#define EPROM_R_SHIFT 0
-#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
-
-#define INTA_TXOVERFLOW (1<<15)
-#define INTA_TIMEOUT (1<<14)
-#define INTA_HIPRIORITYDESCERR (1<<9)
-#define INTA_HIPRIORITYDESCOK (1<<8)
-#define INTA_NORMPRIORITYDESCERR (1<<7)
-#define INTA_NORMPRIORITYDESCOK (1<<6)
-#define INTA_RXOVERFLOW (1<<5)
-#define INTA_RXDESCERR (1<<4)
-#define INTA_LOWPRIORITYDESCERR (1<<3)
-#define INTA_LOWPRIORITYDESCOK (1<<2)
-#define INTA_RXOK (1)
-#define INTA_MASK 0x3c
-
-#define RXRING_ADDR 0xe4 /* page 0 */
-#define PGSELECT 0x5e
-#define PGSELECT_PG_SHIFT 0
-#define RX_CONF 0x44
-#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
-(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
-#define RX_CHECK_BSSID_SHIFT 23
-#define ACCEPT_PWR_FRAME_SHIFT 22
-#define ACCEPT_MNG_FRAME_SHIFT 20
-#define ACCEPT_CTL_FRAME_SHIFT 19
-#define ACCEPT_DATA_FRAME_SHIFT 18
-#define ACCEPT_ICVERR_FRAME_SHIFT 12
-#define ACCEPT_CRCERR_FRAME_SHIFT 5
-#define ACCEPT_BCAST_FRAME_SHIFT 3
-#define ACCEPT_MCAST_FRAME_SHIFT 2
-#define ACCEPT_ALLMAC_FRAME_SHIFT 0
-#define ACCEPT_NICMAC_FRAME_SHIFT 1
-
-#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
-#define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_NONE 7
-#define RX_AUTORESETPHY_SHIFT 28
-
-#define TX_CONF 0x40
-#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
-#define TX_LOOPBACK_SHIFT 17
-#define TX_LOOPBACK_NONE 0
-#define TX_LOOPBACK_CONTINUE 3
-#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
-#define TX_DPRETRY_SHIFT 0
-#define R8180_MAX_RETRY 255
-#define TX_RTSRETRY_SHIFT 8
-#define TX_NOICV_SHIFT 19
-#define TX_NOCRC_SHIFT 16
-#define TX_DMA_POLLING 0xd9
-#define TX_DMA_POLLING_BEACON_SHIFT 7
-#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
-#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
-#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
-#define TX_MANAGEPRIORITY_RING_ADDR 0x0C
-#define TX_BKPRIORITY_RING_ADDR 0x10
-#define TX_BEPRIORITY_RING_ADDR 0x14
-#define TX_VIPRIORITY_RING_ADDR 0x20
-#define TX_VOPRIORITY_RING_ADDR 0x24
-#define TX_HIGHPRIORITY_RING_ADDR 0x28
-#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-#define MAX_RX_DMA_2048 7
-#define MAX_RX_DMA_1024	6
-#define MAX_RX_DMA_SHIFT 10
-#define INT_TIMEOUT 0x48
-#define CONFIG3_CLKRUN_SHIFT 2
-#define CONFIG3_ANAPARAM_W_SHIFT 6
-#define ANAPARAM 0x54
-#define BEACON_INTERVAL 0x70
-#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
-(1<<6)|(1<<7)|(1<<8)|(1<<9))
-#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
-(1<<8)|(1<<9))
-#define ATIM 0x72
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define PHY_ADR 0x7c
-#define SECURITY 0x5f /* 1209 this is sth wrong */
-#define SECURITY_WEP_TX_ENABLE_SHIFT 1
-#define SECURITY_WEP_RX_ENABLE_SHIFT 0
-#define SECURITY_ENCRYP_104 1
-#define SECURITY_ENCRYP_SHIFT 4
-#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
-#define KEY0 0x90  /* 1209 this is sth wrong */
-#define CONFIG2_ANTENNA_SHIFT 6
-#define TX_BEACON_RING_ADDR 0x4c
-#define CONFIG0_WEP40_SHIFT 7
-#define CONFIG0_WEP104_SHIFT 6
-#define AGCRESET_SHIFT 5
-
-
-
-/*
- * Operational registers offsets in PCI (I/O) space.
- * RealTek names are used.
- */
-
-#define TSFTR 0x0018
-
-#define TLPDA 0x0020
-
-#define BSSID 0x002E
-
-#define CR 0x0037
-
-#define RF_SW_CONFIG	        0x8			/* store data which is transmitted to RF for driver	*/
-#define RF_SW_CFG_SI		BIT1
-#define EIFS			0x2D			/* Extended InterFrame Space Timer, in unit of 4 us.	*/
-
-#define BRSR			0x34			/* Basic rate set										*/
-
-#define IMR 0x006C
-#define ISR 0x003C
-
-#define TCR 0x0040
-
-#define RCR 0x0044
-
-#define TimerInt 0x0048
-
-#define CR9346 0x0050
-
-#define CONFIG0 0x0051
-#define CONFIG2 0x0053
-
-#define MSR 0x0058
-
-#define CONFIG3 0x0059
-#define CONFIG4 0x005A
-	/* SD3 szuyitasi: Mac0x57= CC -> B0 Mac0x60= D1 -> C6	*/
-	/* Mac0x60 = 0x000004C6 power save parameters			*/
-	#define ANAPARM_ASIC_ON    0xB0054D00
-	#define ANAPARM2_ASIC_ON  0x000004C6
-
-	#define ANAPARM_ON ANAPARM_ASIC_ON
-	#define ANAPARM2_ON ANAPARM2_ASIC_ON
-
-#define TESTR 0x005B
-
-#define PSR 0x005E
-
-#define BcnItv 0x0070
-
-#define AtimWnd 0x0072
-
-#define BintrItv 0x0074
-
-#define PhyAddr 0x007C
-#define PhyDataR 0x007E
-
-/* following are for rtl8185 */
-#define RFPinsOutput 0x80
-#define RFPinsEnable 0x82
-#define RF_TIMING 0x8c
-#define RFPinsSelect 0x84
-#define ANAPARAM2 0x60
-#define RF_PARA 0x88
-#define RFPinsInput 0x86
-#define GP_ENABLE 0x90
-#define GPIO 0x91
-#define SW_CONTROL_GPIO 0x400
-#define TX_ANTENNA 0x9f
-#define TX_GAIN_OFDM 0x9e
-#define TX_GAIN_CCK 0x9d
-#define WPA_CONFIG 0xb0
-#define TX_AGC_CTL 0x9c
-#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
-#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
-#define TX_AGC_CTL_FEEDBACK_ANT 2
-#define RESP_RATE 0x34
-#define SIFS 0xb4
-#define DIFS 0xb5
-
-#define SLOT 0xb6
-#define CW_CONF 0xbc
-#define CW_CONF_PERPACKET_RETRY_SHIFT 1
-#define CW_CONF_PERPACKET_CW_SHIFT 0
-#define CW_VAL 0xbd
-#define MAX_RESP_RATE_SHIFT 4
-#define MIN_RESP_RATE_SHIFT 0
-#define RATE_FALLBACK 0xbe
-
-#define CONFIG5 0x00D8
-
-#define PHYPR			0xDA			/* 0xDA - 0x0B PHY Parameter Register.	*/
-
-#define FEMR			0x1D4	/* Function Event Mask register	*/
-
-#define FFER 0x00FC
-#define FFER_END 0x00FF
-
-
-
-/*
- * Bitmasks for specific register functions.
- * Names are derived from the register name and function name.
- *
- * <REGISTER>_<FUNCTION>[<bit>]
- *
- * this leads to some awkward names...
- */
-
-#define BRSR_BPLCP  ((1 << 8))
-#define BRSR_MBR    ((1 << 1)|(1 << 0))
-#define BRSR_MBR_8185 ((1 << 11)|(1 << 10)|(1 << 9)|(1 << 8)|(1 << 7)|(1 << 6)|(1 << 5)|(1 << 4)|(1 << 3)|(1 << 2)|(1 << 1)|(1 << 0))
-#define BRSR_MBR0   ((1 << 0))
-#define BRSR_MBR1   ((1 << 1))
-
-#define CR_RST      ((1 << 4))
-#define CR_RE       ((1 << 3))
-#define CR_TE       ((1 << 2))
-#define CR_MulRW    ((1 << 0))
-
-#define IMR_Dot11hInt	((1 << 25))			/*802.11h Measurement Interrupt					*/
-#define IMR_BcnDmaInt	((1 << 24))			/*Beacon DMA Interrupt */ /*What differenct between BcnDmaInt and BcnInt???	*/
-#define IMR_WakeInt		((1 << 23))			/*Wake Up Interrupt								*/
-#define IMR_TXFOVW		((1 << 22))			/*Tx FIFO Overflow Interrupt					*/
-#define IMR_TimeOut1	((1 << 21))			/*Time Out Interrupt 1							*/
-#define IMR_BcnInt		((1 << 20))			/*Beacon Time out Interrupt						*/
-#define IMR_ATIMInt		((1 << 19))			/*ATIM Time Out Interrupt						*/
-#define IMR_TBDER		((1 << 18))			/*Tx Beacon Descriptor Error Interrupt			*/
-#define IMR_TBDOK		((1 << 17))			/*Tx Beacon Descriptor OK Interrupt				*/
-#define IMR_THPDER		((1 << 16))			/*Tx High Priority Descriptor Error Interrupt	*/
-#define IMR_THPDOK		((1 << 15))			/*Tx High Priority Descriptor OK Interrupt		*/
-#define IMR_TVODER		((1 << 14))			/*Tx AC_VO Descriptor Error Interrupt			*/
-#define IMR_TVODOK		((1 << 13))			/*Tx AC_VO Descriptor OK Interrupt				*/
-#define IMR_FOVW		((1 << 12))			/*Rx FIFO Overflow Interrupt					*/
-#define IMR_RDU			((1 << 11))			/*Rx Descriptor Unavailable Interrupt			*/
-#define IMR_TVIDER		((1 << 10))			/*Tx AC_VI Descriptor Error Interrupt			*/
-#define IMR_TVIDOK		((1 << 9))			/*Tx AC_VI Descriptor OK Interrupt				*/
-#define IMR_RER			((1 << 8))			/*Rx Error Interrupt							*/
-#define IMR_ROK			((1 << 7))			/*Receive OK Interrupt							*/
-#define IMR_TBEDER		((1 << 6))			/*Tx AC_BE Descriptor Error Interrupt			*/
-#define IMR_TBEDOK		((1 << 5))			/*Tx AC_BE Descriptor OK Interrupt				*/
-#define IMR_TBKDER		((1 << 4))			/*Tx AC_BK Descriptor Error Interrupt			*/
-#define IMR_TBKDOK		((1 << 3))			/*Tx AC_BK Descriptor OK Interrupt				*/
-#define IMR_RQoSOK		((1 << 2))			/*Rx QoS OK Interrupt							*/
-#define IMR_TimeOut2	((1 << 1))			/*Time Out Interrupt 2							*/
-#define IMR_TimeOut3	((1 << 0))			/*Time Out Interrupt 3							*/
-#define IMR_TMGDOK      ((1 << 30))
-#define ISR_Dot11hInt	((1 << 25))			/*802.11h Measurement Interrupt					*/
-#define ISR_BcnDmaInt	((1 << 24))			/*Beacon DMA Interrupt	*/ /*What differenct between BcnDmaInt and BcnInt???	*/
-#define ISR_WakeInt		((1 << 23))			/*Wake Up Interrupt								*/
-#define ISR_TXFOVW		((1 << 22))			/*Tx FIFO Overflow Interrupt					*/
-#define ISR_TimeOut1	((1 << 21))			/*Time Out Interrupt 1							*/
-#define ISR_BcnInt		((1 << 20))			/*Beacon Time out Interrupt						*/
-#define ISR_ATIMInt		((1 << 19))			/*ATIM Time Out Interrupt						*/
-#define ISR_TBDER		((1 << 18))			/*Tx Beacon Descriptor Error Interrupt			*/
-#define ISR_TBDOK		((1 << 17))			/*Tx Beacon Descriptor OK Interrupt				*/
-#define ISR_THPDER		((1 << 16))			/*Tx High Priority Descriptor Error Interrupt	*/
-#define ISR_THPDOK		((1 << 15))			/*Tx High Priority Descriptor OK Interrupt		*/
-#define ISR_TVODER		((1 << 14))			/*Tx AC_VO Descriptor Error Interrupt			*/
-#define ISR_TVODOK		((1 << 13))			/*Tx AC_VO Descriptor OK Interrupt				*/
-#define ISR_FOVW		((1 << 12))			/*Rx FIFO Overflow Interrupt					*/
-#define ISR_RDU			((1 << 11))			/*Rx Descriptor Unavailable Interrupt			*/
-#define ISR_TVIDER		((1 << 10))			/*Tx AC_VI Descriptor Error Interrupt			*/
-#define ISR_TVIDOK		((1 << 9))			/*Tx AC_VI Descriptor OK Interrupt				*/
-#define ISR_RER			((1 << 8))			/*Rx Error Interrupt							*/
-#define ISR_ROK			((1 << 7))			/*Receive OK Interrupt							*/
-#define ISR_TBEDER		((1 << 6))			/*Tx AC_BE Descriptor Error Interrupt			*/
-#define ISR_TBEDOK		((1 << 5))			/*Tx AC_BE Descriptor OK Interrupt				*/
-#define ISR_TBKDER		((1 << 4))			/*Tx AC_BK Descriptor Error Interrupt			*/
-#define ISR_TBKDOK		((1 << 3))			/*Tx AC_BK Descriptor OK Interrupt				*/
-#define ISR_RQoSOK		((1 << 2))			/*Rx QoS OK Interrupt							*/
-#define ISR_TimeOut2	((1 << 1))			/*Time Out Interrupt 2							*/
-#define ISR_TimeOut3	((1 << 0))			/*Time Out Interrupt 3							*/
-
-/* these definition is used for Tx/Rx test temporarily */
-#define ISR_TLPDER  ISR_TVIDER
-#define ISR_TLPDOK  ISR_TVIDOK
-#define ISR_TNPDER  ISR_TVODER
-#define ISR_TNPDOK  ISR_TVODOK
-#define ISR_TimeOut ISR_TimeOut1
-#define ISR_RXFOVW ISR_FOVW
-
-
-#define HW_VERID_R8180_F 3
-#define HW_VERID_R8180_ABCD 2
-#define HW_VERID_R8185_ABC 4
-#define HW_VERID_R8185_D 5
-#define HW_VERID_R8185B_B 6
-
-#define TCR_CWMIN   ((1 << 31))
-#define TCR_SWSEQ   ((1 << 30))
-#define TCR_HWVERID_MASK ((1 << 27)|(1 << 26)|(1 << 25))
-#define TCR_HWVERID_SHIFT 25
-#define TCR_SAT     ((1 << 24))
-#define TCR_PLCP_LEN TCR_SAT /* rtl8180 */
-#define TCR_MXDMA_MASK   ((1 << 23)|(1 << 22)|(1 << 21))
-#define TCR_MXDMA_1024 6
-#define TCR_MXDMA_2048 7
-#define TCR_MXDMA_SHIFT  21
-#define TCR_DISCW   ((1 << 20))
-#define TCR_ICV     ((1 << 19))
-#define TCR_LBK     ((1 << 18)|(1 << 17))
-#define TCR_LBK1    ((1 << 18))
-#define TCR_LBK0    ((1 << 17))
-#define TCR_CRC     ((1 << 16))
-#define TCR_DPRETRY_MASK   ((1 << 15)|(1 << 14)|(1 << 13)|(1 << 12)|(1 << 11)|(1 << 10)|(1 << 9)|(1 << 8))
-#define TCR_RTSRETRY_MASK   ((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)|(1 << 6)|(1 << 7))
-#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 /* rtl8185 */
-
-#define RCR_ONLYERLPKT ((1 << 31))
-#define RCR_CS_SHIFT   29
-#define RCR_CS_MASK    ((1 << 30) | (1 << 29))
-#define RCR_ENMARP     ((1 << 28))
-#define RCR_CBSSID     ((1 << 23))
-#define RCR_APWRMGT    ((1 << 22))
-#define RCR_ADD3       ((1 << 21))
-#define RCR_AMF        ((1 << 20))
-#define RCR_ACF        ((1 << 19))
-#define RCR_ADF        ((1 << 18))
-#define RCR_RXFTH      ((1 << 15)|(1 << 14)|(1 << 13))
-#define RCR_RXFTH2     ((1 << 15))
-#define RCR_RXFTH1     ((1 << 14))
-#define RCR_RXFTH0     ((1 << 13))
-#define RCR_AICV       ((1 << 12))
-#define RCR_MXDMA      ((1 << 10)|(1 << 9)|(1 << 8))
-#define RCR_MXDMA2     ((1 << 10))
-#define RCR_MXDMA1     ((1 << 9))
-#define RCR_MXDMA0     ((1 << 8))
-#define RCR_9356SEL    ((1 << 6))
-#define RCR_ACRC32     ((1 << 5))
-#define RCR_AB         ((1 << 3))
-#define RCR_AM         ((1 << 2))
-#define RCR_APM        ((1 << 1))
-#define RCR_AAP        ((1 << 0))
-
-#define CR9346_EEM     ((1 << 7)|(1 << 6))
-#define CR9346_EEM1    ((1 << 7))
-#define CR9346_EEM0    ((1 << 6))
-#define CR9346_EECS    ((1 << 3))
-#define CR9346_EESK    ((1 << 2))
-#define CR9346_EED1    ((1 << 1))
-#define CR9346_EED0    ((1 << 0))
-
-#define CONFIG3_PARM_En    ((1 << 6))
-#define CONFIG3_FuncRegEn  ((1 << 1))
-
-#define CONFIG4_PWRMGT     ((1 << 5))
-
-#define MSR_LINK_MASK      ((1 << 2)|(1 << 3))
-#define MSR_LINK_MANAGED   2
-#define MSR_LINK_NONE      0
-#define MSR_LINK_SHIFT     2
-#define MSR_LINK_ADHOC     1
-#define MSR_LINK_MASTER    3
-
-#define BcnItv_BcnItv      (0x01FF)
-
-#define AtimWnd_AtimWnd    (0x01FF)
-
-#define BintrItv_BintrItv  (0x01FF)
-
-#define FEMR_INTR    ((1 << 15))
-#define FEMR_WKUP    ((1 << 14))
-#define FEMR_GWAKE   ((1 << 4))
-
-#define FFER_INTR    ((1 << 15))
-#define FFER_GWAKE   ((1 << 4))
-
-/* Three wire mode.					*/
-#define SW_THREE_WIRE			0
-#define HW_THREE_WIRE			2
-/* RTL8187S by amy					*/
-#define HW_THREE_WIRE_PI		5
-#define HW_THREE_WIRE_SI		6
-/* by amy							*/
-#define TCR_LRL_OFFSET		0
-#define TCR_SRL_OFFSET		8
-#define TCR_MXDMA_OFFSET	21
-#define TCR_DISReqQsize_OFFSET		28
-#define TCR_DurProcMode_OFFSET		30
-
-#define RCR_MXDMA_OFFSET				8
-#define RCR_FIFO_OFFSET					13
-
-#define AckTimeOutReg	0x79		/* ACK timeout register, in unit of 4 us. */
-
-#define RFTiming			0x8C
-
-#define TPPollStop		0x93
-
-#define TXAGC_CTL		0x9C			/*< RJ_TODO_8185B> TX_AGC_CONTROL (0x9C seems be removed at 8185B, see p37). */
-#define CCK_TXAGC		0x9D
-#define OFDM_TXAGC		0x9E
-#define ANTSEL			0x9F
-
-#define ACM_CONTROL             0x00BF      /* ACM Control Registe */
-
-#define	IntMig			0xE2			/* Interrupt Migration (0xE2 ~ 0xE3)	*/
-
-#define TID_AC_MAP		0xE8			/* TID to AC Mapping Register			*/
-
-#define ANAPARAM3		0xEE			/* <RJ_TODO_8185B> How to use it?		*/
-
-#define AC_VO_PARAM		0xF0			/* AC_VO Parameters Record				*/
-#define AC_VI_PARAM		0xF4			/* AC_VI Parameters Record				*/
-#define AC_BE_PARAM		0xF8			/* AC_BE Parameters Record				*/
-#define AC_BK_PARAM		0xFC			/* AC_BK Parameters Record				*/
-
-#define GPIOCtrl			0x16B			/*GPIO Control Register.			*/
-#define ARFR			0x1E0	/* Auto Rate Fallback Register (0x1e0 ~ 0x1e2)	*/
-
-#define RFSW_CTRL			0x272	/* 0x272-0x273.								*/
-#define SW_3W_DB0			0x274	/* Software 3-wire data buffer bit 31~0.		*/
-#define SW_3W_DB1			0x278	/* Software 3-wire data buffer bit 63~32.	*/
-#define SW_3W_CMD0			0x27C	/* Software 3-wire Control/Status Register.	*/
-#define SW_3W_CMD1			0x27D	/* Software 3-wire Control/Status Register.	*/
-
-#define PI_DATA_READ		0X360	/* 0x360 - 0x361  Parallel Interface Data Register.	*/
-#define SI_DATA_READ		0x362	/* 0x362 - 0x363  Serial Interface Data Register.	*/
-
-/*
-----------------------------------------------------------------------------
-		8185B TPPollStop bits					(offset 0x93, 1 byte)
-----------------------------------------------------------------------------
-*/
-#define TPPOLLSTOP_BQ			(0x01 << 7)
-#define TPPOLLSTOP_AC_VIQ		(0x01 << 4)
-
-#define MSR_LINK_ENEDCA	   (1<<4)
-
-/*
-----------------------------------------------------------------------------
-		8187B AC_XX_PARAM bits
-----------------------------------------------------------------------------
-*/
-#define AC_PARAM_TXOP_LIMIT_OFFSET		16
-#define AC_PARAM_ECW_MAX_OFFSET			12
-#define AC_PARAM_ECW_MIN_OFFSET			8
-#define AC_PARAM_AIFS_OFFSET			0
-
-/*
-----------------------------------------------------------------------------
-		8187B ACM_CONTROL bits					(Offset 0xBF, 1 Byte)
-----------------------------------------------------------------------------
-*/
-#define VOQ_ACM_EN				(0x01 << 7)	/*BIT7	*/
-#define VIQ_ACM_EN				(0x01 << 6)	/*BIT6	*/
-#define BEQ_ACM_EN				(0x01 << 5)	/*BIT5	*/
-#define ACM_HW_EN				(0x01 << 4)	/*BIT4	*/
-#define VOQ_ACM_CTL				(0x01 << 2)	/*BIT2	*/	/* Set to 1 when AC_VO used time reaches or exceeds the admitted time	*/
-#define VIQ_ACM_CTL				(0x01 << 1)	/*BIT1	*/	/* Set to 1 when AC_VI used time reaches or exceeds the admitted time	*/
-#define BEQ_ACM_CTL				(0x01 << 0)	/*BIT0	*/	/* Set to 1 when AC_BE used time reaches or exceeds the admitted time	*/
-
-
-/*
-----------------------------------------------------------------------------
-		8185B SW_3W_CMD bits					(Offset 0x27C-0x27D, 16bit)
-----------------------------------------------------------------------------
-*/
-#define SW_3W_CMD0_HOLD		((1 << 7))
-#define SW_3W_CMD1_RE		((1 << 0)) /* BIT8		*/
-#define SW_3W_CMD1_WE		((1 << 1)) /* BIT9		*/
-#define SW_3W_CMD1_DONE		((1 << 2)) /* BIT10		*/
-
-#define BB_HOST_BANG_RW		(1 << 3)
-
-/*
-----------------------------------------------------------------------------
-		8185B RATE_FALLBACK_CTL bits			(Offset 0xBE, 8bit)
-----------------------------------------------------------------------------
-*/
-#define RATE_FALLBACK_CTL_ENABLE				((1 << 7))
-#define RATE_FALLBACK_CTL_ENABLE_RTSCTS		((1 << 6))
-/* Auto rate fallback per 2^n retry. */
-#define RATE_FALLBACK_CTL_AUTO_STEP0	0x00
-#define RATE_FALLBACK_CTL_AUTO_STEP1	0x01
-#define RATE_FALLBACK_CTL_AUTO_STEP2	0x02
-#define RATE_FALLBACK_CTL_AUTO_STEP3	0x03
-
-
-#define RTL8225z2_ANAPARAM_OFF	0x55480658
-#define RTL8225z2_ANAPARAM2_OFF	0x72003f70
-/* by amy for power save		*/
-#define RF_CHANGE_BY_HW BIT30
-#define RF_CHANGE_BY_PS BIT29
-#define RF_CHANGE_BY_IPS BIT28
-/* by amy for power save		*/
-/* by amy for antenna			*/
-#define EEPROM_SW_REVD_OFFSET 0x3f
-
-/*  BIT[8-9] is for SW Antenna Diversity.
- *  Only the value EEPROM_SW_AD_ENABLE means enable, other values are disable.
- */
-#define EEPROM_SW_AD_MASK			0x0300
-#define EEPROM_SW_AD_ENABLE			0x0100
-
-/* BIT[10-11] determine if Antenna 1 is the Default Antenna.
- * Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
- */
-#define EEPROM_DEF_ANT_MASK			0x0C00
-#define EEPROM_DEF_ANT_1			0x0400
-/*by amy for antenna																				*/
-/* {by amy 080312																					*/
-/* 0x7C, 0x7D Crystal calibration and Tx Power tracking mechanism. Added by Roger. 2007.12.10.		*/
-#define EEPROM_RSV						0x7C
-#define EEPROM_XTAL_CAL_XOUT_MASK	0x0F	/* 0x7C[3:0], Crystal calibration for Xout.				*/
-#define EEPROM_XTAL_CAL_XIN_MASK		0xF0	/* 0x7C[7:4], Crystal calibration for Xin.			*/
-#define EEPROM_THERMAL_METER_MASK	0x0F00	/* 0x7D[3:0], Thermal meter reference level.			*/
-#define EEPROM_XTAL_CAL_ENABLE		0x1000	/* 0x7D[4], Crystal calibration enabled/disabled BIT.	*/
-#define EEPROM_THERMAL_METER_ENABLE	0x2000	/* 0x7D[5], Thermal meter enabled/disabled BIT.			*/
-#define EN_LPF_CAL			0x238	/* Enable LPF Calibration.										*/
-#define PWR_METER_EN		BIT1
-/* <RJ_TODO_8185B> where are false alarm counters in 8185B? */
-#define CCK_FALSE_ALARM		0xD0
-/* by amy 080312} */
-
-/* YJ,add for Country IE, 080630 */
-#define EEPROM_COUNTRY_CODE  0x2E
-/* YJ,add,080630,end */
-
-#endif
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h
deleted file mode 100644
index 7df7392..0000000
--- a/drivers/staging/rtl8187se/r8180_rtl8225.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This is part of the rtl8180-sa2400 driver released under the GPL (See file
- * COPYING for details).
- *
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * This files contains programming code for the rtl8225 radio frontend.
- *
- * *Many* thanks to Realtek Corp. for their great support!
- */
-
-#include "r8180.h"
-
-#define RTL8225_ANAPARAM_ON  0xa0000b59
-#define RTL8225_ANAPARAM_OFF 0xa00beb59
-#define RTL8225_ANAPARAM2_OFF 0x840dec11
-#define RTL8225_ANAPARAM2_ON  0x860dec11
-#define RTL8225_ANAPARAM_SLEEP 0xa00bab59
-#define RTL8225_ANAPARAM2_SLEEP 0x840dec11
-
-void rtl8225z2_rf_init(struct net_device *dev);
-void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
-void rtl8225z2_rf_close(struct net_device *dev);
-
-void RF_WriteReg(struct net_device *dev, u8 offset, u16 data);
-u16 RF_ReadReg(struct net_device *dev, u8 offset);
-
-void rtl8180_set_mode(struct net_device *dev, int mode);
-void rtl8180_set_mode(struct net_device *dev, int mode);
-bool SetZebraRFPowerState8185(struct net_device *dev,
-			      enum rt_rf_power_state eRFPowerState);
-void rtl8225z4_rf_sleep(struct net_device *dev);
-void rtl8225z4_rf_wakeup(struct net_device *dev);
-
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
deleted file mode 100644
index 47104fa..0000000
--- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * This is part of the rtl8180-sa2400 driver
- * released under the GPL (See file COPYING for details).
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * This files contains programming code for the rtl8225
- * radio frontend.
- *
- * *Many* thanks to Realtek Corp. for their great support!
- */
-
-#include "r8180_hw.h"
-#include "r8180_rtl8225.h"
-#include "r8180_93cx6.h"
-
-#include "ieee80211/dot11d.h"
-
-static void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
-{
-	int i;
-	u16 out, select;
-	u8 bit;
-	u32 bangdata = (data << 4) | (adr & 0xf);
-
-	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
-
-	write_nic_word(dev, RFPinsEnable,
-		(read_nic_word(dev, RFPinsEnable) | 0x7));
-
-	select = read_nic_word(dev, RFPinsSelect);
-
-	write_nic_word(dev, RFPinsSelect, select | 0x7 |
-		       SW_CONTROL_GPIO);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
-	force_pci_posting(dev);
-	udelay(2);
-
-	write_nic_word(dev, RFPinsOutput, out);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	for (i = 15; i >= 0; i--) {
-		bit = (bangdata & (1 << i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out);
-
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
-		i--;
-		bit = (bangdata & (1 << i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
-		write_nic_word(dev, RFPinsOutput, bit | out);
-
-	}
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
-	write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
-
-	rtl8185_rf_pins_enable(dev);
-}
-
-static const u8 rtl8225_agc[] = {
-	0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
-	0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
-	0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
-	0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
-	0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
-	0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
-	0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
-	0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
-	0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
-	0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
-	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
-	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-};
-
-static const u32 rtl8225_chan[] = {
-	0,
-	0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
-	0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A,
-};
-
-static const u8 rtl8225z2_gain_bg[] = {
-	0x23, 0x15, 0xa5, /* -82-1dBm */
-	0x23, 0x15, 0xb5, /* -82-2dBm */
-	0x23, 0x15, 0xc5, /* -82-3dBm */
-	0x33, 0x15, 0xc5, /* -78dBm */
-	0x43, 0x15, 0xc5, /* -74dBm */
-	0x53, 0x15, 0xc5, /* -70dBm */
-	0x63, 0x15, 0xc5, /* -66dBm */
-};
-
-static const u8 rtl8225z2_gain_a[] = {
-	0x13, 0x27, 0x5a, /* -82dBm */
-	0x23, 0x23, 0x58, /* -82dBm */
-	0x33, 0x1f, 0x56, /* -82dBm */
-	0x43, 0x1b, 0x54, /* -78dBm */
-	0x53, 0x17, 0x51, /* -74dBm */
-	0x63, 0x24, 0x4f, /* -70dBm */
-	0x73, 0x0f, 0x4c, /* -66dBm */
-};
-
-static const u16 rtl8225z2_rxgain[] = {
-	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
-	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
-	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
-	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
-	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
-	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
-	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
-	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
-	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
-	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
-	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
-	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb
-
-};
-
-static void rtl8225z2_set_gain(struct net_device *dev, short gain)
-{
-	const u8 *rtl8225_gain;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 mode = priv->ieee80211->mode;
-
-	if (mode == IEEE_B || mode == IEEE_G)
-		rtl8225_gain = rtl8225z2_gain_bg;
-	else
-		rtl8225_gain = rtl8225z2_gain_a;
-
-	write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
-	write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
-	write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
-	write_phy_ofdm(dev, 0x21, 0x37);
-}
-
-static u32 read_rtl8225(struct net_device *dev, u8 adr)
-{
-	u32 data2Write = ((u32)(adr & 0x1f)) << 27;
-	u32 dataRead;
-	u32 mask;
-	u16 oval, oval2, oval3, tmp;
-	int i;
-	short bit, rw;
-	u8 wLength = 6;
-	u8 rLength = 12;
-	u8 low2high = 0;
-
-	oval = read_nic_word(dev, RFPinsOutput);
-	oval2 = read_nic_word(dev, RFPinsEnable);
-	oval3 = read_nic_word(dev, RFPinsSelect);
-
-	write_nic_word(dev, RFPinsEnable, (oval2|0xf));
-	write_nic_word(dev, RFPinsSelect, (oval3|0xf));
-
-	dataRead = 0;
-
-	oval &= ~0xf;
-
-	write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN);
-	udelay(4);
-
-	write_nic_word(dev, RFPinsOutput, oval);
-	udelay(5);
-
-	rw = 0;
-
-	mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
-
-	for (i = 0; i < wLength/2; i++) {
-		bit = ((data2Write&mask) != 0) ? 1 : 0;
-		write_nic_word(dev, RFPinsOutput, bit | oval | rw);
-		udelay(1);
-
-		write_nic_word(dev, RFPinsOutput,
-				bit | oval | BB_HOST_BANG_CLK | rw);
-		udelay(2);
-		write_nic_word(dev, RFPinsOutput,
-				bit | oval | BB_HOST_BANG_CLK | rw);
-		udelay(2);
-
-		mask = (low2high) ? (mask<<1) : (mask>>1);
-
-		if (i == 2) {
-			rw = BB_HOST_BANG_RW;
-			write_nic_word(dev, RFPinsOutput,
-					bit | oval | BB_HOST_BANG_CLK | rw);
-			udelay(2);
-			write_nic_word(dev, RFPinsOutput, bit | oval | rw);
-			udelay(2);
-			break;
-		}
-
-		bit = ((data2Write&mask) != 0) ? 1 : 0;
-
-		write_nic_word(dev, RFPinsOutput,
-				oval | bit | rw | BB_HOST_BANG_CLK);
-		udelay(2);
-		write_nic_word(dev, RFPinsOutput,
-				oval | bit | rw | BB_HOST_BANG_CLK);
-		udelay(2);
-
-		write_nic_word(dev, RFPinsOutput, oval | bit | rw);
-		udelay(1);
-
-		mask = (low2high) ? (mask<<1) : (mask>>1);
-	}
-
-	write_nic_word(dev, RFPinsOutput, rw|oval);
-	udelay(2);
-	mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
-
-	/*
-	 * We must set data pin to HW controlled, otherwise RF can't driver it
-	 * and value RF register won't be able to read back properly.
-	 */
-	write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01)));
-
-	for (i = 0; i < rLength; i++) {
-		write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
-
-		write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
-		udelay(2);
-		write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
-		udelay(2);
-		write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
-		udelay(2);
-		tmp = read_nic_word(dev, RFPinsInput);
-
-		dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
-
-		write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
-
-		mask = (low2high) ? (mask<<1) : (mask>>1);
-	}
-
-	write_nic_word(dev, RFPinsOutput,
-			BB_HOST_BANG_EN | BB_HOST_BANG_RW | oval);
-	udelay(2);
-
-	write_nic_word(dev, RFPinsEnable, oval2);
-	write_nic_word(dev, RFPinsSelect, oval3); /* Set To SW Switch */
-	write_nic_word(dev, RFPinsOutput, 0x3a0);
-
-	return dataRead;
-}
-
-void rtl8225z2_rf_close(struct net_device *dev)
-{
-	RF_WriteReg(dev, 0x4, 0x1f);
-
-	force_pci_posting(dev);
-	mdelay(1);
-
-	rtl8180_set_anaparam(dev, RTL8225z2_ANAPARAM_OFF);
-	rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF);
-}
-
-/*
- * Map dBm into Tx power index according to current HW model, for example,
- * RF and PA, and current wireless mode.
- */
-static s8 DbmToTxPwrIdx(struct r8180_priv *priv,
-			enum wireless_mode mode, s32 PowerInDbm)
-{
-	bool bUseDefault = true;
-	s8 TxPwrIdx = 0;
-
-	/*
-	 * OFDM Power in dBm = Index * 0.5 + 0
-	 * CCK Power in dBm = Index * 0.25 + 13
-	 */
-	s32 tmp = 0;
-
-	if (mode == WIRELESS_MODE_G) {
-		bUseDefault = false;
-		tmp = (2 * PowerInDbm);
-
-		if (tmp < 0)
-			TxPwrIdx = 0;
-		else if (tmp > 40) /* 40 means 20 dBm. */
-			TxPwrIdx = 40;
-		else
-			TxPwrIdx = (s8)tmp;
-	} else if (mode == WIRELESS_MODE_B) {
-		bUseDefault = false;
-		tmp = (4 * PowerInDbm) - 52;
-
-		if (tmp < 0)
-			TxPwrIdx = 0;
-		else if (tmp > 28) /* 28 means 20 dBm. */
-			TxPwrIdx = 28;
-		else
-			TxPwrIdx = (s8)tmp;
-	}
-
-	/*
-	 * TRUE if we want to use a default implementation.
-	 * We shall set it to FALSE when we have exact translation formula
-	 * for target IC. 070622, by rcnjko.
-	 */
-	if (bUseDefault) {
-		if (PowerInDbm < 0)
-			TxPwrIdx = 0;
-		else if (PowerInDbm > 35)
-			TxPwrIdx = 35;
-		else
-			TxPwrIdx = (u8)PowerInDbm;
-	}
-
-	return TxPwrIdx;
-}
-
-void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 max_cck_power_level;
-	u8 max_ofdm_power_level;
-	u8 min_ofdm_power_level;
-	char cck_power_level = (char)(0xff & priv->chtxpwr[ch]);
-	char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]);
-
-	if (IS_DOT11D_ENABLE(priv->ieee80211) &&
-	    IS_DOT11D_STATE_DONE(priv->ieee80211)) {
-		u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
-		u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B,
-							MaxTxPwrInDbm);
-		u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G,
-							MaxTxPwrInDbm);
-
-		if (cck_power_level > CckMaxPwrIdx)
-			cck_power_level = CckMaxPwrIdx;
-		if (ofdm_power_level > OfdmMaxPwrIdx)
-			ofdm_power_level = OfdmMaxPwrIdx;
-	}
-
-	max_cck_power_level = 15;
-	max_ofdm_power_level = 25;
-	min_ofdm_power_level = 10;
-
-	if (cck_power_level > 35)
-		cck_power_level = 35;
-
-	write_nic_byte(dev, CCK_TXAGC, cck_power_level);
-	force_pci_posting(dev);
-	mdelay(1);
-
-	if (ofdm_power_level > 35)
-		ofdm_power_level = 35;
-
-	if (priv->up == 0) {
-		write_phy_ofdm(dev, 2, 0x42);
-		write_phy_ofdm(dev, 5, 0x00);
-		write_phy_ofdm(dev, 6, 0x40);
-		write_phy_ofdm(dev, 7, 0x00);
-		write_phy_ofdm(dev, 8, 0x40);
-	}
-
-	write_nic_byte(dev, OFDM_TXAGC, ofdm_power_level);
-
-	if (ofdm_power_level <= 11) {
-		write_phy_ofdm(dev, 0x07, 0x5c);
-		write_phy_ofdm(dev, 0x09, 0x5c);
-	}
-
-	if (ofdm_power_level <= 17) {
-		write_phy_ofdm(dev, 0x07, 0x54);
-		write_phy_ofdm(dev, 0x09, 0x54);
-	} else {
-		write_phy_ofdm(dev, 0x07, 0x50);
-		write_phy_ofdm(dev, 0x09, 0x50);
-	}
-
-	force_pci_posting(dev);
-	mdelay(1);
-}
-
-void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
-{
-	rtl8225z2_SetTXPowerLevel(dev, ch);
-
-	RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
-
-	if ((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
-		RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
-
-	mdelay(1);
-
-	force_pci_posting(dev);
-	mdelay(10);
-}
-
-static void rtl8225_host_pci_init(struct net_device *dev)
-{
-	write_nic_word(dev, RFPinsOutput, 0x480);
-
-	rtl8185_rf_pins_enable(dev);
-
-	write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO);
-
-	write_nic_byte(dev, GP_ENABLE, 0);
-
-	force_pci_posting(dev);
-	mdelay(200);
-
-	/* bit 6 is for RF on/off detection */
-	write_nic_word(dev, GP_ENABLE, 0xff & (~(1 << 6)));
-}
-
-void rtl8225z2_rf_init(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int i;
-	short channel = 1;
-	u16 brsr;
-	u32 data;
-
-	priv->chan = channel;
-
-	rtl8225_host_pci_init(dev);
-
-	write_nic_dword(dev, RF_TIMING, 0x000a8008);
-
-	brsr = read_nic_word(dev, BRSR);
-
-	write_nic_word(dev, BRSR, 0xffff);
-
-	write_nic_dword(dev, RF_PARA, 0x100044);
-
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	write_nic_byte(dev, CONFIG3, 0x44);
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
-	rtl8185_rf_pins_enable(dev);
-
-	write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
-	write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
-	write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
-	write_rtl8225(dev, 0x3, 0x441); mdelay(1);
-	write_rtl8225(dev, 0x4, 0x8c3); mdelay(1);
-	write_rtl8225(dev, 0x5, 0xc72); mdelay(1);
-	write_rtl8225(dev, 0x6, 0xe6);  mdelay(1);
-	write_rtl8225(dev, 0x7, rtl8225_chan[channel]);  mdelay(1);
-	write_rtl8225(dev, 0x8, 0x3f);  mdelay(1);
-	write_rtl8225(dev, 0x9, 0x335); mdelay(1);
-	write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
-	write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
-	write_rtl8225(dev, 0xc, 0x850); mdelay(1);
-	write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
-	write_rtl8225(dev, 0xe, 0x2b);  mdelay(1);
-	write_rtl8225(dev, 0xf, 0x114);
-
-	mdelay(100);
-
-	write_rtl8225(dev, 0x0, 0x1b7);
-
-	for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
-		write_rtl8225(dev, 0x1, i + 1);
-		write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
-	}
-
-	write_rtl8225(dev, 0x3, 0x80);
-	write_rtl8225(dev, 0x5, 0x4);
-
-	write_rtl8225(dev, 0x0, 0xb7);
-
-	write_rtl8225(dev, 0x2, 0xc4d);
-
-	/* FIXME!! rtl8187 we have to check if calibrarion
-	 * is successful and eventually cal. again (repeat
-	 * the two write on reg 2)
-	 */
-	data = read_rtl8225(dev, 6);
-	if (!(data & 0x00000080)) {
-		write_rtl8225(dev, 0x02, 0x0c4d);
-		force_pci_posting(dev); mdelay(200);
-		write_rtl8225(dev, 0x02, 0x044d);
-		force_pci_posting(dev); mdelay(100);
-		data = read_rtl8225(dev, 6);
-		if (!(data & 0x00000080))
-			DMESGW("RF Calibration Failed!!!!\n");
-	}
-
-	mdelay(200);
-
-	write_rtl8225(dev, 0x0, 0x2bf);
-
-	for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
-		write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
-		mdelay(1);
-
-		/* enable writing AGC table */
-		write_phy_ofdm(dev, 0xa, i + 0x80);
-		mdelay(1);
-	}
-
-	force_pci_posting(dev);
-	mdelay(1);
-
-	write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
-	write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
-	write_phy_ofdm(dev, 0x02, 0x62); mdelay(1);
-	write_phy_ofdm(dev, 0x03, 0x00); mdelay(1);
-	write_phy_ofdm(dev, 0x04, 0x00); mdelay(1);
-	write_phy_ofdm(dev, 0x05, 0x00); mdelay(1);
-	write_phy_ofdm(dev, 0x06, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x07, 0x00); mdelay(1);
-	write_phy_ofdm(dev, 0x08, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1);
-	write_phy_ofdm(dev, 0x0a, 0x08); mdelay(1);
-	write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1);
-	write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1);
-	write_phy_ofdm(dev, 0x0d, 0x43);
-	write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1);
-	write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1);
-	write_phy_ofdm(dev, 0x10, 0x84); mdelay(1);
-	write_phy_ofdm(dev, 0x11, 0x07); mdelay(1);
-	write_phy_ofdm(dev, 0x12, 0x20); mdelay(1);
-	write_phy_ofdm(dev, 0x13, 0x20); mdelay(1);
-	write_phy_ofdm(dev, 0x14, 0x00); mdelay(1);
-	write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x16, 0x00); mdelay(1);
-	write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
-	write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
-	write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
-	write_phy_ofdm(dev, 0x1b, 0x15); mdelay(1);
-	write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1);
-	write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
-	write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1);
-	write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
-	write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1);
-	write_phy_ofdm(dev, 0x21, 0x17); mdelay(1);
-	write_phy_ofdm(dev, 0x22, 0x16); mdelay(1);
-	write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME maybe not needed */
-	write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
-	write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
-	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
-	write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
-
-	rtl8225z2_set_gain(dev, 4);
-
-	write_phy_cck(dev, 0x0, 0x98); mdelay(1);
-	write_phy_cck(dev, 0x3, 0x20); mdelay(1);
-	write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
-	write_phy_cck(dev, 0x5, 0x12); mdelay(1);
-	write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
-	write_phy_cck(dev, 0x7, 0x78); mdelay(1);
-	write_phy_cck(dev, 0x8, 0x2e); mdelay(1);
-	write_phy_cck(dev, 0x10, 0x93); mdelay(1);
-	write_phy_cck(dev, 0x11, 0x88); mdelay(1);
-	write_phy_cck(dev, 0x12, 0x47); mdelay(1);
-	write_phy_cck(dev, 0x13, 0xd0);
-	write_phy_cck(dev, 0x19, 0x00);
-	write_phy_cck(dev, 0x1a, 0xa0);
-	write_phy_cck(dev, 0x1b, 0x08);
-	write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
-	write_phy_cck(dev, 0x41, 0x8d); mdelay(1);
-	write_phy_cck(dev, 0x42, 0x15); mdelay(1);
-	write_phy_cck(dev, 0x43, 0x18); mdelay(1);
-	write_phy_cck(dev, 0x44, 0x36); mdelay(1);
-	write_phy_cck(dev, 0x45, 0x35); mdelay(1);
-	write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
-	write_phy_cck(dev, 0x47, 0x25); mdelay(1);
-	write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
-	write_phy_cck(dev, 0x49, 0x12); mdelay(1);
-	write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
-	write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
-	write_phy_cck(dev, 0x4c, 0x05); mdelay(1);
-
-	write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
-
-	rtl8225z2_SetTXPowerLevel(dev, channel);
-
-	/* RX antenna default to A */
-	write_phy_cck(dev, 0x11, 0x9b); mdelay(1);		/* B: 0xDB */
-	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);		/* B: 0x10 */
-
-	rtl8185_tx_antenna(dev, 0x03);				/* B: 0x00 */
-
-	/* switch to high-speed 3-wire
-	 * last digit. 2 for both cck and ofdm
-	 */
-	write_nic_dword(dev, 0x94, 0x15c00002);
-	rtl8185_rf_pins_enable(dev);
-
-	rtl8225z2_rf_set_chan(dev, priv->chan);
-}
-
-#define MAX_DOZE_WAITING_TIMES_85B		20
-#define MAX_POLLING_24F_TIMES_87SE		10
-#define LPS_MAX_SLEEP_WAITING_TIMES_87SE	5
-
-bool SetZebraRFPowerState8185(struct net_device *dev,
-			      enum rt_rf_power_state eRFPowerState)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8			btCR9346, btConfig3;
-	bool bActionAllowed = true, bTurnOffBB = true;
-	u8			u1bTmp;
-	int			i;
-	bool		bResult = true;
-	u8			QueueID;
-
-	if (priv->SetRFPowerStateInProgress == true)
-		return false;
-
-	priv->SetRFPowerStateInProgress = true;
-
-	btCR9346 = read_nic_byte(dev, CR9346);
-	write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
-
-	btConfig3 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En));
-
-	switch (eRFPowerState) {
-	case RF_ON:
-		write_nic_word(dev, 0x37C, 0x00EC);
-
-		/* turn on AFE */
-		write_nic_byte(dev, 0x54, 0x00);
-		write_nic_byte(dev, 0x62, 0x00);
-
-		/* turn on RF */
-		RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
-		RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
-		/* turn on RF again */
-		RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
-		RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
-		/* turn on BB */
-		write_phy_ofdm(dev, 0x10, 0x40);
-		write_phy_ofdm(dev, 0x12, 0x40);
-
-		/* Avoid power down at init time. */
-		write_nic_byte(dev, CONFIG4, priv->RFProgType);
-
-		u1bTmp = read_nic_byte(dev, 0x24E);
-		write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
-		break;
-	case RF_SLEEP:
-		for (QueueID = 0, i = 0; QueueID < 6;) {
-			if (get_curr_tx_free_desc(dev, QueueID) ==
-							priv->txringcount) {
-				QueueID++;
-				continue;
-			} else {
-				priv->TxPollingTimes++;
-				if (priv->TxPollingTimes >=
-					LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
-					bActionAllowed = false;
-					break;
-				} else
-					udelay(10);
-			}
-		}
-
-		if (bActionAllowed) {
-			/* turn off BB RXIQ matrix to cut off rx signal */
-			write_phy_ofdm(dev, 0x10, 0x00);
-			write_phy_ofdm(dev, 0x12, 0x00);
-
-			/* turn off RF */
-			RF_WriteReg(dev, 0x4, 0x0000);
-			RF_WriteReg(dev, 0x0, 0x0000);
-
-			/* turn off AFE except PLL */
-			write_nic_byte(dev, 0x62, 0xff);
-			write_nic_byte(dev, 0x54, 0xec);
-
-			mdelay(1);
-
-			{
-				int i = 0;
-				while (true) {
-					u8 tmp24F = read_nic_byte(dev, 0x24f);
-
-					if ((tmp24F == 0x01) ||
-							(tmp24F == 0x09)) {
-						bTurnOffBB = true;
-						break;
-					} else {
-						udelay(10);
-						i++;
-						priv->TxPollingTimes++;
-
-						if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
-							bTurnOffBB = false;
-							break;
-						} else
-							udelay(10);
-					}
-				}
-			}
-
-			if (bTurnOffBB) {
-				/* turn off BB */
-				u1bTmp = read_nic_byte(dev, 0x24E);
-				write_nic_byte(dev, 0x24E,
-						(u1bTmp | BIT5 | BIT6));
-
-				/* turn off AFE PLL */
-				write_nic_byte(dev, 0x54, 0xFC);
-				write_nic_word(dev, 0x37C, 0x00FC);
-			}
-		}
-		break;
-	case RF_OFF:
-		for (QueueID = 0, i = 0; QueueID < 6;) {
-			if (get_curr_tx_free_desc(dev, QueueID) ==
-					priv->txringcount) {
-				QueueID++;
-				continue;
-			} else {
-				udelay(10);
-				i++;
-			}
-
-			if (i >= MAX_DOZE_WAITING_TIMES_85B)
-				break;
-		}
-
-		/* turn off BB RXIQ matrix to cut off rx signal */
-		write_phy_ofdm(dev, 0x10, 0x00);
-		write_phy_ofdm(dev, 0x12, 0x00);
-
-		/* turn off RF */
-		RF_WriteReg(dev, 0x4, 0x0000);
-		RF_WriteReg(dev, 0x0, 0x0000);
-
-		/* turn off AFE except PLL */
-		write_nic_byte(dev, 0x62, 0xff);
-		write_nic_byte(dev, 0x54, 0xec);
-
-		mdelay(1);
-
-		{
-			int i = 0;
-
-			while (true) {
-				u8 tmp24F = read_nic_byte(dev, 0x24f);
-
-				if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
-					bTurnOffBB = true;
-					break;
-				} else {
-					bTurnOffBB = false;
-					udelay(10);
-					i++;
-				}
-
-				if (i > MAX_POLLING_24F_TIMES_87SE)
-					break;
-			}
-		}
-
-		if (bTurnOffBB) {
-			/* turn off BB */
-			u1bTmp = read_nic_byte(dev, 0x24E);
-			write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
-
-			/* turn off AFE PLL (80M) */
-			write_nic_byte(dev, 0x54, 0xFC);
-			write_nic_word(dev, 0x37C, 0x00FC);
-		}
-		break;
-	}
-
-	btConfig3 &= ~(CONFIG3_PARM_En);
-	write_nic_byte(dev, CONFIG3, btConfig3);
-
-	btCR9346 &= ~(0xC0);
-	write_nic_byte(dev, CR9346, btCR9346);
-
-	if (bResult && bActionAllowed)
-		priv->eRFPowerState = eRFPowerState;
-
-	priv->SetRFPowerStateInProgress = false;
-
-	return bResult && bActionAllowed;
-}
-
-void rtl8225z4_rf_sleep(struct net_device *dev)
-{
-	MgntActSet_RF_State(dev, RF_SLEEP, RF_CHANGE_BY_PS);
-}
-
-void rtl8225z4_rf_wakeup(struct net_device *dev)
-{
-	MgntActSet_RF_State(dev, RF_ON, RF_CHANGE_BY_PS);
-}
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
deleted file mode 100644
index b552491..0000000
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ /dev/null
@@ -1,1409 +0,0 @@
-/*
-	This file contains wireless extension handlers.
-
-	This is part of rtl8180 OpenSource driver.
-	Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part
-	of the official realtek driver.
-
-	Parts of this driver are based on the rtl8180 driver skeleton
-	from Patric Schenke & Andres Salomon.
-
-	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
-	We want to thanks the Authors of those projects and the Ndiswrapper
-	project Authors.
-*/
-
-
-#include "r8180.h"
-#include "r8180_hw.h"
-
-#include <net/iw_handler.h>
-#include "ieee80211/dot11d.h"
-
-static u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
-	6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
-
-#define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
-
-static struct rtl8187se_channel_list default_channel_plan[] = {
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19},		/* FCC */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},						/* IC */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* ETSI	*/
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* Spain. Change to ETSI. */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* France. Change to ETSI. */
-	{{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9},						/* MKK */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},	/* MKK1	*/
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},	/* Israel */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17},			/* For 11a , TELEC */
-	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}					/* For Global Domain. 1-11:active scan, 12-14 passive scan.*/	/* +YJ, 080626 */
-};
-static int r8180_wx_get_freq(struct net_device *dev,
-			     struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
-}
-
-
-static int r8180_wx_set_key(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *key)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct iw_point *erq = &(wrqu->encoding);
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	if (erq->length > 0) {
-		u32 *tkey = (u32 *) key;
-		priv->key0[0] = tkey[0];
-		priv->key0[1] = tkey[1];
-		priv->key0[2] = tkey[2];
-		priv->key0[3] = tkey[3] & 0xff;
-		DMESG("Setting wep key to %x %x %x %x",
-		      tkey[0], tkey[1], tkey[2], tkey[3]);
-		rtl8180_set_hw_wep(dev);
-	}
-	return 0;
-}
-
-
-static int r8180_wx_set_beaconinterval(struct net_device *dev,
-				       struct iw_request_info *aa,
-				       union iwreq_data *wrqu, char *b)
-{
-	int *parms = (int *)b;
-	int bi = parms[0];
-
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	DMESG("setting beacon interval to %x", bi);
-
-	priv->ieee80211->current_network.beacon_interval = bi;
-	rtl8180_commit(dev);
-	up(&priv->wx_sem);
-
-	return 0;
-}
-
-
-
-static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
-}
-
-
-
-static int r8180_wx_get_rate(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
-}
-
-
-
-static int r8180_wx_set_rate(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	int ret;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-
-	ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-
-
-static int r8180_wx_set_crcmon(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int *parms = (int *)extra;
-	int enable = (parms[0] > 0);
-	short prev = priv->crcmon;
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-
-	if (enable)
-		priv->crcmon = 1;
-	else
-		priv->crcmon = 0;
-
-	DMESG("bad CRC in monitor mode are %s",
-	      priv->crcmon ? "accepted" : "rejected");
-
-	if (prev != priv->crcmon && priv->up)	{
-		rtl8180_down(dev);
-		rtl8180_up(dev);
-	}
-
-	up(&priv->wx_sem);
-
-	return 0;
-}
-
-
-static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	if (priv->bInactivePs)	{
-		if (wrqu->mode == IW_MODE_ADHOC)
-			IPSLeave(dev);
-	}
-	ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
-
-	up(&priv->wx_sem);
-	return ret;
-}
-
-/* YJ,add,080819,for hidden ap */
-struct  iw_range_with_scan_capa	{
-		/* Informative stuff (to choose between different interface) */
-
-		__u32		throughput; /* To give an idea... */
-
-		/* In theory this value should be the maximum benchmarked
-		 * TCP/IP throughput, because with most of these devices the
-		 * bit rate is meaningless (overhead an co) to estimate how
-		 * fast the connection will go and pick the fastest one.
-		 * I suggest people to play with Netperf or any benchmark...
-		 */
-
-		/* NWID (or domain id)	*/
-		__u32           min_nwid; /* Minimal NWID we are able to set */
-		__u32			max_nwid; /* Maximal NWID we are able to set */
-
-		/* Old Frequency (backward compat - moved lower ) */
-		__u16			old_num_channels;
-		__u8			old_num_frequency;
-
-		/* Scan capabilities */
-		__u8			scan_capa;
-};
-/* YJ,add,080819,for hidden ap */
-
-
-static int rtl8180_wx_get_range(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
-{
-	struct iw_range *range = (struct iw_range *)extra;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u16 val;
-	int i;
-
-	wrqu->data.length = sizeof(*range);
-	memset(range, 0, sizeof(*range));
-
-	/* Let's try to keep this struct in the same order as in
-	 * linux/include/wireless.h
-	 */
-
-	/* TODO: See what values we can set, and remove the ones we can't
-	 * set, or fill them with some default data.
-	 */
-
-	/* ~5 Mb/s real (802.11b) */
-	range->throughput = 5 * 1000 * 1000;
-
-	/* TODO: Not used in 802.11b?	*/
-/*	range->min_nwid; */	/* Minimal NWID we are able to set */
-	/* TODO: Not used in 802.11b?	*/
-/*	range->max_nwid; */	/* Maximal NWID we are able to set */
-
-		/* Old Frequency (backward compat - moved lower ) */
-/*	range->old_num_channels; */
-/*	range->old_num_frequency; */
-/*	range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
-	if (priv->rf_set_sens != NULL)
-		range->sensitivity = priv->max_sens;	/* signal level threshold range */
-
-	range->max_qual.qual = 100;
-	/* TODO: Find real max RSSI and stick here */
-	range->max_qual.level = 0;
-	range->max_qual.noise = -98;
-	range->max_qual.updated = 7; /* Updated all three */
-
-	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
-	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
-	range->avg_qual.level = 20 + -98;
-	range->avg_qual.noise = 0;
-	range->avg_qual.updated = 7; /* Updated all three */
-
-	range->num_bitrates = RATE_COUNT;
-
-	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
-		range->bitrate[i] = rtl8180_rates[i];
-
-	range->min_frag = MIN_FRAG_THRESHOLD;
-	range->max_frag = MAX_FRAG_THRESHOLD;
-
-	range->pm_capa = 0;
-
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 16;
-
-		range->num_channels = 14;
-
-	for (i = 0, val = 0; i < 14; i++) {
-
-		/* Include only legal frequencies for some countries */
-		if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
-				range->freq[val].i = i + 1;
-			range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
-			range->freq[val].e = 1;
-			val++;
-		} else {
-			/* FIXME: do we need to set anything for channels */
-			/* we don't use ? */
-		}
-
-		if (val == IW_MAX_FREQUENCIES)
-			break;
-	}
-
-	range->num_frequency = val;
-	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-						IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
-	return 0;
-}
-
-
-static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-	struct ieee80211_device *ieee = priv->ieee80211;
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	if (wrqu->data.flags & IW_SCAN_THIS_ESSID)	{
-		struct iw_scan_req *req = (struct iw_scan_req *)b;
-		if (req->essid_len)		{
-			ieee->current_network.ssid_len = req->essid_len;
-			memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
-		}
-	}
-
-	down(&priv->wx_sem);
-	if (priv->up)	{
-		priv->ieee80211->actscanning = true;
-		if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED))	{
-			IPSLeave(dev);
-		ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
-			ret = 0;
-		}	else	{
-			/* prevent scan in BusyTraffic */
-			/* FIXME: Need to consider last scan time */
-			if ((priv->link_detect.b_busy_traffic) && (true)) {
-				ret = 0;
-				printk("Now traffic is busy, please try later!\n");
-			}	else
-				/* prevent scan in BusyTraffic,end */
-				ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
-		}
-	}	else
-			ret = -1;
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-
-
-static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b)
-{
-
-	int ret;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	down(&priv->wx_sem);
-	if (priv->up)
-		ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
-	else
-		ret = -1;
-
-	up(&priv->wx_sem);
-	return ret;
-}
-
-
-static int r8180_wx_set_essid(struct net_device *dev,
-			      struct iw_request_info *a,
-			      union iwreq_data *wrqu, char *b)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	int ret;
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	if (priv->bInactivePs)
-		IPSLeave(dev);
-
-	ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
-
-	up(&priv->wx_sem);
-	return ret;
-}
-
-
-static int r8180_wx_get_essid(struct net_device *dev,
-			      struct iw_request_info *a,
-			      union iwreq_data *wrqu, char *b)
-{
-	int ret;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	down(&priv->wx_sem);
-
-	ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-
-
-static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b)
-{
-	int ret;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-
-	ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
-
-	up(&priv->wx_sem);
-	return ret;
-}
-
-
-static int r8180_wx_get_name(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
-}
-
-static int r8180_wx_set_frag(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	if (wrqu->frag.disabled)
-		priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
-	else {
-		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
-		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
-			return -EINVAL;
-
-		priv->ieee80211->fts = wrqu->frag.value & ~0x1;
-	}
-
-	return 0;
-}
-
-
-static int r8180_wx_get_frag(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	wrqu->frag.value = priv->ieee80211->fts;
-	wrqu->frag.fixed = 0;	/* no auto select */
-	wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
-
-	return 0;
-}
-
-
-static int r8180_wx_set_wap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *awrq, char *extra)
-{
-	int ret;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-
-	ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
-
-	up(&priv->wx_sem);
-	return ret;
-
-}
-
-
-static int r8180_wx_get_wap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
-}
-
-
-static int r8180_wx_set_enc(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *key)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-
-	down(&priv->wx_sem);
-
-	if (priv->hw_wep)
-		ret = r8180_wx_set_key(dev, info, wrqu, key);
-	else	{
-		DMESG("Setting SW wep key");
-		ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
-	}
-
-	up(&priv->wx_sem);
-	return ret;
-}
-
-
-static int r8180_wx_get_enc(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *key)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
-}
-
-
-static int r8180_wx_set_scan_type(struct net_device *dev,
-				  struct iw_request_info *aa,
-				  union	iwreq_data *wrqu, char *p)
-{
-
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int *parms = (int *)p;
-	int mode = parms[0];
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	priv->ieee80211->active_scan = mode;
-
-	return 1;
-}
-
-static int r8180_wx_set_retry(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int err = 0;
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-
-	if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
-	    wrqu->retry.disabled)	{
-		err = -EINVAL;
-		goto exit;
-	}
-	if (!(wrqu->retry.flags & IW_RETRY_LIMIT))	{
-		err = -EINVAL;
-		goto exit;
-	}
-
-	if (wrqu->retry.value > R8180_MAX_RETRY)	{
-		err = -EINVAL;
-		goto exit;
-	}
-	if (wrqu->retry.flags & IW_RETRY_MAX) {
-		priv->retry_rts = wrqu->retry.value;
-		DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
-
-	}	else {
-		priv->retry_data = wrqu->retry.value;
-		DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
-	}
-
-	/* FIXME !
-	 * We might try to write directly the TX config register
-	 * or to restart just the (R)TX process.
-	 * I'm unsure if whole reset is really needed
-	 */
-
-	rtl8180_commit(dev);
-exit:
-	up(&priv->wx_sem);
-
-	return err;
-}
-
-static int r8180_wx_get_retry(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-	wrqu->retry.disabled = 0; /* can't be disabled */
-
-	if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
-	    IW_RETRY_LIFETIME)
-		return -EINVAL;
-
-	if (wrqu->retry.flags & IW_RETRY_MAX) {
-		wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
-		wrqu->retry.value = priv->retry_rts;
-	} else {
-		wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
-		wrqu->retry.value = priv->retry_data;
-	}
-
-	return 0;
-}
-
-static int r8180_wx_get_sens(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	if (priv->rf_set_sens == NULL)
-		return -1; /* we have not this support for this radio */
-	wrqu->sens.value = priv->sens;
-	return 0;
-}
-
-
-static int r8180_wx_set_sens(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	short err = 0;
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	if (priv->rf_set_sens == NULL) {
-		err = -1; /* we have not this support for this radio */
-		goto exit;
-	}
-	if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
-		priv->sens = wrqu->sens.value;
-	else
-		err = -EINVAL;
-
-exit:
-	up(&priv->wx_sem);
-
-	return err;
-}
-
-
-static int r8180_wx_set_rawtx(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-
-	ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
-
-	up(&priv->wx_sem);
-
-	return ret;
-
-}
-
-static int r8180_wx_get_power(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu, char *extra)
-{
-	int ret;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	down(&priv->wx_sem);
-
-	ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-
-static int r8180_wx_set_power(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu, char *extra)
-{
-	int ret;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
-	if (wrqu->power.disabled == 0) {
-		wrqu->power.flags |= IW_POWER_ALL_R;
-		wrqu->power.flags |= IW_POWER_TIMEOUT;
-		wrqu->power.value = 1000;
-	}
-
-	ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-
-static int r8180_wx_set_rts(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	if (wrqu->rts.disabled)
-		priv->rts = DEFAULT_RTS_THRESHOLD;
-	else {
-		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
-		    wrqu->rts.value > MAX_RTS_THRESHOLD)
-			return -EINVAL;
-
-		priv->rts = wrqu->rts.value;
-	}
-
-	return 0;
-}
-static int r8180_wx_get_rts(struct net_device *dev,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
-	wrqu->rts.value = priv->rts;
-	wrqu->rts.fixed = 0;	/* no auto select */
-	wrqu->rts.disabled = (wrqu->rts.value == 0);
-
-	return 0;
-}
-static int dummy(struct net_device *dev, struct iw_request_info *a,
-		 union iwreq_data *wrqu, char *b)
-{
-	return -1;
-}
-
-static int r8180_wx_get_iwmode(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee;
-	int ret = 0;
-
-
-
-	down(&priv->wx_sem);
-
-	ieee = priv->ieee80211;
-
-	strcpy(extra, "802.11");
-	if (ieee->modulation & IEEE80211_CCK_MODULATION) {
-		strcat(extra, "b");
-		if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-			strcat(extra, "/g");
-	} else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-		strcat(extra, "g");
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-static int r8180_wx_set_iwmode(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee80211;
-	int *param = (int *)extra;
-	int ret = 0;
-	int modulation = 0, mode = 0;
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-
-	if (*param == 1) {
-		modulation |= IEEE80211_CCK_MODULATION;
-		mode = IEEE_B;
-	printk(KERN_INFO "B mode!\n");
-	} else if (*param == 2) {
-		modulation |= IEEE80211_OFDM_MODULATION;
-		mode = IEEE_G;
-	printk(KERN_INFO "G mode!\n");
-	} else if (*param == 3) {
-		modulation |= IEEE80211_CCK_MODULATION;
-		modulation |= IEEE80211_OFDM_MODULATION;
-		mode = IEEE_B|IEEE_G;
-	printk(KERN_INFO "B/G mode!\n");
-	}
-
-	if (ieee->proto_started) {
-		ieee80211_stop_protocol(ieee);
-		ieee->mode = mode;
-		ieee->modulation = modulation;
-		ieee80211_start_protocol(ieee);
-	} else {
-		ieee->mode = mode;
-		ieee->modulation = modulation;
-	}
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-static int r8180_wx_get_preamble(struct net_device *dev,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
-	down(&priv->wx_sem);
-
-
-
-	*extra = (char) priv->plcp_preamble_mode;	/* 0:auto 1:short 2:long */
-	up(&priv->wx_sem);
-
-	return 0;
-}
-static int r8180_wx_set_preamble(struct net_device *dev,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	if (*extra < 0 || *extra > 2)
-		ret = -1;
-	else
-		priv->plcp_preamble_mode = *((short *)extra);
-
-
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-static int r8180_wx_get_siglevel(struct net_device *dev,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-
-
-
-	down(&priv->wx_sem);
-	/* Modify by hikaru 6.5 */
-	*((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
-
-
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-static int r8180_wx_get_sigqual(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-
-
-
-	down(&priv->wx_sem);
-	/* Modify by hikaru 6.5	*/
-	*((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
-
-
-
-	up(&priv->wx_sem);
-
-	return ret;
-}
-static int r8180_wx_reset_stats(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	down(&priv->wx_sem);
-
-	priv->stats.txrdu = 0;
-	priv->stats.rxrdu = 0;
-	priv->stats.rxnolast = 0;
-	priv->stats.rxnodata = 0;
-	priv->stats.rxnopointer = 0;
-	priv->stats.txnperr = 0;
-	priv->stats.txresumed = 0;
-	priv->stats.rxerr = 0;
-	priv->stats.rxoverflow = 0;
-	priv->stats.rxint = 0;
-
-	priv->stats.txnpokint = 0;
-	priv->stats.txhpokint = 0;
-	priv->stats.txhperr = 0;
-	priv->stats.ints = 0;
-	priv->stats.shints = 0;
-	priv->stats.txoverflow = 0;
-	priv->stats.rxdmafail = 0;
-	priv->stats.txbeacon = 0;
-	priv->stats.txbeaconerr = 0;
-	priv->stats.txlpokint = 0;
-	priv->stats.txlperr = 0;
-	priv->stats.txretry = 0;/* 20060601 */
-	priv->stats.rxcrcerrmin = 0 ;
-	priv->stats.rxcrcerrmid = 0;
-	priv->stats.rxcrcerrmax = 0;
-	priv->stats.rxicverr = 0;
-
-	up(&priv->wx_sem);
-
-	return 0;
-
-}
-static int r8180_wx_radio_on(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-
-	down(&priv->wx_sem);
-	priv->rf_wakeup(dev);
-
-	up(&priv->wx_sem);
-
-	return 0;
-
-}
-
-static int r8180_wx_radio_off(struct net_device *dev,
-			      struct iw_request_info *info,
-			      union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-
-	down(&priv->wx_sem);
-	priv->rf_sleep(dev);
-
-	up(&priv->wx_sem);
-
-	return 0;
-
-}
-static int r8180_wx_get_channelplan(struct net_device *dev,
-				    struct iw_request_info *info,
-				    union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
-	down(&priv->wx_sem);
-	*extra = priv->channel_plan;
-
-
-
-	up(&priv->wx_sem);
-
-	return 0;
-}
-static int r8180_wx_set_channelplan(struct net_device *dev,
-				    struct iw_request_info *info,
-				    union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int *val = (int *)extra;
-	int i;
-	printk("-----in fun %s\n", __func__);
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	/* unsigned long flags; */
-	down(&priv->wx_sem);
-	if (default_channel_plan[*val].len != 0) {
-		priv->channel_plan = *val;
-		/* Clear old channel map 8 */
-		for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
-			GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
-
-		/* Set new channel map */
-		for (i = 1; i <= default_channel_plan[*val].len; i++)
-			GET_DOT11D_INFO(priv->ieee80211)->channel_map[default_channel_plan[*val].channel[i-1]] = 1;
-
-	}
-	up(&priv->wx_sem);
-
-	return 0;
-}
-
-static int r8180_wx_get_version(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	/* struct ieee80211_device *ieee; */
-
-	down(&priv->wx_sem);
-	strcpy(extra, "1020.0808");
-	up(&priv->wx_sem);
-
-	return 0;
-}
-
-/* added by amy 080818 */
-/*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
-static int r8180_wx_set_forcerate(struct net_device *dev,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 forcerate = *extra;
-
-	down(&priv->wx_sem);
-
-	printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
-	if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
-		(forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
-		(forcerate == 96) || (forcerate == 108)) {
-		priv->ForcedDataRate = 1;
-		priv->ieee80211->rate = forcerate * 5;
-	}	else if (forcerate == 0)	{
-		priv->ForcedDataRate = 0;
-		printk("OK! return rate adaptive\n");
-	}	else
-			printk("ERR: wrong rate\n");
-	up(&priv->wx_sem);
-	return 0;
-}
-
-static int r8180_wx_set_enc_ext(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
-{
-
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	int ret = 0;
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
-	up(&priv->wx_sem);
-	return ret;
-
-}
-static int r8180_wx_set_auth(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
-	up(&priv->wx_sem);
-	return ret;
-}
-
-static int r8180_wx_set_mlme(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	int ret = 0;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-
-	down(&priv->wx_sem);
-#if 1
-	ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
-#endif
-	up(&priv->wx_sem);
-	return ret;
-}
-static int r8180_wx_set_gen_ie(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-	int ret = 0;
-		struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-	if (priv->ieee80211->bHwRadioOff)
-		return 0;
-
-	down(&priv->wx_sem);
-#if 1
-	ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
-#endif
-	up(&priv->wx_sem);
-	return ret;
-
-
-}
-
-static const iw_handler r8180_wx_handlers[] =	{
-	IW_HANDLER(SIOCGIWNAME,		r8180_wx_get_name),
-	IW_HANDLER(SIOCSIWNWID,		dummy),
-	IW_HANDLER(SIOCGIWNWID,		dummy),
-	IW_HANDLER(SIOCSIWFREQ,		r8180_wx_set_freq),
-	IW_HANDLER(SIOCGIWFREQ,		r8180_wx_get_freq),
-	IW_HANDLER(SIOCSIWMODE, 	r8180_wx_set_mode),
-	IW_HANDLER(SIOCGIWMODE,		r8180_wx_get_mode),
-	IW_HANDLER(SIOCSIWSENS,		r8180_wx_set_sens),
-	IW_HANDLER(SIOCGIWSENS,		r8180_wx_get_sens),
-	IW_HANDLER(SIOCGIWRANGE,	rtl8180_wx_get_range),
-	IW_HANDLER(SIOCSIWSPY,		dummy),
-	IW_HANDLER(SIOCGIWSPY,		dummy),
-	IW_HANDLER(SIOCSIWAP,		r8180_wx_set_wap),
-	IW_HANDLER(SIOCGIWAP,		r8180_wx_get_wap),
-	IW_HANDLER(SIOCSIWMLME,		r8180_wx_set_mlme),
-	IW_HANDLER(SIOCGIWAPLIST,	dummy),		/* deprecated */
-	IW_HANDLER(SIOCSIWSCAN,		r8180_wx_set_scan),
-	IW_HANDLER(SIOCGIWSCAN,		r8180_wx_get_scan),
-	IW_HANDLER(SIOCSIWESSID,	r8180_wx_set_essid),
-	IW_HANDLER(SIOCGIWESSID,	r8180_wx_get_essid),
-	IW_HANDLER(SIOCSIWNICKN,	dummy),
-	IW_HANDLER(SIOCGIWNICKN,	dummy),
-	IW_HANDLER(SIOCSIWRATE,		r8180_wx_set_rate),
-	IW_HANDLER(SIOCGIWRATE,		r8180_wx_get_rate),
-	IW_HANDLER(SIOCSIWRTS,		r8180_wx_set_rts),
-	IW_HANDLER(SIOCGIWRTS,		r8180_wx_get_rts),
-	IW_HANDLER(SIOCSIWFRAG,		r8180_wx_set_frag),
-	IW_HANDLER(SIOCGIWFRAG,		r8180_wx_get_frag),
-	IW_HANDLER(SIOCSIWTXPOW,	dummy),
-	IW_HANDLER(SIOCGIWTXPOW,	dummy),
-	IW_HANDLER(SIOCSIWRETRY,	r8180_wx_set_retry),
-	IW_HANDLER(SIOCGIWRETRY,	r8180_wx_get_retry),
-	IW_HANDLER(SIOCSIWENCODE,	r8180_wx_set_enc),
-	IW_HANDLER(SIOCGIWENCODE,	r8180_wx_get_enc),
-	IW_HANDLER(SIOCSIWPOWER,	r8180_wx_set_power),
-	IW_HANDLER(SIOCGIWPOWER,	r8180_wx_get_power),
-	IW_HANDLER(SIOCSIWGENIE,	r8180_wx_set_gen_ie),
-	IW_HANDLER(SIOCSIWAUTH,		r8180_wx_set_auth),
-	IW_HANDLER(SIOCSIWENCODEEXT,	r8180_wx_set_enc_ext),
-};
-
-static const struct iw_priv_args r8180_private_args[] = {
-	{
-		SIOCIWFIRSTPRIV + 0x0,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
-	},
-	{	SIOCIWFIRSTPRIV + 0x1,
-		0, 0, "dummy"
-
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x2,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
-	},
-	{	SIOCIWFIRSTPRIV + 0x3,
-		0, 0, "dummy"
-
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x4,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
-
-	},
-	{	SIOCIWFIRSTPRIV + 0x5,
-		0, 0, "dummy"
-
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x6,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
-
-	},
-	{	SIOCIWFIRSTPRIV + 0x7,
-		0, 0, "dummy"
-
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x8,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x9,
-		0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0xA,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0xB,
-		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
-	},
-	{	SIOCIWFIRSTPRIV + 0xC,
-		0, 0, "dummy"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0xD,
-		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
-	},
-	{	SIOCIWFIRSTPRIV + 0xE,
-		0, 0, "dummy"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0xF,
-		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x10,
-		0, 0, "resetstats"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x11,
-		0, 0, "dummy"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x12,
-		0, 0, "radioon"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x13,
-		0, 0, "radiooff"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x14,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x15,
-		0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x16,
-		0, 0, "dummy"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x17,
-		0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
-	},
-	{
-		SIOCIWFIRSTPRIV + 0x18,
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
-	},
-};
-
-
-static iw_handler r8180_private_handler[] = {
-	r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
-	dummy,
-	r8180_wx_set_beaconinterval,
-	dummy,
-	/* r8180_wx_set_monitor_type, */
-	r8180_wx_set_scan_type,
-	dummy,
-	r8180_wx_set_rawtx,
-	dummy,
-	r8180_wx_set_iwmode,
-	r8180_wx_get_iwmode,
-	r8180_wx_set_preamble,
-	r8180_wx_get_preamble,
-	dummy,
-	r8180_wx_get_siglevel,
-	dummy,
-	r8180_wx_get_sigqual,
-	r8180_wx_reset_stats,
-	dummy,/* r8180_wx_get_stats */
-	r8180_wx_radio_on,
-	r8180_wx_radio_off,
-	r8180_wx_set_channelplan,
-	r8180_wx_get_channelplan,
-	dummy,
-	r8180_wx_get_version,
-	r8180_wx_set_forcerate,
-};
-
-static inline int is_same_network(struct ieee80211_network *src,
-				  struct ieee80211_network *dst,
-				  struct ieee80211_device *ieee)
-{
-		/* A network is only a duplicate if the channel, BSSID, ESSID
-		 * and the capability field (in particular IBSS and BSS) all match.
-		 * We treat all <hidden> with the same BSSID and channel
-		 * as one network
-		 */
-		if (src->channel != dst->channel)
-			return 0;
-
-		if (memcmp(src->bssid, dst->bssid, ETH_ALEN) != 0)
-			return 0;
-
-		if (ieee->iw_mode != IW_MODE_INFRA) {
-			if (src->ssid_len != dst->ssid_len)
-				return 0;
-			if (memcmp(src->ssid, dst->ssid, src->ssid_len) != 0)
-				return 0;
-		}
-
-		if ((src->capability & WLAN_CAPABILITY_IBSS) !=
-		    (dst->capability & WLAN_CAPABILITY_IBSS))
-			return 0;
-		if ((src->capability & WLAN_CAPABILITY_BSS) !=
-		    (dst->capability & WLAN_CAPABILITY_BSS))
-			return 0;
-
-		return 1;
-}
-
-/* WB modified to show signal to GUI on 18-01-2008 */
-static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee80211;
-	struct iw_statistics *wstats = &priv->wstats;
-	int tmp_level = 0;
-	int tmp_qual = 0;
-	int tmp_noise = 0;
-
-	if (ieee->state < IEEE80211_LINKED)	{
-		wstats->qual.qual = 0;
-		wstats->qual.level = 0;
-		wstats->qual.noise = 0;
-		wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
-		return wstats;
-	}
-
-	tmp_level = (&ieee->current_network)->stats.signal;
-	tmp_qual = (&ieee->current_network)->stats.signalstrength;
-	tmp_noise = (&ieee->current_network)->stats.noise;
-
-	wstats->qual.level = tmp_level;
-	wstats->qual.qual = tmp_qual;
-	wstats->qual.noise = tmp_noise;
-	wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
-	return wstats;
-}
-
-struct iw_handler_def  r8180_wx_handlers_def = {
-	.standard = r8180_wx_handlers,
-	.num_standard = ARRAY_SIZE(r8180_wx_handlers),
-	.private = r8180_private_handler,
-	.num_private = ARRAY_SIZE(r8180_private_handler),
-	.num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
-	.get_wireless_stats = r8180_get_wireless_stats,
-	.private_args = (struct iw_priv_args *)r8180_private_args,
-};
-
-
diff --git a/drivers/staging/rtl8187se/r8180_wx.h b/drivers/staging/rtl8187se/r8180_wx.h
deleted file mode 100644
index d471520..0000000
--- a/drivers/staging/rtl8187se/r8180_wx.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-	This is part of rtl8180 OpenSource driver - v 0.3
-	Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the official realtek driver
-	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
-	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
-	We want to thanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/* this file (will) contains wireless extension handlers*/
-
-#ifndef R8180_WX_H
-#define R8180_WX_H
-#include <linux/wireless.h>
-#include "ieee80211/ieee80211.h"
-extern struct iw_handler_def r8180_wx_handlers_def;
-
-#endif
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
deleted file mode 100644
index cc6f100..0000000
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ /dev/null
@@ -1,1464 +0,0 @@
-/*
- * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
- *
- * Module Name:
- *	r8185b_init.c
- *
- * Abstract:
- *	Hardware Initialization and Hardware IO for RTL8185B
- *
- * Major Change History:
- *	When		Who				What
- *	----------	---------------		-------------------------------
- *	2006-11-15	Xiong			Created
- *
- * Notes:
- *	This file is ported from RTL8185B Windows driver.
- *
- *
- */
-
-/*--------------------------Include File------------------------------------*/
-#include <linux/spinlock.h>
-#include "r8180_hw.h"
-#include "r8180.h"
-#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_93cx6.h"   /* Card EEPROM */
-#include "r8180_wx.h"
-#include "ieee80211/dot11d.h"
-/* #define CONFIG_RTL8180_IO_MAP */
-#define TC_3W_POLL_MAX_TRY_CNT 5
-
-static u8 MAC_REG_TABLE[][2] =	{
-	/*
-	 * PAGE 0:
-	 * 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in
-	 * HwConfigureRTL8185()
-	 * 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185().
-	 * 0x1F0~0x1F8  set in MacConfig_85BASIC()
-	 */
-	{0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
-	{0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
-	{0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
-	{0x94, 0x0F}, {0x95, 0x32},
-	{0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00},
-	{0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
-	{0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
-	{0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
-	{0xff, 0x00},
-
-	/*
-	 * PAGE 1:
-	 * For Flextronics system Logo PCIHCT failure:
-	 * 0x1C4~0x1CD set no-zero value to avoid PCI configuration
-	 * space 0x45[7]=1
-	 */
-	{0x5e, 0x01},
-	{0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
-	{0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
-	{0x82, 0xFF}, {0x83, 0x03},
-	/* lzm add 080826 */
-	{0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22},
-	/* lzm add 080826 */
-	{0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},
-	{0xe2, 0x00},
-
-
-	/* PAGE 2: */
-	{0x5e, 0x02},
-	{0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5},
-	{0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff},
-	{0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08},
-	{0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f},
-	{0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f},
-	{0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
-	{0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
-
-	/* PAGE 0: */
-	{0x5e, 0x00}, {0x9f, 0x03}
-	};
-
-
-static u8  ZEBRA_AGC[] = {
-	0,
-	0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76,
-	0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A,
-	0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x48, 0x47, 0x46, 0x45,
-	0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
-	0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-	0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, 0x17, 0x17, 0x18, 0x18,
-	0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
-	0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22,
-	0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
-	0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
-	};
-
-static u32 ZEBRA_RF_RX_GAIN_TABLE[] = {
-	0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6,
-	0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057,
-	0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3,
-	0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3,
-	0x0183, 0x0163, 0x0143, 0x0123, 0x0103
-	};
-
-static u8 OFDM_CONFIG[]	= {
-	/* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */
-	/* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */
-	/* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */
-	/* 0x00	*/
-	0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
-	0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
-	/* 0x10	*/
-	0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
-	0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
-	/* 0x20	*/
-	0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
-	0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
-	/* 0x30	*/
-	0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
-	0xD8, 0x3C, 0x7B, 0x10, 0x10
-	};
-
-	/*---------------------------------------------------------------
-	 *	Hardware IO
-	 *	the code is ported from Windows source code
-	 *---------------------------------------------------------------
-	 */
-
-static u8 PlatformIORead1Byte(struct net_device *dev, u32 offset)
-{
-	return read_nic_byte(dev, offset);
-}
-
-static void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data)
-{
-	write_nic_byte(dev, offset, data);
-	/*
-	 * To make sure write operation is completed,
-	 * 2005.11.09, by rcnjko.
-	 */
-	read_nic_byte(dev, offset);
-}
-
-static void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data)
-{
-	write_nic_word(dev, offset, data);
-	/*
-	 * To make sure write operation is completed,
-	 *  2005.11.09, by rcnjko.
-	 */
-	read_nic_word(dev, offset);
-}
-
-static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
-{
-	if (offset == PhyAddr) {
-		/* For Base Band configuration. */
-		unsigned char	cmdByte;
-		unsigned long	dataBytes;
-		unsigned char	idx;
-		u8		u1bTmp;
-
-		cmdByte = (u8)(data & 0x000000ff);
-		dataBytes = data>>8;
-
-		/*
-		 *	071010, rcnjko:
-		 *	The critical section is only BB read/write race
-		 *	condition. Assumption:
-		 *	1. We assume NO one will access BB at DIRQL, otherwise,
-		 *	system will crash for
-		 *	acquiring the spinlock in such context.
-		 *	2. PlatformIOWrite4Byte() MUST NOT be recursive.
-		 */
-		/* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
-
-		for (idx = 0; idx < 30; idx++) {
-			/* Make sure command bit is clear before access it. */
-			u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
-			if ((u1bTmp & BIT7) == 0)
-				break;
-			else
-				mdelay(10);
-		}
-
-		for (idx = 0; idx < 3; idx++)
-			PlatformIOWrite1Byte(dev, offset+1+idx,
-					     ((u8 *)&dataBytes)[idx]);
-
-		write_nic_byte(dev, offset, cmdByte);
-
-		/* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */
-	} else {
-		write_nic_dword(dev, offset, data);
-		/*
-		 * To make sure write operation is completed, 2005.11.09,
-		 *  by rcnjko.
-		 */
-		read_nic_dword(dev, offset);
-	}
-}
-
-static void SetOutputEnableOfRfPins(struct net_device *dev)
-{
-	write_nic_word(dev, RFPinsEnable, 0x1bff);
-}
-
-static bool HwHSSIThreeWire(struct net_device *dev,
-			    u8 *pDataBuf,
-			    bool write)
-{
-	u8	TryCnt;
-	u8	u1bTmp;
-
-	/* Check if WE and RE are cleared. */
-	for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
-		u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
-		if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
-			break;
-
-		udelay(10);
-	}
-	if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
-		netdev_err(dev,
-			   "HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n",
-			   u1bTmp);
-	return false;
-	}
-
-	/* RTL8187S HSSI Read/Write Function */
-	u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
-	u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
-	write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
-
-	/* jong: HW SI read must set reg84[3]=0. */
-	u1bTmp = read_nic_byte(dev, RFPinsSelect);
-	u1bTmp &= ~BIT3;
-	write_nic_byte(dev, RFPinsSelect, u1bTmp);
-	/*  Fill up data buffer for write operation. */
-
-	/* SI - reg274[3:0] : RF register's Address */
-	if (write)
-		write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
-	else
-		write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
-
-	/* Set up command: WE or RE. */
-	if (write)
-		write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
-	else
-		write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
-
-
-	/* Check if DONE is set. */
-	for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
-		u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
-		if (u1bTmp & SW_3W_CMD1_DONE)
-			break;
-
-		udelay(10);
-	}
-
-	write_nic_byte(dev, SW_3W_CMD1, 0);
-
-	/* Read back data for read operation. */
-	if (!write) {
-		/* Serial Interface : reg363_362[11:0] */
-		*((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ);
-		*((u16 *)pDataBuf) &= 0x0FFF;
-	}
-
-	return true;
-}
-
-void RF_WriteReg(struct net_device *dev, u8 offset, u16 data)
-{
-	u16 reg = (data << 4) | (offset & 0x0f);
-	HwHSSIThreeWire(dev, (u8 *)&reg, true);
-}
-
-u16 RF_ReadReg(struct net_device *dev, u8 offset)
-{
-	u16 reg = offset & 0x0f;
-	HwHSSIThreeWire(dev, (u8 *)&reg, false);
-	return reg;
-}
-
-static u8 ReadBBPortUchar(struct net_device *dev, u32 addr)
-{
-	PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
-	return PlatformIORead1Byte(dev, PhyDataR);
-}
-
-/* by Owen on 04/07/14 for writing BB register successfully */
-static void WriteBBPortUchar(struct net_device *dev, u32 Data)
-{
-	PlatformIOWrite4Byte(dev, PhyAddr, Data);
-	ReadBBPortUchar(dev, Data);
-}
-
-/*
- *	Description:
- *	Perform Antenna settings with antenna diversity on 87SE.
- *		Created by Roger, 2008.01.25.
- */
-bool SetAntennaConfig87SE(struct net_device *dev,
-			  u8   DefaultAnt, /* 0: Main, 1: Aux. */
-			  bool bAntDiversity) /* 1:Enable, 0: Disable. */
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	bool   bAntennaSwitched = true;
-	/* 0x00 = disabled, 0x80 = enabled */
-	u8	ant_diversity_offset = 0x00;
-
-	/*
-	 * printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n",
-	 * DefaultAnt, bAntDiversity);
-	 */
-
-	/* Threshold for antenna diversity. */
-	write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */
-
-	if (bAntDiversity)	/*	Enable Antenna Diversity. */
-		ant_diversity_offset = 0x80;
-
-	if (DefaultAnt == 1) { /* aux Antenna */
-		/* Mac register, aux antenna */
-		write_nic_byte(dev, ANTSEL, 0x00);
-
-		/* Config CCK RX antenna. */
-		write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
-
-		/* Reg01 : 47 | ant_diversity_offset */
-		write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
-
-		/* Config OFDM RX antenna. */
-		write_phy_ofdm(dev, 0x0D, 0x54);	/* Reg0d : 54 */
-		/* Reg18 : 32 */
-		write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
-	} else { /* main Antenna */
-		/* Mac register, main antenna */
-		write_nic_byte(dev, ANTSEL, 0x03);
-
-		/* Config CCK RX antenna.	*/
-		write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
-		/* Reg01 : 47 */
-		write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
-
-		/* Config OFDM RX antenna. */
-		write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */
-		/*Reg18 : 32 */
-		write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
-	}
-	priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */
-	return	bAntennaSwitched;
-}
-/*
- *--------------------------------------------------------------
- *		Hardware Initialization.
- *		the code is ported from Windows source code
- *--------------------------------------------------------------
- */
-
-static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
-{
-
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u32			i;
-	u32	addr, data;
-	u32 u4bRegOffset, u4bRegValue;
-	u16 u4bRF23, u4bRF24;
-	u8			u1b24E;
-	int d_cut = 0;
-
-
-/*
- *===========================================================================
- *	87S_PCIE :: RADIOCFG.TXT
- *===========================================================================
- */
-
-
-	/* Page1 : reg16-reg30 */
-	RF_WriteReg(dev, 0x00, 0x013f);		mdelay(1); /* switch to page1 */
-	u4bRF23 = RF_ReadReg(dev, 0x08);	mdelay(1);
-	u4bRF24 = RF_ReadReg(dev, 0x09);	mdelay(1);
-
-	if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
-		d_cut = 1;
-		netdev_info(dev, "card type changed from C- to D-cut\n");
-	}
-
-	/* Page0 : reg0-reg15 */
-
-	RF_WriteReg(dev, 0x00, 0x009f);		mdelay(1);/* 1	*/
-	RF_WriteReg(dev, 0x01, 0x06e0);		mdelay(1);
-	RF_WriteReg(dev, 0x02, 0x004d);		mdelay(1);/* 2	*/
-	RF_WriteReg(dev, 0x03, 0x07f1);		mdelay(1);/* 3	*/
-	RF_WriteReg(dev, 0x04, 0x0975);		mdelay(1);
-	RF_WriteReg(dev, 0x05, 0x0c72);		mdelay(1);
-	RF_WriteReg(dev, 0x06, 0x0ae6);		mdelay(1);
-	RF_WriteReg(dev, 0x07, 0x00ca);		mdelay(1);
-	RF_WriteReg(dev, 0x08, 0x0e1c);		mdelay(1);
-	RF_WriteReg(dev, 0x09, 0x02f0);		mdelay(1);
-	RF_WriteReg(dev, 0x0a, 0x09d0);		mdelay(1);
-	RF_WriteReg(dev, 0x0b, 0x01ba);		mdelay(1);
-	RF_WriteReg(dev, 0x0c, 0x0640);		mdelay(1);
-	RF_WriteReg(dev, 0x0d, 0x08df);		mdelay(1);
-	RF_WriteReg(dev, 0x0e, 0x0020);		mdelay(1);
-	RF_WriteReg(dev, 0x0f, 0x0990);		mdelay(1);
-
-	/*  Page1 : reg16-reg30 */
-	RF_WriteReg(dev, 0x00, 0x013f);		mdelay(1);
-	RF_WriteReg(dev, 0x03, 0x0806);		mdelay(1);
-	RF_WriteReg(dev, 0x04, 0x03a7);		mdelay(1);
-	RF_WriteReg(dev, 0x05, 0x059b);		mdelay(1);
-	RF_WriteReg(dev, 0x06, 0x0081);		mdelay(1);
-	RF_WriteReg(dev, 0x07, 0x01A0);		mdelay(1);
-/*
- * Don't write RF23/RF24 to make a difference between 87S C cut and D cut.
- * asked by SD3 stevenl.
- */
-	RF_WriteReg(dev, 0x0a, 0x0001);		mdelay(1);
-	RF_WriteReg(dev, 0x0b, 0x0418);		mdelay(1);
-
-	if (d_cut) {
-		RF_WriteReg(dev, 0x0c, 0x0fbe);		mdelay(1);
-		RF_WriteReg(dev, 0x0d, 0x0008);		mdelay(1);
-		/* RX LO buffer */
-		RF_WriteReg(dev, 0x0e, 0x0807);		mdelay(1);
-	} else {
-		RF_WriteReg(dev, 0x0c, 0x0fbe);		mdelay(1);
-		RF_WriteReg(dev, 0x0d, 0x0008);		mdelay(1);
-		/* RX LO buffer */
-		RF_WriteReg(dev, 0x0e, 0x0806);		mdelay(1);
-	}
-
-	RF_WriteReg(dev, 0x0f, 0x0acc);		mdelay(1);
-	RF_WriteReg(dev, 0x00, 0x01d7);		mdelay(1); /* 6 */
-	RF_WriteReg(dev, 0x03, 0x0e00);		mdelay(1);
-	RF_WriteReg(dev, 0x04, 0x0e50);		mdelay(1);
-
-	for (i = 0; i <= 36; i++) {
-		RF_WriteReg(dev, 0x01, i);		mdelay(1);
-		RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
-	}
-
-	RF_WriteReg(dev, 0x05, 0x0203);		mdelay(1); /* 203, 343 */
-	RF_WriteReg(dev, 0x06, 0x0200);		mdelay(1); /* 400 */
-	/* switch to reg16-reg30, and HSSI disable 137 */
-	RF_WriteReg(dev, 0x00, 0x0137);		mdelay(1);
-	mdelay(10); /* Deay 10 ms. */		/* 0xfd */
-
-	/* Z4 synthesizer loop filter setting, 392 */
-	RF_WriteReg(dev, 0x0d, 0x0008);		mdelay(1);
-	mdelay(10); /* Deay 10 ms. */		/* 0xfd */
-
-	/* switch to reg0-reg15, and HSSI disable */
-	RF_WriteReg(dev, 0x00, 0x0037);		mdelay(1);
-	mdelay(10); /* Deay 10 ms. */		/* 0xfd	*/
-
-	/* CBC on, Tx Rx disable, High gain */
-	RF_WriteReg(dev, 0x04, 0x0160);		mdelay(1);
-	mdelay(10); /* Deay 10 ms. */		/* 0xfd	*/
-
-	/* Z4 setted channel 1 */
-	RF_WriteReg(dev, 0x07, 0x0080);		mdelay(1);
-	mdelay(10); /* Deay 10 ms. */		/* 0xfd	*/
-
-	RF_WriteReg(dev, 0x02, 0x088D);		mdelay(1); /* LC calibration */
-	mdelay(200); /* Deay 200 ms. */		/* 0xfd	*/
-	mdelay(10);  /* Deay 10 ms. */		/* 0xfd	*/
-	mdelay(10);  /* Deay 10 ms. */		/* 0xfd	*/
-
-	/* switch to reg16-reg30 137, and HSSI disable 137 */
-	RF_WriteReg(dev, 0x00, 0x0137);		mdelay(1);
-	mdelay(10); /* Deay 10 ms. */		/* 0xfd	*/
-
-	RF_WriteReg(dev, 0x07, 0x0000);		mdelay(1);
-	RF_WriteReg(dev, 0x07, 0x0180);		mdelay(1);
-	RF_WriteReg(dev, 0x07, 0x0220);		mdelay(1);
-	RF_WriteReg(dev, 0x07, 0x03E0);		mdelay(1);
-
-	/* DAC calibration off 20070702	*/
-	RF_WriteReg(dev, 0x06, 0x00c1);		mdelay(1);
-	RF_WriteReg(dev, 0x0a, 0x0001);		mdelay(1);
-	/* For crystal calibration, added by Roger, 2007.12.11. */
-	if (priv->bXtalCalibration) { /* reg 30.	*/
-	 /*
-	  *	enable crystal calibration.
-	  *	RF Reg[30], (1)Xin:[12:9], Xout:[8:5],  addr[4:0].
-	  *	(2)PA Pwr delay timer[15:14], default: 2.4us,
-	  *	set BIT15=0
-	  *	(3)RF signal on/off when calibration[13], default: on,
-	  *	set BIT13=0.
-	  *	So we should minus 4 BITs offset.
-	  */
-		RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) |
-			    (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
-		netdev_info(dev, "ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
-		      (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) |
-		       BIT11 | BIT9);
-	} else {
-		/* using default value. Xin=6, Xout=6.	*/
-		RF_WriteReg(dev, 0x0f, 0x0acc);		mdelay(1);
-	}
-	/* switch to reg0-reg15, and HSSI enable */
-	RF_WriteReg(dev, 0x00, 0x00bf);		mdelay(1);
-	/* Rx BB start calibration, 00c//+edward */
-	RF_WriteReg(dev, 0x0d, 0x08df);		mdelay(1);
-	/* temperature meter off */
-	RF_WriteReg(dev, 0x02, 0x004d);		mdelay(1);
-	RF_WriteReg(dev, 0x04, 0x0975);		mdelay(1); /* Rx mode */
-	mdelay(10);	/* Deay 10 ms.*/	/* 0xfe	*/
-	mdelay(10);	/* Deay 10 ms.*/	/* 0xfe	*/
-	mdelay(10);	/* Deay 10 ms.*/	/* 0xfe	*/
-	/* Rx mode*/	/*+edward */
-	RF_WriteReg(dev, 0x00, 0x0197);		mdelay(1);
-	/* Rx mode*/	/*+edward */
-	RF_WriteReg(dev, 0x05, 0x05ab);		mdelay(1);
-	/* Rx mode*/	/*+edward */
-	RF_WriteReg(dev, 0x00, 0x009f);		mdelay(1);
-	/* Rx mode*/	/*+edward */
-	RF_WriteReg(dev, 0x01, 0x0000);		mdelay(1);
-	/* Rx mode*/	/*+edward */
-	RF_WriteReg(dev, 0x02, 0x0000);		mdelay(1);
-	/* power save parameters. */
-	u1b24E = read_nic_byte(dev, 0x24E);
-	write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
-
-	/*======================================================================
-	 *
-	 *======================================================================
-	 * CCKCONF.TXT
-	 *======================================================================
-	 *
-	 *	[POWER SAVE] Power Saving Parameters by jong. 2007-11-27
-	 *	CCK reg0x00[7]=1'b1 :power saving for TX (default)
-	 *	CCK reg0x00[6]=1'b1: power saving for RX (default)
-	 *	CCK reg0x06[4]=1'b1: turn off channel estimation related
-	 *	circuits if not doing channel estimation.
-	 *	CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
-	 *	CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
-	 */
-
-	write_phy_cck(dev, 0x00, 0xc8);
-	write_phy_cck(dev, 0x06, 0x1c);
-	write_phy_cck(dev, 0x10, 0x78);
-	write_phy_cck(dev, 0x2e, 0xd0);
-	write_phy_cck(dev, 0x2f, 0x06);
-	write_phy_cck(dev, 0x01, 0x46);
-
-	/* power control */
-	write_nic_byte(dev, CCK_TXAGC, 0x10);
-	write_nic_byte(dev, OFDM_TXAGC, 0x1B);
-	write_nic_byte(dev, ANTSEL, 0x03);
-
-
-
-	/*
-	 *======================================================================
-	 *	AGC.txt
-	 *======================================================================
-	 */
-
-	write_phy_ofdm(dev, 0x00, 0x12);
-
-	for (i = 0; i < 128; i++) {
-
-		data = ZEBRA_AGC[i+1];
-		data = data << 8;
-		data = data | 0x0000008F;
-
-		addr = i + 0x80; /* enable writing AGC table */
-		addr = addr << 8;
-		addr = addr | 0x0000008E;
-
-		WriteBBPortUchar(dev, data);
-		WriteBBPortUchar(dev, addr);
-		WriteBBPortUchar(dev, 0x0000008E);
-	}
-
-	PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080);	/* Annie, 2006-05-05 */
-
-	/*
-	 *======================================================================
-	 *
-	 *======================================================================
-	 * OFDMCONF.TXT
-	 *======================================================================
-	 */
-
-	for (i = 0; i < 60; i++) {
-		u4bRegOffset = i;
-		u4bRegValue = OFDM_CONFIG[i];
-
-		WriteBBPortUchar(dev,
-				(0x00000080 |
-				(u4bRegOffset & 0x7f) |
-				((u4bRegValue & 0xff) << 8)));
-	}
-
-	/*
-	 *======================================================================
-	 * by amy for antenna
-	 *======================================================================
-	 */
-	/*
-	 * Config Sw/Hw  Combinational Antenna Diversity. Added by Roger,
-	 * 2008.02.26.
-	 */
-	SetAntennaConfig87SE(dev, priv->bDefaultAntenna1,
-			     priv->bSwAntennaDiverity);
-}
-
-
-void UpdateInitialGain(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	/* lzm add 080826 */
-	if (priv->eRFPowerState != RF_ON) {
-		/*	Don't access BB/RF under disable PLL situation.
-		 *	RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain -
-		 *	pHalData->eRFPowerState!=RF_ON\n"));
-		 *	Back to the original state
-		 */
-		priv->InitialGain = priv->InitialGainBackUp;
-		return;
-	}
-
-	switch (priv->InitialGain) {
-	case 1: /* m861dBm */
-		write_phy_ofdm(dev, 0x17, 0x26);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
-		break;
-
-	case 2: /* m862dBm */
-		write_phy_ofdm(dev, 0x17, 0x36);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
-		break;
-
-	case 3: /* m863dBm */
-		write_phy_ofdm(dev, 0x17, 0x36);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
-		break;
-
-	case 4: /* m864dBm */
-		write_phy_ofdm(dev, 0x17, 0x46);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
-		break;
-
-	case 5: /* m82dBm */
-		write_phy_ofdm(dev, 0x17, 0x46);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0x96);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfb);	mdelay(1);
-		break;
-
-	case 6: /* m78dBm */
-		write_phy_ofdm(dev, 0x17, 0x56);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0x96);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
-		break;
-
-	case 7: /* m74dBm */
-		write_phy_ofdm(dev, 0x17, 0x56);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0xa6);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
-		break;
-
-	case 8:
-		write_phy_ofdm(dev, 0x17, 0x66);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0xb6);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfc);	mdelay(1);
-		break;
-
-	default: /* MP */
-		write_phy_ofdm(dev, 0x17, 0x26);	mdelay(1);
-		write_phy_ofdm(dev, 0x24, 0x86);	mdelay(1);
-		write_phy_ofdm(dev, 0x05, 0xfa);	mdelay(1);
-		break;
-	}
-}
-/*
- *	Description:
- *		Tx Power tracking mechanism routine on 87SE.
- *	Created by Roger, 2007.12.11.
- */
-static void InitTxPwrTracking87SE(struct net_device *dev)
-{
-	u32	u4bRfReg;
-
-	u4bRfReg = RF_ReadReg(dev, 0x02);
-
-	/* Enable Thermal meter indication.	*/
-	RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN);		mdelay(1);
-}
-
-static void PhyConfig8185(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-		write_nic_dword(dev, RCR, priv->ReceiveConfig);
-	   priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
-	/*  RF config */
-	ZEBRA_Config_85BASIC_HardCode(dev);
-	/* Set default initial gain state to 4, approved by SD3 DZ, by Bruce,
-	 * 2007-06-06.
-	 */
-	if (priv->bDigMechanism) {
-		if (priv->InitialGain == 0)
-			priv->InitialGain = 4;
-	}
-
-	/*
-	 *	Enable thermal meter indication to implement TxPower tracking
-	 *	on 87SE. We initialize thermal meter here to avoid unsuccessful
-	 *	configuration. Added by Roger, 2007.12.11.
-	 */
-	if (priv->bTxPowerTrack)
-		InitTxPwrTracking87SE(dev);
-
-	priv->InitialGainBackUp = priv->InitialGain;
-	UpdateInitialGain(dev);
-
-	return;
-}
-
-static void HwConfigureRTL8185(struct net_device *dev)
-{
-	/*
-	 * RTL8185_TODO: Determine Retrylimit, TxAGC,
-	 * AutoRateFallback control.
-	 */
-	u8 bUNIVERSAL_CONTROL_RL = 0;
-	u8 bUNIVERSAL_CONTROL_AGC = 1;
-	u8 bUNIVERSAL_CONTROL_ANT = 1;
-	u8 bAUTO_RATE_FALLBACK_CTL = 1;
-	u8 val8;
-	write_nic_word(dev, BRSR, 0x0fff);
-	/* Retry limit */
-	val8 = read_nic_byte(dev, CW_CONF);
-
-	if (bUNIVERSAL_CONTROL_RL)
-		val8 = val8 & 0xfd;
-	else
-		val8 = val8 | 0x02;
-
-	write_nic_byte(dev, CW_CONF, val8);
-
-	/* Tx AGC */
-	val8 = read_nic_byte(dev, TXAGC_CTL);
-	if (bUNIVERSAL_CONTROL_AGC) {
-		write_nic_byte(dev, CCK_TXAGC, 128);
-		write_nic_byte(dev, OFDM_TXAGC, 128);
-		val8 = val8 & 0xfe;
-	} else {
-		val8 = val8 | 0x01;
-	}
-
-
-	write_nic_byte(dev, TXAGC_CTL, val8);
-
-	/* Tx Antenna including Feedback control */
-	val8 = read_nic_byte(dev, TXAGC_CTL);
-
-	if (bUNIVERSAL_CONTROL_ANT) {
-		write_nic_byte(dev, ANTSEL, 0x00);
-		val8 = val8 & 0xfd;
-	} else {
-		val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */
-	}
-
-	write_nic_byte(dev, TXAGC_CTL, val8);
-
-	/* Auto Rate fallback control	*/
-	val8 = read_nic_byte(dev, RATE_FALLBACK);
-	val8 &= 0x7c;
-	if (bAUTO_RATE_FALLBACK_CTL) {
-		val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
-
-		/* <RJ_TODO_8185B> We shall set up the ARFR according
-		 * to user's setting.
-		 */
-		PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */
-	}
-	write_nic_byte(dev, RATE_FALLBACK, val8);
-}
-
-static void MacConfig_85BASIC_HardCode(struct net_device *dev)
-{
-	/*
-	 *======================================================================
-	 * MACREG.TXT
-	 *======================================================================
-	 */
-	int nLinesRead = 0;
-	u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0;
-	int i;
-
-	nLinesRead = sizeof(MAC_REG_TABLE)/2;
-
-	for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */
-		u4bRegOffset = MAC_REG_TABLE[i][0];
-		u4bRegValue = MAC_REG_TABLE[i][1];
-
-				if (u4bRegOffset == 0x5e)
-					u4bPageIndex = u4bRegValue;
-				else
-					u4bRegOffset |= (u4bPageIndex << 8);
-
-		write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
-	}
-	/* ================================================================= */
-}
-
-static void MacConfig_85BASIC(struct net_device *dev)
-{
-
-	u8			u1DA;
-	MacConfig_85BASIC_HardCode(dev);
-
-	/* ================================================================= */
-
-	/* Follow TID_AC_MAP of WMac. */
-	write_nic_word(dev, TID_AC_MAP, 0xfa50);
-
-	/* Interrupt Migration, Jong suggested we use set 0x0000 first,
-	 * 2005.12.14, by rcnjko.
-	 */
-	write_nic_word(dev, IntMig, 0x0000);
-
-	/* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */
-	PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
-	PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
-	PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
-
-	/* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */
-
-	/*
-	 *  power save parameter based on
-	 * "87SE power save parameters 20071127.doc", as follow.
-	 */
-
-	/* Enable DA10 TX power saving */
-	u1DA = read_nic_byte(dev, PHYPR);
-	write_nic_byte(dev, PHYPR, (u1DA | BIT2));
-
-	/* POWER: */
-	write_nic_word(dev, 0x360, 0x1000);
-	write_nic_word(dev, 0x362, 0x1000);
-
-	/* AFE. */
-	write_nic_word(dev, 0x370, 0x0560);
-	write_nic_word(dev, 0x372, 0x0560);
-	write_nic_word(dev, 0x374, 0x0DA4);
-	write_nic_word(dev, 0x376, 0x0DA4);
-	write_nic_word(dev, 0x378, 0x0560);
-	write_nic_word(dev, 0x37A, 0x0560);
-	write_nic_word(dev, 0x37C, 0x00EC);
-	write_nic_word(dev, 0x37E, 0x00EC); /* +edward */
-	write_nic_byte(dev, 0x24E, 0x01);
-}
-
-static u8 GetSupportedWirelessMode8185(struct net_device *dev)
-{
-	return WIRELESS_MODE_B | WIRELESS_MODE_G;
-}
-
-static void
-ActUpdateChannelAccessSetting(struct net_device *dev,
-			      enum wireless_mode mode,
-			      struct chnl_access_setting *chnl_access_setting)
-{
-	AC_CODING	eACI;
-
-	/*
-	 *	<RJ_TODO_8185B>
-	 *	TODO: We still don't know how to set up these registers,
-	 *	just follow WMAC to verify 8185B FPAG.
-	 *
-	 *	<RJ_TODO_8185B>
-	 *	Jong said CWmin/CWmax register are not functional in 8185B,
-	 *	so we shall fill channel access realted register into AC
-	 *	parameter registers,
-	 *	even in nQBss.
-	 */
-
-	/* Suggested by Jong, 2005.12.08. */
-	chnl_access_setting->sifs_timer = 0x22;
-	chnl_access_setting->difs_timer = 0x1C; /* 2006.06.02, by rcnjko. */
-	chnl_access_setting->slot_time_timer = 9; /* 2006.06.02, by rcnjko. */
-	/*
-	 * Suggested by wcchu, it is the default value of EIFS register,
-	 * 2005.12.08.
-	 */
-	chnl_access_setting->eifs_timer = 0x5B;
-	chnl_access_setting->cwmin_index = 3; /* 2006.06.02, by rcnjko. */
-	chnl_access_setting->cwmax_index = 7; /* 2006.06.02, by rcnjko. */
-
-	write_nic_byte(dev, SIFS, chnl_access_setting->sifs_timer);
-	/*
-	 * Rewrited from directly use PlatformEFIOWrite1Byte(),
-	 * by Annie, 2006-03-29.
-	 */
-	write_nic_byte(dev, SLOT, chnl_access_setting->slot_time_timer);
-
-	write_nic_byte(dev, EIFS, chnl_access_setting->eifs_timer);
-
-	/*
-	 * <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS
-	 * register, 2005.12.08.
-	 */
-	write_nic_byte(dev, AckTimeOutReg, 0x5B);
-
-	for (eACI = 0; eACI < AC_MAX; eACI++)
-		write_nic_byte(dev, ACM_CONTROL, 0);
-}
-
-static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
-{
-	struct  r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct  ieee80211_device *ieee = priv->ieee80211;
-	u8	btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
-
-	if ((btWirelessMode & btSupportedWirelessMode) == 0)	{
-		/*
-		 * Don't switch to unsupported wireless mode, 2006.02.15,
-		 * by rcnjko.
-		 */
-		DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
-			btWirelessMode, btSupportedWirelessMode);
-		return;
-	}
-
-	/* 1. Assign wireless mode to switch if necessary. */
-	if (btWirelessMode == WIRELESS_MODE_AUTO) {
-		if ((btSupportedWirelessMode & WIRELESS_MODE_A)) {
-			btWirelessMode = WIRELESS_MODE_A;
-		} else if (btSupportedWirelessMode & WIRELESS_MODE_G) {
-				btWirelessMode = WIRELESS_MODE_G;
-
-		} else if ((btSupportedWirelessMode & WIRELESS_MODE_B))	{
-				btWirelessMode = WIRELESS_MODE_B;
-		} else {
-			DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
-			       btSupportedWirelessMode);
-			btWirelessMode = WIRELESS_MODE_B;
-		}
-	}
-
-	/*
-	 * 2. Swtich band: RF or BB specific actions,
-	 * for example, refresh tables in omc8255, or change initial gain if
-	 * necessary. Nothing to do for Zebra to switch band. Update current
-	 * wireless mode if we switch to specified band successfully.
-	 */
-
-	ieee->mode = (enum wireless_mode)btWirelessMode;
-
-	/* 3. Change related setting. */
-	if (ieee->mode == WIRELESS_MODE_A)
-		DMESG("WIRELESS_MODE_A\n");
-	else if (ieee->mode == WIRELESS_MODE_B)
-		DMESG("WIRELESS_MODE_B\n");
-	else if (ieee->mode == WIRELESS_MODE_G)
-		DMESG("WIRELESS_MODE_G\n");
-
-	ActUpdateChannelAccessSetting(dev, ieee->mode,
-				      &priv->ChannelAccessSetting);
-}
-
-void rtl8185b_irq_enable(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	priv->irq_enabled = 1;
-	write_nic_dword(dev, IMR, priv->IntrMask);
-}
-
-static void MgntDisconnectIBSS(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u8 i;
-
-	for (i = 0; i < 6; i++)
-		priv->ieee80211->current_network.bssid[i] = 0x55;
-
-
-
-	priv->ieee80211->state = IEEE80211_NOLINK;
-	/*
-	 *	Stop Beacon.
-	 *
-	 *	Vista add a Adhoc profile, HW radio off until
-	 *	OID_DOT11_RESET_REQUEST Driver would set MSR=NO_LINK,
-	 *	then HW Radio ON, MgntQueue Stuck. Because Bcn DMA isn't
-	 *	complete, mgnt queue would stuck until Bcn packet send.
-	 *
-	 *	Disable Beacon Queue Own bit, suggested by jong
-	 */
-	ieee80211_stop_send_beacons(priv->ieee80211);
-
-	priv->ieee80211->link_change(dev);
-	notify_wx_assoc_event(priv->ieee80211);
-}
-
-static void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u8 i;
-
-	SendDisassociation(priv->ieee80211, asSta, asRsn);
-
-	if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) {
-		/* ShuChen TODO: change media status. */
-
-		for (i = 0; i < 6; i++)
-			priv->ieee80211->current_network.bssid[i] = 0x22;
-
-		ieee80211_disassociate(priv->ieee80211);
-	}
-}
-
-static void MgntDisconnectAP(struct net_device *dev, u8 asRsn)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	/*
-	 * Commented out by rcnjko, 2005.01.27:
-	 * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
-	 *
-	 *	2004/09/15, kcwu, the key should be cleared, or the new
-	 *	handshaking will not success
-	 *
-	 *	In WPA WPA2 need to Clear all key ... because new key will set
-	 *	after new handshaking. 2004.10.11, by rcnjko.
-	 */
-	MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid,
-				asRsn);
-
-	priv->ieee80211->state = IEEE80211_NOLINK;
-}
-
-static bool MgntDisconnect(struct net_device *dev, u8 asRsn)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	/*
-	 *	Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
-	 */
-
-	if (IS_DOT11D_ENABLE(priv->ieee80211))
-		Dot11d_Reset(priv->ieee80211);
-	/* In adhoc mode, update beacon frame. */
-	if (priv->ieee80211->state == IEEE80211_LINKED)	{
-		if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
-			MgntDisconnectIBSS(dev);
-
-		if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
-			/*
-			 *	We clear key here instead of MgntDisconnectAP()
-			 *	because that MgntActSet_802_11_DISASSOCIATE()
-			 *	is an interface called by OS, e.g.
-			 *	OID_802_11_DISASSOCIATE in Windows while as
-			 *	MgntDisconnectAP() is used to handle
-			 *	disassociation related things to AP, e.g. send
-			 *	Disassoc frame to AP.  2005.01.27, by rcnjko.
-			 */
-			MgntDisconnectAP(dev, asRsn);
-		}
-		/* Indicate Disconnect, 2005.02.23, by rcnjko.	*/
-	}
-	return true;
-}
-/*
- *	Description:
- *		Chang RF Power State.
- *		Note that, only MgntActSet_RF_State() is allowed to set
- *		HW_VAR_RF_STATE.
- *
- *	Assumption:
- *		PASSIVE LEVEL.
- */
-static bool SetRFPowerState(struct net_device *dev,
-			    enum rt_rf_power_state eRFPowerState)
-{
-	struct	r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	bool	bResult = false;
-
-	if (eRFPowerState == priv->eRFPowerState)
-		return bResult;
-
-	bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
-
-	return bResult;
-}
-
-bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet,
-			 u32 ChangeSource)
-{
-	struct	r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	bool	bActionAllowed = false;
-	bool	bConnectBySSID = false;
-	enum rt_rf_power_state rtState;
-	u16	RFWaitCounter = 0;
-	unsigned long flag;
-	/*
-	 *	Prevent the race condition of RF state change. By Bruce,
-	 *	2007-11-28. Only one thread can change the RF state at one time,
-	 *	and others should wait to be executed.
-	 */
-	while (true) {
-		spin_lock_irqsave(&priv->rf_ps_lock, flag);
-		if (priv->RFChangeInProgress) {
-			spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
-			/*  Set RF after the previous action is done.	*/
-			while (priv->RFChangeInProgress) {
-				RFWaitCounter++;
-				udelay(1000); /* 1 ms	*/
-
-				/*
-				 *	Wait too long, return FALSE to avoid
-				 *	to be stuck here.
-				 */
-				if (RFWaitCounter > 1000) { /* 1sec */
-					netdev_info(dev, "MgntActSet_RF_State(): Wait too long to set RF\n");
-					/* TODO: Reset RF state? */
-					return false;
-				}
-			}
-		} else {
-			priv->RFChangeInProgress = true;
-			spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
-			break;
-		}
-	}
-	rtState = priv->eRFPowerState;
-
-	switch (StateToSet) {
-	case RF_ON:
-		/*
-		 *	Turn On RF no matter the IPS setting because we need to
-		 *	update the RF state to Ndis under Vista, or the Windows
-		 *	does not allow the driver to perform site survey any
-		 *	more. By Bruce, 2007-10-02.
-		 */
-		priv->RfOffReason &= (~ChangeSource);
-
-		if (!priv->RfOffReason)	{
-			priv->RfOffReason = 0;
-			bActionAllowed = true;
-
-			if (rtState == RF_OFF &&
-			    ChangeSource >= RF_CHANGE_BY_HW)
-				bConnectBySSID = true;
-		}
-		break;
-
-	case RF_OFF:
-		 /* 070125, rcnjko: we always keep connected in AP mode. */
-
-		if (priv->RfOffReason > RF_CHANGE_BY_IPS) {
-			/*
-			 *	060808, Annie:
-			 *	Disconnect to current BSS when radio off.
-			 *	Asked by QuanTa.
-			 *
-			 *	Calling MgntDisconnect() instead of
-			 *	MgntActSet_802_11_DISASSOCIATE(), because
-			 *	we do NOT need to set ssid to dummy ones.
-			 */
-			MgntDisconnect(dev, disas_lv_ss);
-			/*
-			 *	Clear content of bssDesc[] and bssDesc4Query[]
-			 *	to avoid reporting old bss to UI.
-			 */
-		}
-
-		priv->RfOffReason |= ChangeSource;
-		bActionAllowed = true;
-		break;
-	case RF_SLEEP:
-		priv->RfOffReason |= ChangeSource;
-		bActionAllowed = true;
-		break;
-	default:
-		break;
-	}
-
-	if (bActionAllowed) {
-		/* Config HW to the specified mode. */
-		SetRFPowerState(dev, StateToSet);
-	}
-
-	/* Release RF spinlock	*/
-	spin_lock_irqsave(&priv->rf_ps_lock, flag);
-	priv->RFChangeInProgress = false;
-	spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
-	return bActionAllowed;
-}
-
-static void InactivePowerSave(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	/*
-	 *	This flag "bSwRfProcessing", indicates the status of IPS
-	 *	procedure, should be set if the IPS workitem is really
-	 *	scheduled. The old code, sets this flag before scheduling the
-	 *	IPS workitem and however, at the same time the previous IPS
-	 *	workitem did not end yet, fails to schedule the current
-	 *	workitem. Thus, bSwRfProcessing blocks the IPS procedure of
-	 *	switching RF.
-	 */
-	priv->bSwRfProcessing = true;
-
-	MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
-
-	/*
-	 *	To solve CAM values miss in RF OFF, rewrite CAM values after
-	 *	RF ON. By Bruce, 2007-09-20.
-	 */
-
-	priv->bSwRfProcessing = false;
-}
-
-/*
- *	Description:
- *		Enter the inactive power save mode. RF will be off
- */
-void IPSEnter(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	enum rt_rf_power_state rtState;
-	if (priv->bInactivePs) {
-		rtState = priv->eRFPowerState;
-
-		/*
-		 *	Do not enter IPS in the following conditions:
-		 *	(1) RF is already OFF or
-		 *	Sleep (2) bSwRfProcessing (indicates the IPS is still
-		 *	under going) (3) Connected (only disconnected can
-		 *	trigger IPS)(4) IBSS (send Beacon)
-		 *	(5) AP mode (send Beacon)
-		 */
-		if (rtState == RF_ON && !priv->bSwRfProcessing
-			&& (priv->ieee80211->state != IEEE80211_LINKED)) {
-			priv->eInactivePowerState = RF_OFF;
-			InactivePowerSave(dev);
-		}
-	}
-}
-void IPSLeave(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	enum rt_rf_power_state rtState;
-	if (priv->bInactivePs) {
-		rtState = priv->eRFPowerState;
-		if ((rtState == RF_OFF || rtState == RF_SLEEP) &&
-		    !priv->bSwRfProcessing
-		    && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
-			priv->eInactivePowerState = RF_ON;
-			InactivePowerSave(dev);
-		}
-	}
-}
-
-void rtl8185b_adapter_start(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee80211;
-
-	u8 SupportedWirelessMode;
-	u8 InitWirelessMode;
-	u8 bInvalidWirelessMode = 0;
-	u8 tmpu8;
-	u8 btCR9346;
-	u8 TmpU1b;
-	u8 btPSR;
-
-	write_nic_byte(dev, 0x24e, (BIT5|BIT6|BIT0));
-	rtl8180_reset(dev);
-
-	priv->dma_poll_mask = 0;
-	priv->dma_poll_stop_mask = 0;
-
-	HwConfigureRTL8185(dev);
-	write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
-	write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff);
-	/* default network type to 'No Link' */
-	write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3);
-	write_nic_word(dev, BcnItv, 100);
-	write_nic_word(dev, AtimWnd, 2);
-	PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
-	write_nic_byte(dev, WPA_CONFIG, 0);
-	MacConfig_85BASIC(dev);
-	/* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07,
-	 * by rcnjko.
-	 */
-	/* BT_DEMO_BOARD type */
-	PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
-
-	/*
-	 *---------------------------------------------------------------------
-	 *	Set up PHY related.
-	 *---------------------------------------------------------------------
-	 */
-	/* Enable Config3.PARAM_En to revise AnaaParm. */
-	write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */
-	tmpu8 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En));
-	/* Turn on Analog power. */
-	/* Asked for by William, otherwise, MAC 3-wire can't work,
-	 * 2006.06.27, by rcnjko.
-	 */
-	write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
-	write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
-	write_nic_word(dev, ANAPARAM3, 0x0010);
-
-	write_nic_byte(dev, CONFIG3, tmpu8);
-	write_nic_byte(dev, CR9346, 0x00);
-	/* enable EEM0 and EEM1 in 9346CR */
-	btCR9346 = read_nic_byte(dev, CR9346);
-	write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
-
-	/* B cut use LED1 to control HW RF on/off */
-	TmpU1b = read_nic_byte(dev, CONFIG5);
-	TmpU1b = TmpU1b & ~BIT3;
-	write_nic_byte(dev, CONFIG5, TmpU1b);
-
-	/* disable EEM0 and EEM1 in 9346CR */
-	btCR9346 &= ~(0xC0);
-	write_nic_byte(dev, CR9346, btCR9346);
-
-	/* Enable Led (suggested by Jong) */
-	/* B-cut RF Radio on/off  5e[3]=0 */
-	btPSR = read_nic_byte(dev, PSR);
-	write_nic_byte(dev, PSR, (btPSR | BIT3));
-	/* setup initial timing for RFE. */
-	write_nic_word(dev, RFPinsOutput, 0x0480);
-	SetOutputEnableOfRfPins(dev);
-	write_nic_word(dev, RFPinsSelect, 0x2488);
-
-	/* PHY config. */
-	PhyConfig8185(dev);
-
-	/*
-	 *	We assume RegWirelessMode has already been initialized before,
-	 *	however, we has to validate the wireless mode here and provide a
-	 *	reasonable initialized value if necessary. 2005.01.13,
-	 *	by rcnjko.
-	 */
-	SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
-	if ((ieee->mode != WIRELESS_MODE_B) &&
-		(ieee->mode != WIRELESS_MODE_G) &&
-		(ieee->mode != WIRELESS_MODE_A) &&
-		(ieee->mode != WIRELESS_MODE_AUTO)) {
-		/* It should be one of B, G, A, or AUTO. */
-		bInvalidWirelessMode = 1;
-	} else {
-	/* One of B, G, A, or AUTO. */
-		/* Check if the wireless mode is supported by RF. */
-		if	((ieee->mode != WIRELESS_MODE_AUTO) &&
-			(ieee->mode & SupportedWirelessMode) == 0) {
-			bInvalidWirelessMode = 1;
-		}
-	}
-
-	if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) {
-		/* Auto or other invalid value. */
-		/* Assigne a wireless mode to initialize. */
-		if ((SupportedWirelessMode & WIRELESS_MODE_A)) {
-			InitWirelessMode = WIRELESS_MODE_A;
-		} else if ((SupportedWirelessMode & WIRELESS_MODE_G)) {
-			InitWirelessMode = WIRELESS_MODE_G;
-		} else if ((SupportedWirelessMode & WIRELESS_MODE_B)) {
-			InitWirelessMode = WIRELESS_MODE_B;
-		} else {
-			DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
-				 SupportedWirelessMode);
-			InitWirelessMode = WIRELESS_MODE_B;
-		}
-
-		/* Initialize RegWirelessMode if it is not a valid one.	*/
-		if (bInvalidWirelessMode)
-			ieee->mode = (enum wireless_mode)InitWirelessMode;
-
-	} else {
-	/* One of B, G, A. */
-		InitWirelessMode = ieee->mode;
-	}
-	priv->eRFPowerState = RF_OFF;
-	priv->RfOffReason = 0;
-	{
-		MgntActSet_RF_State(dev, RF_ON, 0);
-	}
-		/*
-		 * If inactive power mode is enabled, disable rf while in
-		 * disconnected state.
-		 */
-	if (priv->bInactivePs)
-		MgntActSet_RF_State(dev , RF_OFF, RF_CHANGE_BY_IPS);
-
-	ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
-
-	/* ----------------------------------------------------------------- */
-
-	rtl8185b_irq_enable(dev);
-
-	netif_start_queue(dev);
-}
-
-void rtl8185b_rx_enable(struct net_device *dev)
-{
-	u8 cmd;
-	/* for now we accept data, management & ctl frame*/
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-
-	if (dev->flags & IFF_PROMISC)
-		DMESG("NIC in promisc mode");
-
-	if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || dev->flags &
-	    IFF_PROMISC) {
-		priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
-		priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
-	}
-
-	if (priv->ieee80211->iw_mode == IW_MODE_MONITOR)
-		priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF |
-				      RCR_APWRMGT | RCR_AICV;
-
-
-	if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
-		priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
-
-	write_nic_dword(dev, RCR, priv->ReceiveConfig);
-
-	fix_rx_fifo(dev);
-
-	cmd = read_nic_byte(dev, CMD);
-	write_nic_byte(dev, CMD, cmd | (1<<CMD_RX_ENABLE_SHIFT));
-
-}
-
-void rtl8185b_tx_enable(struct net_device *dev)
-{
-	u8 cmd;
-	u8 byte;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	write_nic_dword(dev, TCR, priv->TransmitConfig);
-	byte = read_nic_byte(dev, MSR);
-	byte |= MSR_LINK_ENEDCA;
-	write_nic_byte(dev, MSR, byte);
-
-	fix_tx_fifo(dev);
-
-	cmd = read_nic_byte(dev, CMD);
-	write_nic_byte(dev, CMD, cmd | (1<<CMD_TX_ENABLE_SHIFT));
-}
-
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 636ec55..e305d43 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -545,20 +545,18 @@
 static struct recv_frame *portctrl(struct adapter *adapter,
 				   struct recv_frame *precv_frame)
 {
-	u8   *psta_addr = NULL, *ptr;
+	u8   *psta_addr, *ptr;
 	uint  auth_alg;
 	struct recv_frame *pfhdr;
 	struct sta_info *psta;
 	struct sta_priv *pstapriv;
 	struct recv_frame *prtnframe;
-	u16	ether_type = 0;
+	u16	ether_type;
 	u16  eapol_type = 0x888e;/* for Funia BD's WPA issue */
 	struct rx_pkt_attrib *pattrib;
-	__be16 be_tmp;
 
 
 	pstapriv = &adapter->stapriv;
-	psta = rtw_get_stainfo(pstapriv, psta_addr);
 
 	auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
 
@@ -566,24 +564,23 @@
 	pfhdr = precv_frame;
 	pattrib = &pfhdr->attrib;
 	psta_addr = pattrib->ta;
+	psta = rtw_get_stainfo(pstapriv, psta_addr);
 
 	prtnframe = NULL;
 
 	RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm));
 
 	if (auth_alg == 2) {
+		/* get ether_type */
+		ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
+		memcpy(&ether_type, ptr, 2);
+		ether_type = ntohs((unsigned short)ether_type);
+
 		if ((psta != NULL) && (psta->ieee8021x_blocked)) {
 			/* blocked */
 			/* only accept EAPOL frame */
 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==1\n"));
 
-			prtnframe = precv_frame;
-
-			/* get ether_type */
-			ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
-			memcpy(&be_tmp, ptr, 2);
-			ether_type = ntohs(be_tmp);
-
 			if (ether_type == eapol_type) {
 				prtnframe = precv_frame;
 			} else {
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index 2636e7f..cf30a08 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -359,7 +359,7 @@
 		if (wpa_len > 0) {
 			p = buf;
 			_rtw_memset(buf, 0, MAX_WPA_IE_LEN);
-			p += sprintf(p, "wpa_ie =");
+			p += sprintf(p, "wpa_ie=");
 			for (i = 0; i < wpa_len; i++)
 				p += sprintf(p, "%02x", wpa_ie[i]);
 
@@ -376,7 +376,7 @@
 		if (rsn_len > 0) {
 			p = buf;
 			_rtw_memset(buf, 0, MAX_WPA_IE_LEN);
-			p += sprintf(p, "rsn_ie =");
+			p += sprintf(p, "rsn_ie=");
 			for (i = 0; i < rsn_len; i++)
 				p += sprintf(p, "%02x", rsn_ie[i]);
 			_rtw_memset(&iwe, 0, sizeof(iwe));
@@ -2899,7 +2899,7 @@
 	/*	Commented by Albert 2010/10/12 */
 	/*	Because of the output size limitation, I had removed the "Role" information. */
 	/*	About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
-	sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo));
+	sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
 	wrqu->data.length = strlen(extra);
 
 	return ret;
@@ -2918,7 +2918,7 @@
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
 
-	sprintf(extra, "\n\nCM =%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
+	sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
 	wrqu->data.length = strlen(extra);
 	return ret;
 }
@@ -2935,7 +2935,7 @@
 			pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
 			pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
 
-	sprintf(extra, "\n\nRole =%.2d\n", rtw_p2p_role(pwdinfo));
+	sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
 	wrqu->data.length = strlen(extra);
 	return ret;
 }
@@ -3022,7 +3022,7 @@
 
 	DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel);
 
-	sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel);
+	sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
 	wrqu->data.length = strlen(extra);
 	return ret;
 }
@@ -3043,7 +3043,7 @@
 	u8 blnMatch = 0;
 	u16	attr_content = 0;
 	uint attr_contentlen = 0;
-	/* 6 is the string "wpsCM =", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */
+	/* 6 is the string "wpsCM=", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */
 	u8 attr_content_str[6 + 17] = {0x00};
 
 	/*	Commented by Albert 20110727 */
@@ -3079,7 +3079,7 @@
 				rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *) &be_tmp, &attr_contentlen);
 				if (attr_contentlen) {
 					attr_content = be16_to_cpu(be_tmp);
-					sprintf(attr_content_str, "\n\nM =%.4d", attr_content);
+					sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
 					blnMatch = 1;
 				}
 			}
@@ -3091,7 +3091,7 @@
 	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
 
 	if (!blnMatch)
-		sprintf(attr_content_str, "\n\nM = 0000");
+		sprintf(attr_content_str, "\n\nM=0000");
 
 	if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17))
 		return -EFAULT;
@@ -3172,9 +3172,9 @@
 	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
 
 	if (!blnMatch)
-		snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add = NULL");
+		snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=NULL");
 	else
-		snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
+		snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
 			attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
 
 	if (copy_to_user(wrqu->data.pointer, go_devadd_str, sizeof(go_devadd_str)))
@@ -3198,7 +3198,7 @@
 	u8 blnMatch = 0;
 	u8 dev_type[8] = {0x00};
 	uint dev_type_len = 0;
-	u8 dev_type_str[17 + 9] = {0x00};	/*  +9 is for the str "dev_type =", we have to clear it at wrqu->data.pointer */
+	u8 dev_type_str[17 + 9] = {0x00};	/*  +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer */
 
 	/*	Commented by Albert 20121209 */
 	/*	The input data is the MAC address which the application wants to know its device type. */
@@ -3239,7 +3239,7 @@
 
 					memcpy(&be_tmp, dev_type, 2);
 					type = be16_to_cpu(be_tmp);
-					sprintf(dev_type_str, "\n\nN =%.2d", type);
+					sprintf(dev_type_str, "\n\nN=%.2d", type);
 					blnMatch = 1;
 				}
 			}
@@ -3252,7 +3252,7 @@
 	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
 
 	if (!blnMatch)
-		sprintf(dev_type_str, "\n\nN = 00");
+		sprintf(dev_type_str, "\n\nN=00");
 
 	if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) {
 		return -EFAULT;
@@ -3277,7 +3277,7 @@
 	u8 blnMatch = 0;
 	u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00};
 	uint dev_len = 0;
-	u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00};	/*  +5 is for the str "devN =", we have to clear it at wrqu->data.pointer */
+	u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00};	/*  +5 is for the str "devN=", we have to clear it at wrqu->data.pointer */
 
 	/*	Commented by Albert 20121225 */
 	/*	The input data is the MAC address which the application wants to know its device name. */
@@ -3310,7 +3310,7 @@
 			if (wpsie) {
 				rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
 				if (dev_len) {
-					sprintf(dev_name_str, "\n\nN =%s", dev_name);
+					sprintf(dev_name_str, "\n\nN=%s", dev_name);
 					blnMatch = 1;
 				}
 			}
@@ -3323,7 +3323,7 @@
 	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
 
 	if (!blnMatch)
-		sprintf(dev_name_str, "\n\nN = 0000");
+		sprintf(dev_name_str, "\n\nN=0000");
 
 	if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17)))
 		return -EFAULT;
@@ -3349,7 +3349,7 @@
 	u8 attr_content[2] = {0x00};
 
 	u8 inv_proc_str[17 + 8] = {0x00};
-	/*  +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */
+	/*  +8 is for the str "InvProc=", we have to clear it at wrqu->data.pointer */
 
 	/*	Commented by Ouden 20121226 */
 	/*	The application wants to know P2P initiation procedure is supported or not. */
@@ -3397,12 +3397,12 @@
 	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
 
 	if (!blnMatch) {
-		sprintf(inv_proc_str, "\nIP =-1");
+		sprintf(inv_proc_str, "\nIP=-1");
 	} else {
 		if (attr_content[0] & 0x20)
-			sprintf(inv_proc_str, "\nIP = 1");
+			sprintf(inv_proc_str, "\nIP=1");
 		else
-			sprintf(inv_proc_str, "\nIP = 0");
+			sprintf(inv_proc_str, "\nIP=0");
 	}
 	if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17))
 		return -EFAULT;
@@ -3512,7 +3512,7 @@
 	/*	The input data contains two informations. */
 	/*	1. First information is the P2P device address which you want to send to. */
 	/*	2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
-	/*	Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
+	/*	Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
 	/*	Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
 
 	DBG_88E("[%s] data = %s\n", __func__, extra);
@@ -3805,48 +3805,48 @@
 
 #ifdef CONFIG_88EU_P2P
 	DBG_88E("[%s] extra = %s\n", __func__, extra);
-	if (!memcmp(extra, "enable =", 7)) {
+	if (!memcmp(extra, "enable=", 7)) {
 		rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
-	} else if (!memcmp(extra, "setDN =", 6)) {
+	} else if (!memcmp(extra, "setDN=", 6)) {
 		wrqu->data.length -= 6;
 		rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
-	} else if (!memcmp(extra, "profilefound =", 13)) {
+	} else if (!memcmp(extra, "profilefound=", 13)) {
 		wrqu->data.length -= 13;
 		rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
-	} else if (!memcmp(extra, "prov_disc =", 10)) {
+	} else if (!memcmp(extra, "prov_disc=", 10)) {
 		wrqu->data.length -= 10;
 		rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
-	} else if (!memcmp(extra, "nego =", 5)) {
+	} else if (!memcmp(extra, "nego=", 5)) {
 		wrqu->data.length -= 5;
 		rtw_p2p_connect(dev, info, wrqu, &extra[5]);
-	} else if (!memcmp(extra, "intent =", 7)) {
+	} else if (!memcmp(extra, "intent=", 7)) {
 		/*	Commented by Albert 2011/03/23 */
 		/*	The wrqu->data.length will include the null character */
 		/*	So, we will decrease 7 + 1 */
 		wrqu->data.length -= 8;
 		rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
-	} else if (!memcmp(extra, "ssid =", 5)) {
+	} else if (!memcmp(extra, "ssid=", 5)) {
 		wrqu->data.length -= 5;
 		rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
-	} else if (!memcmp(extra, "got_wpsinfo =", 12)) {
+	} else if (!memcmp(extra, "got_wpsinfo=", 12)) {
 		wrqu->data.length -= 12;
 		rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
-	} else if (!memcmp(extra, "listen_ch =", 10)) {
+	} else if (!memcmp(extra, "listen_ch=", 10)) {
 		/*	Commented by Albert 2011/05/24 */
 		/*	The wrqu->data.length will include the null character */
 		/*	So, we will decrease (10 + 1) */
 		wrqu->data.length -= 11;
 		rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
-	} else if (!memcmp(extra, "op_ch =", 6)) {
+	} else if (!memcmp(extra, "op_ch=", 6)) {
 		/*	Commented by Albert 2011/05/24 */
 		/*	The wrqu->data.length will include the null character */
 		/*	So, we will decrease (6 + 1) */
 		wrqu->data.length -= 7;
 		rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
-	} else if (!memcmp(extra, "invite =", 7)) {
+	} else if (!memcmp(extra, "invite=", 7)) {
 		wrqu->data.length -= 8;
 		rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
-	} else if (!memcmp(extra, "persistent =", 11)) {
+	} else if (!memcmp(extra, "persistent=", 11)) {
 		wrqu->data.length -= 11;
 		rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
 	}
@@ -3887,7 +3887,7 @@
 			"group_id", 8)) {
 		rtw_p2p_get_groupid(dev, info, wrqu, extra);
 	} else if (!memcmp((__force const char *)wrqu->data.pointer,
-			"peer_deva_inv", 9)) {
+			"peer_deva_inv", 13)) {
 		/*	Get the P2P device address when receiving the P2P Invitation request frame. */
 		rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
 	} else if (!memcmp((__force const char *)wrqu->data.pointer,
@@ -6920,7 +6920,7 @@
 
 	DBG_88E("%s: in =%s\n", __func__, extra);
 
-	countPkTx = strncmp(extra, "count =", 5); /*  strncmp true is 0 */
+	countPkTx = strncmp(extra, "count=", 6); /*  strncmp true is 0 */
 	cotuTx = strncmp(extra, "background", 20);
 	CarrSprTx = strncmp(extra, "background, cs", 20);
 	scTx = strncmp(extra, "background, sc", 20);
@@ -7044,7 +7044,7 @@
 	DBG_88E("%s: %s\n", __func__, input);
 
 	bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /*  strncmp true is 0 */
-	bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /*  strncmp true is 0 */
+	bStopRx = (strncmp(input, "stop", 4) == 0) ? 1 : 0; /*  strncmp true is 0 */
 	bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /*  strncmp true is 0 */
 
 	if (bStartRx) {
diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
index 23ec684..274c359 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.c
+++ b/drivers/staging/rtl8712/rtl871x_recv.c
@@ -254,7 +254,7 @@
 	struct sta_info *psta;
 	struct	sta_priv *pstapriv;
 	union recv_frame *prtnframe;
-	u16 ether_type = 0;
+	u16 ether_type;
 
 	pstapriv = &adapter->stapriv;
 	ptr = get_recvframe_data(precv_frame);
@@ -263,15 +263,14 @@
 	psta = r8712_get_stainfo(pstapriv, psta_addr);
 	auth_alg = adapter->securitypriv.AuthAlgrthm;
 	if (auth_alg == 2) {
+		/* get ether_type */
+		ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
+		memcpy(&ether_type, ptr, 2);
+		ether_type = ntohs((unsigned short)ether_type);
+
 		if ((psta != NULL) && (psta->ieee8021x_blocked)) {
 			/* blocked
 			 * only accept EAPOL frame */
-			prtnframe = precv_frame;
-			/*get ether_type */
-			ptr = ptr + pfhdr->attrib.hdrlen +
-			      pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
-			memcpy(&ether_type, ptr, 2);
-			ether_type = ntohs((unsigned short)ether_type);
 			if (ether_type == 0x888e)
 				prtnframe = precv_frame;
 			else {
diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c
index 780631f..a48ab25 100644
--- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c
@@ -1496,45 +1496,23 @@
 int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen)
 {
 	int match;
-	uint cnt = 0;
-	u8 eid, wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A};
+	const u8 *ie;
 
-	match = false;
+	match = 0;
 
-	if (in_len < 0) {
+	if (in_len < 0)
 		return match;
-	}
 
-	while (cnt < in_len)
-	{
-		eid = in_ie[cnt];
+	ie = cfg80211_find_vendor_ie(0x506F9A, 0x0A, in_ie, in_len);
+	if (ie && (ie[1] <= (MAX_WFD_IE_LEN - 2))) {
+		if (wfd_ie) {
+			*wfd_ielen = ie[1] + 2;
+			memcpy(wfd_ie, ie, ie[1] + 2);
+		} else
+			if (wfd_ielen)
+				*wfd_ielen = 0;
 
-		if ((eid == _VENDOR_SPECIFIC_IE_) &&
-		    !memcmp(&in_ie[cnt+2], wfd_oui, 4)) {
-			if (wfd_ie != NULL) {
-				memcpy(wfd_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
-			} else {
-				if (wfd_ielen != NULL) {
-					*wfd_ielen = 0;
-				}
-			}
-
-			if (wfd_ielen != NULL) {
-				*wfd_ielen = in_ie[cnt + 1] + 2;
-			}
-
-			cnt += in_ie[cnt + 1] + 2;
-
-			match = true;
-			break;
-		} else {
-			cnt += in_ie[cnt + 1] +2; /* goto next */
-		}
-	}
-
-	if (match == true) {
-		match = cnt;
+		match = 1;
 	}
 
 	return match;
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
index 4c75363..1f3e8a0 100644
--- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
@@ -1281,7 +1281,7 @@
 	u8 p2p_status_code = P2P_STATUS_SUCCESS;
 	u8 *p2pie;
 	u32 p2pielen = 0;
-	u8	wfd_ie[ 128 ] = { 0x00 };
+	u8	wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
 	u32	wfd_ielen = 0;
 #endif /* CONFIG_8723AU_P2P */
 
diff --git a/drivers/staging/rtl8723au/core/rtw_p2p.c b/drivers/staging/rtl8723au/core/rtw_p2p.c
index 27a6cc7..1a961e3 100644
--- a/drivers/staging/rtl8723au/core/rtw_p2p.c
+++ b/drivers/staging/rtl8723au/core/rtw_p2p.c
@@ -2535,7 +2535,7 @@
 	u16		wps_devicepassword_id = 0x0000;
 	uint	wps_devicepassword_id_len = 0;
 #ifdef CONFIG_8723AU_P2P
-	u8	wfd_ie[ 128 ] = { 0x00 };
+	u8	wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
 	u32	wfd_ielen = 0;
 #endif /*  CONFIG_8723AU_P2P */
 
@@ -2741,7 +2741,7 @@
 	u32 ies_len;
 	u8 * p2p_ie;
 #ifdef CONFIG_8723AU_P2P
-	u8	wfd_ie[ 128 ] = { 0x00 };
+	u8	wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
 	u32	wfd_ielen = 0;
 #endif /*  CONFIG_8723AU_P2P */
 
diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
index 0dfcfbc..99d81e6 100644
--- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
@@ -570,7 +570,7 @@
 int WFD_info_handler(struct rtw_adapter *padapter, struct ndis_802_11_var_ies *	pIE)
 {
 	struct wifidirect_info	*pwdinfo;
-	u8	wfd_ie[128] = {0x00};
+	u8	wfd_ie[MAX_WFD_IE_LEN] = {0x00};
 	u32	wfd_ielen = 0;
 
 	pwdinfo = &padapter->wdinfo;
@@ -681,7 +681,7 @@
 	inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
 
 	if (pregpriv->wifi_spec == 1) {
-		u32	j, tmp, change_inx;
+		u32	j, tmp, change_inx = false;
 
 		/* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
 		for (i = 0; i < 4; i++) {
diff --git a/drivers/staging/rtl8821ae/base.c b/drivers/staging/rtl8821ae/base.c
index e5073fe..a4c9cc4 100644
--- a/drivers/staging/rtl8821ae/base.c
+++ b/drivers/staging/rtl8821ae/base.c
@@ -388,7 +388,7 @@
 
 }
 
-static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
+static int _rtl_init_deferred_work(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
@@ -410,6 +410,9 @@
 	rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name);
 #endif
 /*<delete in kernel end>*/
+	if (!rtlpriv->works.rtl_wq)
+		return -ENOMEM;
+
 	INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
 			  (void *)rtl_watchdog_wq_callback);
 	INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
@@ -421,6 +424,8 @@
 	INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq,
 			  (void *)rtl_fwevt_wq_callback);
 
+	return 0;
+
 }
 
 void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
@@ -519,7 +524,8 @@
 	INIT_LIST_HEAD(&rtlpriv->entry_list);
 
 	/* <6> init deferred work */
-	_rtl_init_deferred_work(hw);
+	if (_rtl_init_deferred_work(hw))
+		return 1;
 
 	/* <7> */
 #ifdef VIF_TODO
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index ef5933b..3b6e535 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -1855,8 +1855,9 @@
 {
 	static u_char goto_buf[8];
 	static int num;
-	int maxlen, go_pos;
+	int maxlen;
 	char *cp;
+
 	if (type == KT_SPKUP && ch == SPEAKUP_GOTO)
 		goto do_goto;
 	if (type == KT_LATIN && ch == '\n')
@@ -1891,25 +1892,24 @@
 		spk_special_handler = NULL;
 		return 1;
 	}
-	go_pos = kstrtol(goto_buf, 10, (long *)&cp);
-	goto_pos = (u_long) go_pos;
+
+	goto_pos = simple_strtoul(goto_buf, &cp, 10);
+
 	if (*cp == 'x') {
 		if (*goto_buf < '0')
 			goto_pos += spk_x;
-		else
+		else if (goto_pos > 0)
 			goto_pos--;
-		if (goto_pos < 0)
-			goto_pos = 0;
+
 		if (goto_pos >= vc->vc_cols)
 			goto_pos = vc->vc_cols - 1;
 		goto_x = 1;
 	} else {
 		if (*goto_buf < '0')
 			goto_pos += spk_y;
-		else
+		else if (goto_pos > 0)
 			goto_pos--;
-		if (goto_pos < 0)
-			goto_pos = 0;
+
 		if (goto_pos >= vc->vc_rows)
 			goto_pos = vc->vc_rows - 1;
 		goto_x = 0;
diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c
index 8ea9c46..3152a21 100644
--- a/drivers/staging/unisys/uislib/uislib.c
+++ b/drivers/staging/unisys/uislib/uislib.c
@@ -381,17 +381,17 @@
 		cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid;
 		cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid;
 		if (!VirtControlChanFunc) {
-			kfree(bus);
 			LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
 			POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
 					 POSTCODE_SEVERITY_ERR);
+			kfree(bus);
 			return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
 		}
 		if (!VirtControlChanFunc(&cmd)) {
-			kfree(bus);
 			LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
 			POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
 					 POSTCODE_SEVERITY_ERR);
+			kfree(bus);
 			return
 			    CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
 		}
diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h
index d4bf203..d95825d 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset.h
@@ -104,9 +104,9 @@
 
 static inline void delbusdevices(struct list_head *list, U32 busNo)
 {
-	VISORCHIPSET_DEVICE_INFO *p;
+	VISORCHIPSET_DEVICE_INFO *p, *tmp;
 
-	list_for_each_entry(p, list, entry) {
+	list_for_each_entry_safe(p, tmp, list, entry) {
 		if (p->busNo == busNo) {
 			list_del(&p->entry);
 			kfree(p);
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c
index 257c6e5..c475e25 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_main.c
+++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c
@@ -605,16 +605,16 @@
 static void
 cleanup_controlvm_structures(void)
 {
-	VISORCHIPSET_BUS_INFO *bi;
-	VISORCHIPSET_DEVICE_INFO *di;
+	VISORCHIPSET_BUS_INFO *bi, *tmp_bi;
+	VISORCHIPSET_DEVICE_INFO *di, *tmp_di;
 
-	list_for_each_entry(bi, &BusInfoList, entry) {
+	list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) {
 		busInfo_clear(bi);
 		list_del(&bi->entry);
 		kfree(bi);
 	}
 
-	list_for_each_entry(di, &DevInfoList, entry) {
+	list_for_each_entry_safe(di, tmp_di, &DevInfoList, entry) {
 		devInfo_clear(di);
 		list_del(&di->entry);
 		kfree(di);
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
index c5bf60b..92caef7 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
@@ -118,6 +118,7 @@
 	struct udev_list_entry *devices, *dev_list_entry;
 	struct udev_device *dev;
 	const char *path;
+	const char *driver;
 
 	enumerate = udev_enumerate_new(udev_context);
 	udev_enumerate_add_match_subsystem(enumerate, "usb");
@@ -128,10 +129,12 @@
 	udev_list_entry_foreach(dev_list_entry, devices) {
 		path = udev_list_entry_get_name(dev_list_entry);
 		dev = udev_device_new_from_syspath(udev_context, path);
+		if (dev == NULL)
+			continue;
 
 		/* Check whether device uses usbip-host driver. */
-		if (!strcmp(udev_device_get_driver(dev),
-			    USBIP_HOST_DRV_NAME)) {
+		driver = udev_device_get_driver(dev);
+		if (driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME)) {
 			edev = usbip_exported_device_new(path);
 			if (!edev) {
 				dbg("usbip_exported_device_new failed");
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index 47bddcd..211f43f 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -184,7 +184,7 @@
 	 * @devid: unique device identifier in a remote host
 	 * @speed: usb device speed in a remote host
 	 */
-	if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 1)
+	if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4)
 		return -EINVAL;
 
 	usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n",
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 7927927..ffb4eee 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -776,7 +776,8 @@
 		image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
 		if (image[i].kern_buf == NULL) {
 			err = -ENOMEM;
-			goto err_master_buf;
+			vme_master_free(image[i].resource);
+			goto err_master;
 		}
 	}
 
@@ -819,8 +820,6 @@
 
 	return 0;
 
-	/* Ensure counter set correcty to destroy all sysfs devices */
-	i = VME_DEVS;
 err_sysfs:
 	while (i > 0) {
 		i--;
@@ -830,12 +829,10 @@
 
 	/* Ensure counter set correcty to unalloc all master windows */
 	i = MASTER_MAX + 1;
-err_master_buf:
-	for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
-		kfree(image[i].kern_buf);
 err_master:
 	while (i > MASTER_MINOR) {
 		i--;
+		kfree(image[i].kern_buf);
 		vme_master_free(image[i].resource);
 	}
 
diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h
index 5c739be..949f0e5 100644
--- a/drivers/staging/xgifb/vb_def.h
+++ b/drivers/staging/xgifb/vb_def.h
@@ -1,6 +1,6 @@
 #ifndef _VB_DEF_
 #define _VB_DEF_
-#include "../../video/sis/initdef.h"
+#include "../../video/fbdev/sis/initdef.h"
 
 #define VB_XGI301C      0x0020 /* for 301C */
 
diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h
index c08ff5b..0d27594 100644
--- a/drivers/staging/xgifb/vb_struct.h
+++ b/drivers/staging/xgifb/vb_struct.h
@@ -1,6 +1,6 @@
 #ifndef _VB_STRUCT_
 #define _VB_STRUCT_
-#include "../../video/sis/vstruct.h"
+#include "../../video/fbdev/sis/vstruct.h"
 
 struct XGI_LVDSCRT1HDataStruct {
 	unsigned char Reg[8];
diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h
index ddf7776..2643514 100644
--- a/drivers/staging/xgifb/vgatypes.h
+++ b/drivers/staging/xgifb/vgatypes.h
@@ -2,8 +2,8 @@
 #define _VGATYPES_
 
 #include <linux/fb.h>	/* for struct fb_var_screeninfo for sis.h */
-#include "../../video/sis/vgatypes.h"
-#include "../../video/sis/sis.h"		/* for LCD_TYPE */
+#include "../../video/fbdev/sis/vgatypes.h"
+#include "../../video/fbdev/sis/sis.h"		/* for LCD_TYPE */
 
 #ifndef XGI_VB_CHIP_TYPE
 enum XGI_VB_CHIP_TYPE {
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2e6d8dd..5d9b01a 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1226,6 +1226,7 @@
 config SERIAL_TIMBERDALE
 	tristate "Support for timberdale UART"
 	select SERIAL_CORE
+	depends on X86_32 || COMPILE_TEST
 	---help---
 	Add support for UART controller on timberdale.
 
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index d4eda24..dacf0a0 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -318,7 +318,7 @@
 			.src_addr = uap->port.mapbase + UART01x_DR,
 			.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
 			.direction = DMA_DEV_TO_MEM,
-			.src_maxburst = uap->fifosize >> 1,
+			.src_maxburst = uap->fifosize >> 2,
 			.device_fc = false,
 		};
 
@@ -2176,6 +2176,7 @@
 static int pl011_remove(struct amba_device *dev)
 {
 	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	bool busy = false;
 	int i;
 
 	uart_remove_one_port(&amba_reg, &uap->port);
@@ -2183,9 +2184,12 @@
 	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
 		if (amba_ports[i] == uap)
 			amba_ports[i] = NULL;
+		else if (amba_ports[i])
+			busy = true;
 
 	pl011_dma_remove(uap);
-	uart_unregister_driver(&amba_reg);
+	if (!busy)
+		uart_unregister_driver(&amba_reg);
 	return 0;
 }
 
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index 5e6fdb1..14aaea0 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -368,16 +368,12 @@
 static void uart_clps711x_console_putchar(struct uart_port *port, int ch)
 {
 	struct clps711x_port *s = dev_get_drvdata(port->dev);
+	u32 sysflg = 0;
 
 	/* Wait for FIFO is not full */
-	while (1) {
-		u32 sysflg = 0;
-
+	do {
 		regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
-		if (!(sysflg & SYSFLG_UTXFF))
-			break;
-		cond_resched();
-	}
+	} while (sysflg & SYSFLG_UTXFF);
 
 	writew(ch, port->membase + UARTDR_OFFSET);
 }
@@ -387,18 +383,14 @@
 {
 	struct uart_port *port = clps711x_uart.state[co->index].uart_port;
 	struct clps711x_port *s = dev_get_drvdata(port->dev);
+	u32 sysflg = 0;
 
 	uart_console_write(port, c, n, uart_clps711x_console_putchar);
 
 	/* Wait for transmitter to become empty */
-	while (1) {
-		u32 sysflg = 0;
-
+	do {
 		regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
-		if (!(sysflg & SYSFLG_UBUSY))
-			break;
-		cond_resched();
-	}
+	} while (sysflg & SYSFLG_UBUSY);
 }
 
 static int uart_clps711x_console_setup(struct console *co, char *options)
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c
index 028582e..c167a71 100644
--- a/drivers/tty/serial/efm32-uart.c
+++ b/drivers/tty/serial/efm32-uart.c
@@ -798,6 +798,9 @@
 
 static const struct of_device_id efm32_uart_dt_ids[] = {
 	{
+		.compatible = "energymicro,efm32-uart",
+	}, {
+		/* doesn't follow the "vendor,device" scheme, don't use */
 		.compatible = "efm32,uart",
 	}, {
 		/* sentinel */
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index dd8b1a5..08b6b94 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -225,14 +225,19 @@
 	if (enable)
 		enable_irq(up->wakeirq);
 	else
-		disable_irq(up->wakeirq);
+		disable_irq_nosync(up->wakeirq);
 }
 
 static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
 {
 	struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
 
+	if (enable == up->wakeups_enabled)
+		return;
+
 	serial_omap_enable_wakeirq(up, enable);
+	up->wakeups_enabled = enable;
+
 	if (!pdata || !pdata->enable_wakeup)
 		return;
 
@@ -1495,6 +1500,11 @@
 	uart_suspend_port(&serial_omap_reg, &up->port);
 	flush_work(&up->qos_work);
 
+	if (device_may_wakeup(dev))
+		serial_omap_enable_wakeup(up, true);
+	else
+		serial_omap_enable_wakeup(up, false);
+
 	return 0;
 }
 
@@ -1502,6 +1512,9 @@
 {
 	struct uart_omap_port *up = dev_get_drvdata(dev);
 
+	if (device_may_wakeup(dev))
+		serial_omap_enable_wakeup(up, false);
+
 	uart_resume_port(&serial_omap_reg, &up->port);
 
 	return 0;
@@ -1789,6 +1802,7 @@
 	pm_runtime_disable(up->dev);
 	uart_remove_one_port(&serial_omap_reg, &up->port);
 	pm_qos_remove_request(&up->pm_qos_request);
+	device_init_wakeup(&dev->dev, false);
 
 	return 0;
 }
@@ -1877,17 +1891,7 @@
 
 	up->context_loss_cnt = serial_omap_get_context_loss_count(up);
 
-	if (device_may_wakeup(dev)) {
-		if (!up->wakeups_enabled) {
-			serial_omap_enable_wakeup(up, true);
-			up->wakeups_enabled = true;
-		}
-	} else {
-		if (up->wakeups_enabled) {
-			serial_omap_enable_wakeup(up, false);
-			up->wakeups_enabled = false;
-		}
-	}
+	serial_omap_enable_wakeup(up, true);
 
 	up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
 	schedule_work(&up->qos_work);
@@ -1901,6 +1905,8 @@
 
 	int loss_cnt = serial_omap_get_context_loss_count(up);
 
+	serial_omap_enable_wakeup(up, false);
+
 	if (loss_cnt < 0) {
 		dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n",
 			loss_cnt);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 2cf5649..f26834d2 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -89,8 +89,7 @@
 	struct uart_state *state = tty->driver_data;
 	struct uart_port *port = state->uart_port;
 
-	if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
-	    !tty->stopped && !tty->hw_stopped)
+	if (!tty->stopped && !tty->hw_stopped)
 		port->ops->start_tx(port);
 }
 
@@ -1452,6 +1451,8 @@
 		clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
 		spin_unlock_irqrestore(&port->lock, flags);
 		tty_port_tty_set(port, NULL);
+		if (!uart_console(state->uart_port))
+			uart_change_pm(state, UART_PM_STATE_OFF);
 		wake_up_interruptible(&port->open_wait);
 		wake_up_interruptible(&port->delta_msr_wait);
 	}
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index 21e6e84..dd3a96e 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -295,7 +295,7 @@
 			status & ASC_STA_OE) {
 
 			if (c & ASC_RXBUF_FE) {
-				if (c == ASC_RXBUF_FE) {
+				if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) {
 					port->icount.brk++;
 					if (uart_handle_break(port))
 						continue;
@@ -325,7 +325,7 @@
 				flag = TTY_FRAME;
 		}
 
-		if (uart_handle_sysrq_char(port, c))
+		if (uart_handle_sysrq_char(port, c & 0xff))
 			continue;
 
 		uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index d3448a9..3411071 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -878,9 +878,8 @@
 	spin_lock_irq(&current->sighand->siglock);
 	put_pid(current->signal->tty_old_pgrp);
 	current->signal->tty_old_pgrp = NULL;
-	spin_unlock_irq(&current->sighand->siglock);
 
-	tty = get_current_tty();
+	tty = tty_kref_get(current->signal->tty);
 	if (tty) {
 		unsigned long flags;
 		spin_lock_irqsave(&tty->ctrl_lock, flags);
@@ -897,6 +896,7 @@
 #endif
 	}
 
+	spin_unlock_irq(&current->sighand->siglock);
 	/* Now clear signal->tty under the lock */
 	read_lock(&tasklist_lock);
 	session_clear_tty(task_session(current));
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 900f7ff..904efb6 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -518,13 +518,16 @@
 	if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
 		dev_err(&acm->control->dev,
 			"%s - usb_submit_urb(ctrl irq) failed\n", __func__);
+		usb_autopm_put_interface(acm->control);
 		goto error_submit_urb;
 	}
 
 	acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS;
 	if (acm_set_control(acm, acm->ctrlout) < 0 &&
-	    (acm->ctrl_caps & USB_CDC_CAP_LINE))
+	    (acm->ctrl_caps & USB_CDC_CAP_LINE)) {
+		usb_autopm_put_interface(acm->control);
 		goto error_set_control;
+	}
 
 	usb_autopm_put_interface(acm->control);
 
@@ -549,7 +552,6 @@
 error_set_control:
 	usb_kill_urb(acm->ctrlurb);
 error_submit_urb:
-	usb_autopm_put_interface(acm->control);
 error_get_interface:
 disconnected:
 	mutex_unlock(&acm->mutex);
@@ -1652,13 +1654,27 @@
 	},
 	/* Motorola H24 HSPA module: */
 	{ USB_DEVICE(0x22b8, 0x2d91) }, /* modem                                */
-	{ USB_DEVICE(0x22b8, 0x2d92) }, /* modem           + diagnostics        */
-	{ USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port                      */
-	{ USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics        */
-	{ USB_DEVICE(0x22b8, 0x2d96) }, /* modem                         + NMEA */
-	{ USB_DEVICE(0x22b8, 0x2d97) }, /* modem           + diagnostics + NMEA */
-	{ USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port               + NMEA */
-	{ USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */
+	{ USB_DEVICE(0x22b8, 0x2d92),   /* modem           + diagnostics        */
+	.driver_info = NO_UNION_NORMAL, /* handle only modem interface          */
+	},
+	{ USB_DEVICE(0x22b8, 0x2d93),   /* modem + AT port                      */
+	.driver_info = NO_UNION_NORMAL, /* handle only modem interface          */
+	},
+	{ USB_DEVICE(0x22b8, 0x2d95),   /* modem + AT port + diagnostics        */
+	.driver_info = NO_UNION_NORMAL, /* handle only modem interface          */
+	},
+	{ USB_DEVICE(0x22b8, 0x2d96),   /* modem                         + NMEA */
+	.driver_info = NO_UNION_NORMAL, /* handle only modem interface          */
+	},
+	{ USB_DEVICE(0x22b8, 0x2d97),   /* modem           + diagnostics + NMEA */
+	.driver_info = NO_UNION_NORMAL, /* handle only modem interface          */
+	},
+	{ USB_DEVICE(0x22b8, 0x2d99),   /* modem + AT port               + NMEA */
+	.driver_info = NO_UNION_NORMAL, /* handle only modem interface          */
+	},
+	{ USB_DEVICE(0x22b8, 0x2d9a),   /* modem + AT port + diagnostics + NMEA */
+	.driver_info = NO_UNION_NORMAL, /* handle only modem interface          */
+	},
 
 	{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
 	.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index d59d993..1f02e65 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -75,7 +75,7 @@
 				PCI_SLOT(companion->devfn) != slot)
 			continue;
 		companion_hcd = pci_get_drvdata(companion);
-		if (!companion_hcd)
+		if (!companion_hcd || !companion_hcd->self.root_hub)
 			continue;
 		fn(pdev, hcd, companion, companion_hcd);
 	}
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index d1d8c47..7f425ac 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -212,6 +212,8 @@
 	int rc;
 
 	rc = ehci_suspend(hcd, do_wakeup);
+	if (rc)
+		return rc;
 
 	if (exynos_ehci->otg)
 		exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index b3a0e11..c7dd93a 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -303,6 +303,8 @@
 	int ret;
 
 	ret = ehci_suspend(hcd, do_wakeup);
+	if (ret)
+		return ret;
 
 	if (pdata->power_suspend)
 		pdata->power_suspend(pdev);
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 27ac6ad..7ef00ec 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -509,8 +509,31 @@
 	}
 };
 
+static int tegra_ehci_reset(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval;
+	int txfifothresh;
+
+	retval = ehci_setup(hcd);
+	if (retval)
+		return retval;
+
+	/*
+	 * We should really pull this value out of tegra_ehci_soc_config, but
+	 * to avoid needing access to it, make use of the fact that Tegra20 is
+	 * the only one so far that needs a value of 10, and Tegra20 is the
+	 * only one which doesn't set has_hostpc.
+	 */
+	txfifothresh = ehci->has_hostpc ? 0x10 : 10;
+	ehci_writel(ehci, txfifothresh << 16, &ehci->regs->txfill_tuning);
+
+	return 0;
+}
+
 static const struct ehci_driver_overrides tegra_overrides __initconst = {
 	.extra_priv_size	= sizeof(struct tegra_ehci_hcd),
+	.reset			= tegra_ehci_reset,
 };
 
 static int __init ehci_tegra_init(void)
diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c
index af8dc1b..c2c221a 100644
--- a/drivers/usb/host/ohci-jz4740.c
+++ b/drivers/usb/host/ohci-jz4740.c
@@ -82,14 +82,14 @@
 	u16 wIndex, char *buf, u16 wLength)
 {
 	struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd);
-	int ret;
+	int ret = 0;
 
 	switch (typeReq) {
-	case SetHubFeature:
+	case SetPortFeature:
 		if (wValue == USB_PORT_FEAT_POWER)
 			ret = ohci_jz4740_set_vbus_power(jz4740_ohci, true);
 		break;
-	case ClearHubFeature:
+	case ClearPortFeature:
 		if (wValue == USB_PORT_FEAT_POWER)
 			ret = ohci_jz4740_set_vbus_power(jz4740_ohci, false);
 		break;
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 95fa121..762e4a5 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -104,6 +104,7 @@
 	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
 	{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
 	{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
+	{ USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
 	{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
 	{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
 	{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 44ab129..7c6e1de 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -909,6 +909,39 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) },
 	/* Cressi Devices */
 	{ USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) },
+	/* Brainboxes Devices */
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_001_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_012_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_023_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_034_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_101_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_1_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_2_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_3_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_4_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_5_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_6_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_7_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_8_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_257_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_1_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_2_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_3_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_4_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_313_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_324_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_1_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_2_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_357_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_1_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_2_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_3_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_1_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_2_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_1_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) },
+	{ USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) },
 	{ }					/* Terminating entry */
 };
 
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index e599fbf..993c93d 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -1326,3 +1326,40 @@
  * Manufacturer: Cressi
  */
 #define FTDI_CRESSI_PID		0x87d0
+
+/*
+ * Brainboxes devices
+ */
+#define BRAINBOXES_VID			0x05d1
+#define BRAINBOXES_VX_001_PID		0x1001 /* VX-001 ExpressCard 1 Port RS232 */
+#define BRAINBOXES_VX_012_PID		0x1002 /* VX-012 ExpressCard 2 Port RS232 */
+#define BRAINBOXES_VX_023_PID		0x1003 /* VX-023 ExpressCard 1 Port RS422/485 */
+#define BRAINBOXES_VX_034_PID		0x1004 /* VX-034 ExpressCard 2 Port RS422/485 */
+#define BRAINBOXES_US_101_PID		0x1011 /* US-101 1xRS232 */
+#define BRAINBOXES_US_324_PID		0x1013 /* US-324 1xRS422/485 1Mbaud */
+#define BRAINBOXES_US_606_1_PID		0x2001 /* US-606 6 Port RS232 Serial Port 1 and 2 */
+#define BRAINBOXES_US_606_2_PID		0x2002 /* US-606 6 Port RS232 Serial Port 3 and 4 */
+#define BRAINBOXES_US_606_3_PID		0x2003 /* US-606 6 Port RS232 Serial Port 4 and 6 */
+#define BRAINBOXES_US_701_1_PID		0x2011 /* US-701 4xRS232 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_701_2_PID		0x2012 /* US-701 4xRS422 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_279_1_PID		0x2021 /* US-279 8xRS422 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_279_2_PID		0x2022 /* US-279 8xRS422 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_279_3_PID		0x2023 /* US-279 8xRS422 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_279_4_PID		0x2024 /* US-279 8xRS422 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_346_1_PID		0x3011 /* US-346 4xRS422/485 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_346_2_PID		0x3012 /* US-346 4xRS422/485 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_257_PID		0x5001 /* US-257 2xRS232 1Mbaud */
+#define BRAINBOXES_US_313_PID		0x6001 /* US-313 2xRS422/485 1Mbaud */
+#define BRAINBOXES_US_357_PID		0x7001 /* US_357 1xRS232/422/485 */
+#define BRAINBOXES_US_842_1_PID		0x8001 /* US-842 8xRS422/485 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_842_2_PID		0x8002 /* US-842 8xRS422/485 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_842_3_PID		0x8003 /* US-842 8xRS422/485 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_842_4_PID		0x8004 /* US-842 8xRS422/485 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_160_1_PID		0x9001 /* US-160 16xRS232 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_160_2_PID		0x9002 /* US-160 16xRS232 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_160_3_PID		0x9003 /* US-160 16xRS232 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_160_4_PID		0x9004 /* US-160 16xRS232 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_160_5_PID		0x9005 /* US-160 16xRS232 1Mbaud Port 9 and 10 */
+#define BRAINBOXES_US_160_6_PID		0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */
+#define BRAINBOXES_US_160_7_PID		0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */
+#define BRAINBOXES_US_160_8_PID		0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 68fc9fe..367c7f0 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -243,6 +243,7 @@
 #define TELIT_PRODUCT_CC864_DUAL		0x1005
 #define TELIT_PRODUCT_CC864_SINGLE		0x1006
 #define TELIT_PRODUCT_DE910_DUAL		0x1010
+#define TELIT_PRODUCT_UE910_V2			0x1012
 #define TELIT_PRODUCT_LE920			0x1200
 
 /* ZTE PRODUCTS */
@@ -1041,6 +1042,7 @@
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
+	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
 		.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 2e22fc2..b3d5a35 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -83,6 +83,9 @@
 	{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
 	{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+	{ USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) },
+	{ USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
+	{ USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) },
 	{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
 	{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index c38b8c0..42bc082 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -121,8 +121,11 @@
 #define SUPERIAL_VENDOR_ID	0x5372
 #define SUPERIAL_PRODUCT_ID	0x2303
 
-/* Hewlett-Packard LD220-HP POS Pole Display */
+/* Hewlett-Packard POS Pole Displays */
 #define HP_VENDOR_ID		0x03f0
+#define HP_LD960_PRODUCT_ID	0x0b39
+#define HP_LCM220_PRODUCT_ID	0x3139
+#define HP_LCM960_PRODUCT_ID	0x3239
 #define HP_LD220_PRODUCT_ID	0x3524
 
 /* Cressi Edy (diving computer) PC interface */
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index a9eb6221..6b192e6 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -291,7 +291,6 @@
 	{ USB_DEVICE(0x0f3d, 0x68A3), 	/* Airprime/Sierra Wireless Direct IP modems */
 	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
 	},
-       { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */
 
 	{ }
 };
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 640fe01..b078440 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -466,6 +466,9 @@
 	int err;
 	int i;
 
+	if (!port->bulk_in_size || !port->bulk_out_size)
+		return -ENODEV;
+
 	portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
 	if (!portdata)
 		return -ENOMEM;
@@ -473,9 +476,6 @@
 	init_usb_anchor(&portdata->delayed);
 
 	for (i = 0; i < N_IN_URB; i++) {
-		if (!port->bulk_in_size)
-			break;
-
 		buffer = (u8 *)__get_free_page(GFP_KERNEL);
 		if (!buffer)
 			goto bail_out_error;
@@ -489,9 +489,6 @@
 	}
 
 	for (i = 0; i < N_OUT_URB; i++) {
-		if (!port->bulk_out_size)
-			break;
-
 		buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
 		if (!buffer)
 			goto bail_out_error2;
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index a7ac97c..511b229 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -137,7 +137,7 @@
 		if (!(cmdinfo->state & IS_IN_WORK_LIST))
 			continue;
 
-		err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
+		err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
 		if (!err)
 			cmdinfo->state &= ~IS_IN_WORK_LIST;
 		else
@@ -803,7 +803,7 @@
 
 	devinfo->running_task = 1;
 	memset(&devinfo->response, 0, sizeof(devinfo->response));
-	sense_urb = uas_submit_sense_urb(cmnd, GFP_NOIO,
+	sense_urb = uas_submit_sense_urb(cmnd, GFP_ATOMIC,
 					 devinfo->use_streams ? tag : 0);
 	if (!sense_urb) {
 		shost_printk(KERN_INFO, shost,
@@ -813,7 +813,7 @@
 		spin_unlock_irqrestore(&devinfo->lock, flags);
 		return FAILED;
 	}
-	if (uas_submit_task_urb(cmnd, GFP_NOIO, function, tag)) {
+	if (uas_submit_task_urb(cmnd, GFP_ATOMIC, function, tag)) {
 		shost_printk(KERN_INFO, shost,
 			     "%s: %s: submit task mgmt urb failed\n",
 			     __func__, fname);
@@ -1030,7 +1030,7 @@
 		devinfo->use_streams = 0;
 	} else {
 		devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1,
-						    3, 256, GFP_KERNEL);
+						    3, 256, GFP_NOIO);
 		if (devinfo->qdepth < 0)
 			return devinfo->qdepth;
 		devinfo->use_streams = 1;
@@ -1047,7 +1047,7 @@
 	eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
 	eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
 	eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
-	usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL);
+	usb_free_streams(devinfo->intf, eps, 3, GFP_NOIO);
 }
 
 static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1096,16 +1096,17 @@
 	if (result)
 		goto free_streams;
 
+	usb_set_intfdata(intf, shost);
 	result = scsi_add_host(shost, &intf->dev);
 	if (result)
 		goto free_streams;
 
 	scsi_scan_host(shost);
-	usb_set_intfdata(intf, shost);
 	return result;
 
 free_streams:
 	uas_free_streams(devinfo);
+	usb_set_intfdata(intf, NULL);
 set_alt0:
 	usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
 	if (shost)
diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c
index d771870a..6dfd30a 100644
--- a/drivers/usb/usb-common.c
+++ b/drivers/usb/usb-common.c
@@ -69,7 +69,7 @@
 		[USB_STATE_RECONNECTING] = "reconnecting",
 		[USB_STATE_UNAUTHENTICATED] = "unauthenticated",
 		[USB_STATE_DEFAULT] = "default",
-		[USB_STATE_ADDRESS] = "addresssed",
+		[USB_STATE_ADDRESS] = "addressed",
 		[USB_STATE_CONFIGURED] = "configured",
 		[USB_STATE_SUSPENDED] = "suspended",
 	};
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 16ada83..1a2fd97 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -599,8 +599,11 @@
 
 	/* alloc and initialize new uwb_cnflt_alien */
 	cnflt = kzalloc(sizeof(struct uwb_cnflt_alien), GFP_KERNEL);
-	if (!cnflt)
+	if (!cnflt) {
 		dev_err(dev, "failed to alloc uwb_cnflt_alien struct\n");
+		return;
+	}
+
 	INIT_LIST_HEAD(&cnflt->rc_node);
 	init_timer(&cnflt->timer);
 	cnflt->timer.function = uwb_cnflt_timer;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6c793bc..c7b4f0f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -21,7 +21,15 @@
 
 source "drivers/gpu/host1x/Kconfig"
 
+menu "Direct Rendering Manager"
 source "drivers/gpu/drm/Kconfig"
+endmenu
+
+menu "Frame buffer Devices"
+source "drivers/video/fbdev/Kconfig"
+endmenu
+
+source "drivers/video/backlight/Kconfig"
 
 config VGASTATE
        tristate
@@ -33,2482 +41,14 @@
 config HDMI
 	bool
 
-menuconfig FB
-	tristate "Support for frame buffer devices"
-	---help---
-	  The frame buffer device provides an abstraction for the graphics
-	  hardware. It represents the frame buffer of some video hardware and
-	  allows application software to access the graphics hardware through
-	  a well-defined interface, so the software doesn't need to know
-	  anything about the low-level (hardware register) stuff.
-
-	  Frame buffer devices work identically across the different
-	  architectures supported by Linux and make the implementation of
-	  application programs easier and more portable; at this point, an X
-	  server exists which uses the frame buffer device exclusively.
-	  On several non-X86 architectures, the frame buffer device is the
-	  only way to use the graphics hardware.
-
-	  The device is accessed through special device nodes, usually located
-	  in the /dev directory, i.e. /dev/fb*.
-
-	  You need an utility program called fbset to make full use of frame
-	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
-	  and the Framebuffer-HOWTO at
-	  <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more
-	  information.
-
-	  Say Y here and to the driver for your graphics board below if you
-	  are compiling a kernel for a non-x86 architecture.
-
-	  If you are compiling for the x86 architecture, you can say Y if you
-	  want to play with it, but it is not essential. Please note that
-	  running graphical applications that directly touch the hardware
-	  (e.g. an accelerated X server) and that are not frame buffer
-	  device-aware may cause unexpected results. If unsure, say N.
-
-config FIRMWARE_EDID
-       bool "Enable firmware EDID"
-       depends on FB
-       default n
-       ---help---
-         This enables access to the EDID transferred from the firmware.
-	 On the i386, this is from the Video BIOS. Enable this if DDC/I2C
-	 transfers do not work for your driver and if you are using
-	 nvidiafb, i810fb or savagefb.
-
-	 In general, choosing Y for this option is safe.  If you
-	 experience extremely long delays while booting before you get
-	 something on your display, try setting this to N.  Matrox cards in
-	 combination with certain motherboards and monitors are known to
-	 suffer from this problem.
-
-config FB_DDC
-       tristate
-       depends on FB
-       select I2C_ALGOBIT
-       select I2C
-       default n
-
-config FB_BOOT_VESA_SUPPORT
-	bool
-	depends on FB
-	default n
-	---help---
-	  If true, at least one selected framebuffer driver can take advantage
-	  of VESA video modes set at an early boot stage via the vga= parameter.
-
-config FB_CFB_FILLRECT
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Include the cfb_fillrect function for generic software rectangle
-	  filling. This is used by drivers that don't provide their own
-	  (accelerated) version.
-
-config FB_CFB_COPYAREA
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Include the cfb_copyarea function for generic software area copying.
-	  This is used by drivers that don't provide their own (accelerated)
-	  version.
-
-config FB_CFB_IMAGEBLIT
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Include the cfb_imageblit function for generic software image
-	  blitting. This is used by drivers that don't provide their own
-	  (accelerated) version.
-
-config FB_CFB_REV_PIXELS_IN_BYTE
-	bool
-	depends on FB
-	default n
-	---help---
-	  Allow generic frame-buffer functions to work on displays with 1, 2
-	  and 4 bits per pixel depths which has opposite order of pixels in
-	  byte order to bytes in long order.
-
-config FB_SYS_FILLRECT
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Include the sys_fillrect function for generic software rectangle
-	  filling. This is used by drivers that don't provide their own
-	  (accelerated) version and the framebuffer is in system RAM.
-
-config FB_SYS_COPYAREA
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Include the sys_copyarea function for generic software area copying.
-	  This is used by drivers that don't provide their own (accelerated)
-	  version and the framebuffer is in system RAM.
-
-config FB_SYS_IMAGEBLIT
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Include the sys_imageblit function for generic software image
-	  blitting. This is used by drivers that don't provide their own
-	  (accelerated) version and the framebuffer is in system RAM.
-
-menuconfig FB_FOREIGN_ENDIAN
-	bool "Framebuffer foreign endianness support"
-	depends on FB
-	---help---
-	  This menu will let you enable support for the framebuffers with
-	  non-native endianness (e.g. Little-Endian framebuffer on a
-	  Big-Endian machine). Most probably you don't have such hardware,
-	  so it's safe to say "n" here.
-
-choice
-	prompt "Choice endianness support"
-	depends on FB_FOREIGN_ENDIAN
-
-config FB_BOTH_ENDIAN
-	bool "Support for Big- and Little-Endian framebuffers"
-
-config FB_BIG_ENDIAN
-	bool "Support for Big-Endian framebuffers only"
-
-config FB_LITTLE_ENDIAN
-	bool "Support for Little-Endian framebuffers only"
-
-endchoice
-
-config FB_SYS_FOPS
-       tristate
-       depends on FB
-       default n
-
-config FB_DEFERRED_IO
-	bool
-	depends on FB
-
-config FB_HECUBA
-	tristate
-	depends on FB
-	depends on FB_DEFERRED_IO
-
-config FB_SVGALIB
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Common utility functions useful to fbdev drivers of VGA-based
-	  cards.
-
-config FB_MACMODES
-       tristate
-       depends on FB
-       default n
-
-config FB_BACKLIGHT
-	bool
-	depends on FB
-	select BACKLIGHT_LCD_SUPPORT
-	select BACKLIGHT_CLASS_DEVICE
-	default n
-
-config FB_MODE_HELPERS
-        bool "Enable Video Mode Handling Helpers"
-        depends on FB
-	default n
-	---help---
-	  This enables functions for handling video modes using the
-	  Generalized Timing Formula and the EDID parser. A few drivers rely
-          on this feature such as the radeonfb, rivafb, and the i810fb. If
-	  your driver does not take advantage of this feature, choosing Y will
-	  just increase the kernel size by about 5K.
-
-config FB_TILEBLITTING
-       bool "Enable Tile Blitting Support"
-       depends on FB
-       default n
-       ---help---
-         This enables tile blitting.  Tile blitting is a drawing technique
-	 where the screen is divided into rectangular sections (tiles), whereas
-	 the standard blitting divides the screen into pixels. Because the
-	 default drawing element is a tile, drawing functions will be passed
-	 parameters in terms of number of tiles instead of number of pixels.
-	 For example, to draw a single character, instead of using bitmaps,
-	 an index to an array of bitmaps will be used.  To clear or move a
-	 rectangular section of a screen, the rectangle will be described in
-	 terms of number of tiles in the x- and y-axis.
-
-	 This is particularly important to one driver, matroxfb.  If
-	 unsure, say N.
-
-comment "Frame buffer hardware drivers"
-	depends on FB
-
-config FB_GRVGA
-	tristate "Aeroflex Gaisler framebuffer support"
-	depends on FB && SPARC
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
-
-config FB_CIRRUS
-	tristate "Cirrus Logic support"
-	depends on FB && (ZORRO || PCI)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  This enables support for Cirrus Logic GD542x/543x based boards on
-	  Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
-
-	  If you have a PCI-based system, this enables support for these
-	  chips: GD-543x, GD-544x, GD-5480.
-
-	  Please read the file <file:Documentation/fb/cirrusfb.txt>.
-
-	  Say N unless you have such a graphics board or plan to get one
-	  before you next recompile the kernel.
-
-config FB_PM2
-	tristate "Permedia2 support"
-	depends on FB && ((AMIGA && BROKEN) || PCI)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for cards based on
-	  the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
-	  The driver was tested on the following cards:
-		Diamond FireGL 1000 PRO AGP
-		ELSA Gloria Synergy PCI
-		Appian Jeronimo PRO (both heads) PCI
-		3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
-		Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
-		ASK Graphic Blaster Exxtreme AGP
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pm2fb.
-
-config FB_PM2_FIFO_DISCONNECT
-	bool "enable FIFO disconnect feature"
-	depends on FB_PM2 && PCI
-	help
-	  Support the Permedia2 FIFO disconnect feature.
-
-config FB_ARMCLCD
-	tristate "ARM PrimeCell PL110 support"
-	depends on ARM || ARM64 || COMPILE_TEST
-	depends on FB && ARM_AMBA
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This framebuffer device driver is for the ARM PrimeCell PL110
-	  Colour LCD controller.  ARM PrimeCells provide the building
-	  blocks for System on a Chip devices.
-
-	  If you want to compile this as a module (=code which can be
-	  inserted into and removed from the running kernel), say M
-	  here and read <file:Documentation/kbuild/modules.txt>.  The module
-	  will be called amba-clcd.
-
-config FB_ACORN
-	bool "Acorn VIDC support"
-	depends on (FB = y) && ARM && ARCH_ACORN
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the Acorn VIDC graphics
-	  hardware found in Acorn RISC PCs and other ARM-based machines.  If
-	  unsure, say N.
-
-config FB_CLPS711X
-	bool "CLPS711X LCD support"
-	depends on (FB = y) && ARM && ARCH_CLPS711X
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  Say Y to enable the Framebuffer driver for the CLPS7111 and
-	  EP7212 processors.
-
-config FB_SA1100
-	bool "SA-1100 LCD support"
-	depends on (FB = y) && ARM && ARCH_SA1100
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is a framebuffer device for the SA-1100 LCD Controller.
-	  See <http://www.linux-fbdev.org/> for information on framebuffer
-	  devices.
-
-	  If you plan to use the LCD display with your SA-1100 system, say
-	  Y here.
-
-config FB_IMX
-	tristate "Freescale i.MX1/21/25/27 LCD support"
-	depends on FB && ARCH_MXC
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MODE_HELPERS
-	select VIDEOMODE_HELPERS
-
-config FB_CYBER2000
-	tristate "CyberPro 2000/2010/5000 support"
-	depends on FB && PCI && (BROKEN || !SPARC64)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This enables support for the Integraphics CyberPro 20x0 and 5000
-	  VGA chips used in the Rebel.com Netwinder and other machines.
-	  Say Y if you have a NetWinder or a graphics card containing this
-	  device, otherwise say N.
-
-config FB_CYBER2000_DDC
-	bool "DDC for CyberPro support"
-	depends on FB_CYBER2000
-	select FB_DDC
-	default y
-	help
-	  Say Y here if you want DDC support for your CyberPro graphics
-	  card. This is only I2C bus support, driver does not use EDID.
-
-config FB_CYBER2000_I2C
-	bool "CyberPro 2000/2010/5000 I2C support"
-	depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
-	select I2C_ALGOBIT
-	help
-	  Enable support for the I2C video decoder interface on the
-	  Integraphics CyberPro 20x0 and 5000 VGA chips.  This is used
-	  on the Netwinder machines for the SAA7111 video capture.
-
-config FB_APOLLO
-	bool
-	depends on (FB = y) && APOLLO
-	default y
-	select FB_CFB_FILLRECT
-	select FB_CFB_IMAGEBLIT
-
-config FB_Q40
-	bool
-	depends on (FB = y) && Q40
-	default y
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-
-config FB_AMIGA
-	tristate "Amiga native chipset support"
-	depends on FB && AMIGA
-	help
-	  This is the frame buffer device driver for the builtin graphics
-	  chipset found in Amigas.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called amifb.
-
-config FB_AMIGA_OCS
-	bool "Amiga OCS chipset support"
-	depends on FB_AMIGA
-	help
-	  This enables support for the original Agnus and Denise video chips,
-	  found in the Amiga 1000 and most A500's and A2000's. If you intend
-	  to run Linux on any of these systems, say Y; otherwise say N.
-
-config FB_AMIGA_ECS
-	bool "Amiga ECS chipset support"
-	depends on FB_AMIGA
-	help
-	  This enables support for the Enhanced Chip Set, found in later
-	  A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
-	  you intend to run Linux on any of these systems, say Y; otherwise
-	  say N.
-
-config FB_AMIGA_AGA
-	bool "Amiga AGA chipset support"
-	depends on FB_AMIGA
-	help
-	  This enables support for the Advanced Graphics Architecture (also
-	  known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
-	  and CD32. If you intend to run Linux on any of these systems, say Y;
-	  otherwise say N.
-
-config FB_FM2
-	bool "Amiga FrameMaster II/Rainbow II support"
-	depends on (FB = y) && ZORRO
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the Amiga FrameMaster
-	  card from BSC (exhibited 1992 but not shipped as a CBM product).
-
-config FB_ARC
-	tristate "Arc Monochrome LCD board support"
-	depends on FB && X86
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	help
-	  This enables support for the Arc Monochrome LCD board. The board
-	  is based on the KS-108 lcd controller and is typically a matrix
-	  of 2*n chips. This driver was tested with a 128x64 panel. This
-	  driver supports it for use with x86 SBCs through a 16 bit GPIO
-	  interface (8 bit data, 8 bit control). If you anticipate using
-	  this driver, say Y or M; otherwise say N. You must specify the
-	  GPIO IO address to be used for setting control and data.
-
-config FB_ATARI
-	bool "Atari native chipset support"
-	depends on (FB = y) && ATARI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the builtin graphics
-	  chipset found in Ataris.
-
-config FB_OF
-	bool "Open Firmware frame buffer device support"
-	depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MACMODES
-	help
-	  Say Y if you want support with Open Firmware for your graphics
-	  board.
-
-config FB_CONTROL
-	bool "Apple \"control\" display support"
-	depends on (FB = y) && PPC_PMAC && PPC32
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MACMODES
-	help
-	  This driver supports a frame buffer for the graphics adapter in the
-	  Power Macintosh 7300 and others.
-
-config FB_PLATINUM
-	bool "Apple \"platinum\" display support"
-	depends on (FB = y) && PPC_PMAC && PPC32
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MACMODES
-	help
-	  This driver supports a frame buffer for the "platinum" graphics
-	  adapter in some Power Macintoshes.
-
-config FB_VALKYRIE
-	bool "Apple \"valkyrie\" display support"
-	depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MACMODES
-	help
-	  This driver supports a frame buffer for the "valkyrie" graphics
-	  adapter in some Power Macintoshes.
-
-config FB_CT65550
-	bool "Chips 65550 display support"
-	depends on (FB = y) && PPC32 && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the Chips & Technologies
-	  65550 graphics chip in PowerBooks.
-
-config FB_ASILIANT
-	bool "Asiliant (Chips) 69000 display support"
-	depends on (FB = y) && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the Asiliant 69030 chipset
-
-config FB_IMSTT
-	bool "IMS Twin Turbo display support"
-	depends on (FB = y) && PCI
-	select FB_CFB_IMAGEBLIT
-	select FB_MACMODES if PPC
-	help
-	  The IMS Twin Turbo is a PCI-based frame buffer card bundled with
-	  many Macintosh and compatible computers.
-
-config FB_VGA16
-	tristate "VGA 16-color graphics support"
-	depends on FB && (X86 || PPC)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select VGASTATE
-	select FONT_8x16 if FRAMEBUFFER_CONSOLE
-	help
-	  This is the frame buffer device driver for VGA 16 color graphic
-	  cards. Say Y if you have such a card.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called vga16fb.
-
-config FB_BF54X_LQ043
-	tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
-	depends on FB && (BF54x) && !BF542
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	 This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
-
-config FB_BFIN_T350MCQB
-	tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)"
-	depends on FB && BLACKFIN
-	select BFIN_GPTIMERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	 This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD
-	 This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
-	 It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
-
-config FB_BFIN_LQ035Q1
-	tristate "SHARP LQ035Q1DH02 TFT LCD"
-	depends on FB && BLACKFIN && SPI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select BFIN_GPTIMERS
-	help
-	  This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on
-	  the Blackfin Landscape LCD EZ-Extender Card.
-	  This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI
-	  It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called bfin-lq035q1-fb.
-
-config FB_BF537_LQ035
-	tristate "SHARP LQ035 TFT LCD (BF537 STAMP)"
-	depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select BFIN_GPTIMERS
-	help
-	  This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD
-	  attached to a BF537.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called bf537-lq035.
-
-config FB_BFIN_7393
-	tristate "Blackfin ADV7393 Video encoder"
-	depends on FB && BLACKFIN
-	select I2C
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the framebuffer device for a ADV7393 video encoder
-	  attached to a Blackfin on the PPI port.
-	  If your Blackfin board has a ADV7393 select Y.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called bfin_adv7393fb.
-
-choice
-	prompt  "Video mode support"
-	depends on FB_BFIN_7393
-	default NTSC
-
-config NTSC
-	bool 'NTSC 720x480'
-
-config PAL
-	bool 'PAL 720x576'
-
-config NTSC_640x480
-	bool 'NTSC 640x480 (Experimental)'
-
-config PAL_640x480
-	bool 'PAL 640x480 (Experimental)'
-
-config NTSC_YCBCR
-	bool 'NTSC 720x480 YCbCR input'
-
-config PAL_YCBCR
-	bool 'PAL 720x576 YCbCR input'
-
-endchoice
-
-choice
-	prompt  "Size of ADV7393 frame buffer memory Single/Double Size"
-	depends on (FB_BFIN_7393)
-	default ADV7393_1XMEM
-
-config ADV7393_1XMEM
-	bool 'Single'
-
-config ADV7393_2XMEM
-	bool 'Double'
-endchoice
-
-config FB_STI
-	tristate "HP STI frame buffer device support"
-	depends on FB && PARISC
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select STI_CONSOLE
-	select VT
-	default y
-	---help---
-	  STI refers to the HP "Standard Text Interface" which is a set of
-	  BIOS routines contained in a ROM chip in HP PA-RISC based machines.
-	  Enabling this option will implement the linux framebuffer device
-	  using calls to the STI BIOS routines for initialisation.
-	
-	  If you enable this option, you will get a planar framebuffer device
-	  /dev/fb which will work on the most common HP graphic cards of the
-	  NGLE family, including the artist chips (in the 7xx and Bxxx series),
-	  HCRX, HCRX24, CRX, CRX24 and VisEG series.
-
-	  It is safe to enable this option, so you should probably say "Y".
-
-config FB_MAC
-	bool "Generic Macintosh display support"
-	depends on (FB = y) && MAC
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MACMODES
-
-config FB_HP300
-	bool
-	depends on (FB = y) && DIO
-	select FB_CFB_IMAGEBLIT
-	default y
-
-config FB_TGA
-	tristate "TGA/SFB+ framebuffer support"
-	depends on FB && (ALPHA || TC)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select BITREVERSE
-	---help---
-	  This is the frame buffer device driver for generic TGA and SFB+
-	  graphic cards.  These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
-	  also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
-	  TURBOchannel cards, also known as PMAGD-A, -B and -C.
-
-	  Due to hardware limitations ZLX-E2 and E3 cards are not supported
-	  for DECstation 5000/200 systems.  Additionally due to firmware
-	  limitations these cards may cause troubles with booting DECstation
-	  5000/240 and /260 systems, but are fully supported under Linux if
-	  you manage to get it going. ;-)
-
-	  Say Y if you have one of those.
-
-config FB_UVESA
-	tristate "Userspace VESA VGA graphics support"
-	depends on FB && CONNECTOR
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MODE_HELPERS
-	help
-	  This is the frame buffer driver for generic VBE 2.0 compliant
-	  graphic cards. It can also take advantage of VBE 3.0 features,
-	  such as refresh rate adjustment.
-
-	  This driver generally provides more features than vesafb but
-	  requires a userspace helper application called 'v86d'. See
-	  <file:Documentation/fb/uvesafb.txt> for more information.
-
-	  If unsure, say N.
-
-config FB_VESA
-	bool "VESA VGA graphics support"
-	depends on (FB = y) && X86
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_BOOT_VESA_SUPPORT
-	help
-	  This is the frame buffer device driver for generic VESA 2.0
-	  compliant graphic cards. The older VESA 1.2 cards are not supported.
-	  You will get a boot time penguin logo at no additional cost. Please
-	  read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
-
-config FB_EFI
-	bool "EFI-based Framebuffer Support"
-	depends on (FB = y) && X86 && EFI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the EFI frame buffer device driver. If the firmware on
-	  your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
-	  using the EFI framebuffer as your console.
-
-config FB_N411
-       tristate "N411 Apollo/Hecuba devkit support"
-       depends on FB && X86 && MMU
-       select FB_SYS_FILLRECT
-       select FB_SYS_COPYAREA
-       select FB_SYS_IMAGEBLIT
-       select FB_SYS_FOPS
-       select FB_DEFERRED_IO
-       select FB_HECUBA
-       help
-         This enables support for the Apollo display controller in its
-         Hecuba form using the n411 devkit.
-
-config FB_HGA
-	tristate "Hercules mono graphics support"
-	depends on FB && X86
-	help
-	  Say Y here if you have a Hercules mono graphics card.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called hgafb.
-
-	  As this card technology is at least 25 years old,
-	  most people will answer N here.
-
-config FB_GBE
-	bool "SGI Graphics Backend frame buffer support"
-	depends on (FB = y) && SGI_IP32
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
- 	help
-	  This is the frame buffer device driver for SGI Graphics Backend.
-	  This chip is used in SGI O2 and Visual Workstation 320/540.
-
-config FB_GBE_MEM
-	int "Video memory size in MB"
-	depends on FB_GBE
-	default 4
-	help
-	  This is the amount of memory reserved for the framebuffer,
-	  which can be any value between 1MB and 8MB.
-
-config FB_SBUS
-	bool "SBUS and UPA framebuffers"
-	depends on (FB = y) && SPARC
-	help
-	  Say Y if you want support for SBUS or UPA based frame buffer device.
-
-config FB_BW2
-	bool "BWtwo support"
-	depends on (FB = y) && (SPARC && FB_SBUS)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the BWtwo frame buffer.
-
-config FB_CG3
-	bool "CGthree support"
-	depends on (FB = y) && (SPARC && FB_SBUS)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the CGthree frame buffer.
-
-config FB_CG6
-	bool "CGsix (GX,TurboGX) support"
-	depends on (FB = y) && (SPARC && FB_SBUS)
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the CGsix (GX, TurboGX)
-	  frame buffer.
-
-config FB_FFB
-	bool "Creator/Creator3D/Elite3D support"
-	depends on FB_SBUS && SPARC64
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the Creator, Creator3D,
-	  and Elite3D graphics boards.
-
-config FB_TCX
-	bool "TCX (SS4/SS5 only) support"
-	depends on FB_SBUS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the TCX 24/8bit frame
-	  buffer.
-
-config FB_CG14
-	bool "CGfourteen (SX) support"
-	depends on FB_SBUS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the CGfourteen frame
-	  buffer on Desktop SPARCsystems with the SX graphics option.
-
-config FB_P9100
-	bool "P9100 (Sparcbook 3 only) support"
-	depends on FB_SBUS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the P9100 card
-	  supported on Sparcbook 3 machines.
-
-config FB_LEO
-	bool "Leo (ZX) support"
-	depends on FB_SBUS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the SBUS-based Sun ZX
-	  (leo) frame buffer cards.
-
-config FB_IGA
-	bool "IGA 168x display support"
-	depends on (FB = y) && SPARC32
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the framebuffer device for the INTERGRAPHICS 1680 and
-	  successor frame buffer cards.
-
-config FB_XVR500
-	bool "Sun XVR-500 3DLABS Wildcat support"
-	depends on (FB = y) && PCI && SPARC64
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the framebuffer device for the Sun XVR-500 and similar
-	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-	  only works on sparc64 systems where the system firmware has
-	  mostly initialized the card already.  It is treated as a
-	  completely dumb framebuffer device.
-
-config FB_XVR2500
-	bool "Sun XVR-2500 3DLABS Wildcat support"
-	depends on (FB = y) && PCI && SPARC64
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the framebuffer device for the Sun XVR-2500 and similar
-	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-	  only works on sparc64 systems where the system firmware has
-	  mostly initialized the card already.  It is treated as a
-	  completely dumb framebuffer device.
-
-config FB_XVR1000
-	bool "Sun XVR-1000 support"
-	depends on (FB = y) && SPARC64
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the framebuffer device for the Sun XVR-1000 and similar
-	  graphics cards.  The driver only works on sparc64 systems where
-	  the system firmware has mostly initialized the card already.  It
-	  is treated as a completely dumb framebuffer device.
-
-config FB_PVR2
-	tristate "NEC PowerVR 2 display support"
-	depends on FB && SH_DREAMCAST
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Say Y here if you have a PowerVR 2 card in your box.  If you plan to
-	  run linux on your Dreamcast, you will have to say Y here.
-	  This driver may or may not work on other PowerVR 2 cards, but is
-	  totally untested.  Use at your own risk.  If unsure, say N.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pvr2fb.
-
-	  You can pass several parameters to the driver at boot time or at
-	  module load time.  The parameters look like "video=pvr2:XXX", where
-	  the meaning of XXX can be found at the end of the main source file
-	  (<file:drivers/video/pvr2fb.c>). Please see the file
-	  <file:Documentation/fb/pvr2fb.txt>.
-
-config FB_OPENCORES
-	tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
-	depends on FB && HAS_DMA
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This enables support for the OpenCores VGA/LCD core.
-
-	  The OpenCores VGA/LCD core is typically used together with
-	  softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor
-	  systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs.
-
-	  The source code and specification for the core is available at
-	  <http://opencores.org/project,vga_lcd>
-
-config FB_S1D13XXX
-	tristate "Epson S1D13XXX framebuffer support"
-	depends on FB
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  Support for S1D13XXX framebuffer device family (currently only
-	  working with S1D13806). Product specs at
-	  <http://vdc.epson.com/>
-
-config FB_ATMEL
-	tristate "AT91/AT32 LCD Controller support"
-	depends on FB && HAVE_FB_ATMEL
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MODE_HELPERS
-	select VIDEOMODE_HELPERS
-	help
-	  This enables support for the AT91/AT32 LCD Controller.
-
-config FB_INTSRAM
-	bool "Frame Buffer in internal SRAM"
-	depends on FB_ATMEL && ARCH_AT91SAM9261
-	help
-	  Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
-	  to let frame buffer in external SDRAM.
-
-config FB_ATMEL_STN
-	bool "Use a STN display with AT91/AT32 LCD Controller"
-	depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
-	default n
-	help
-	  Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
-	  Controller. Say N if you want to connect a TFT.
-
-	  If unsure, say N.
-
-config FB_NVIDIA
-	tristate "nVidia Framebuffer Support"
-	depends on FB && PCI
-	select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select BITREVERSE
-	select VGASTATE
-	help
-	  This driver supports graphics boards with the nVidia chips, TNT
-	  and newer. For very old chipsets, such as the RIVA128, then use
-	  the rivafb.
-	  Say Y if you have such a graphics board.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called nvidiafb.
-
-config FB_NVIDIA_I2C
-       bool "Enable DDC Support"
-       depends on FB_NVIDIA
-       select FB_DDC
-       help
-	  This enables I2C support for nVidia Chipsets.  This is used
-	  only for getting EDID information from the attached display
-	  allowing for robust video mode handling and switching.
-
-	  Because fbdev-2.6 requires that drivers must be able to
-	  independently validate video mode parameters, you should say Y
-	  here.
-
-config FB_NVIDIA_DEBUG
-	bool "Lots of debug output"
-	depends on FB_NVIDIA
-	default n
-	help
-	  Say Y here if you want the nVidia driver to output all sorts
-	  of debugging information to provide to the maintainer when
-	  something goes wrong.
-
-config FB_NVIDIA_BACKLIGHT
-	bool "Support for backlight control"
-	depends on FB_NVIDIA
-	default y
-	help
-	  Say Y here if you want to control the backlight of your display.
-
-config FB_RIVA
-	tristate "nVidia Riva support"
-	depends on FB && PCI
-	select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select BITREVERSE
-	select VGASTATE
-	help
-	  This driver supports graphics boards with the nVidia Riva/Geforce
-	  chips.
-	  Say Y if you have such a graphics board.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called rivafb.
-
-config FB_RIVA_I2C
-       bool "Enable DDC Support"
-       depends on FB_RIVA
-       select FB_DDC
-       help
-	  This enables I2C support for nVidia Chipsets.  This is used
-	  only for getting EDID information from the attached display
-	  allowing for robust video mode handling and switching.
-
-	  Because fbdev-2.6 requires that drivers must be able to
-	  independently validate video mode parameters, you should say Y
-	  here.
-
-config FB_RIVA_DEBUG
-	bool "Lots of debug output"
-	depends on FB_RIVA
-	default n
-	help
-	  Say Y here if you want the Riva driver to output all sorts
-	  of debugging information to provide to the maintainer when
-	  something goes wrong.
-
-config FB_RIVA_BACKLIGHT
-	bool "Support for backlight control"
-	depends on FB_RIVA
-	default y
-	help
-	  Say Y here if you want to control the backlight of your display.
-
-config FB_I740
-	tristate "Intel740 support"
-	depends on FB && PCI
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select VGASTATE
-	select FB_DDC
-	help
-	  This driver supports graphics cards based on Intel740 chip.
-
-config FB_I810
-	tristate "Intel 810/815 support"
-	depends on FB && PCI && X86_32 && AGP_INTEL
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select VGASTATE
-	help
-	  This driver supports the on-board graphics built in to the Intel 810 
-          and 815 chipsets.  Say Y if you have and plan to use such a board.
-
-          To compile this driver as a module, choose M here: the
-	  module will be called i810fb.
-
-          For more information, please read 
-	  <file:Documentation/fb/intel810.txt>
-
-config FB_I810_GTF
-	bool "use VESA Generalized Timing Formula"
-	depends on FB_I810
-	help
-	  If you say Y, then the VESA standard, Generalized Timing Formula 
-          or GTF, will be used to calculate the required video timing values
-	  per video mode.  Since the GTF allows nondiscrete timings 
-          (nondiscrete being a range of values as opposed to discrete being a
-          set of values), you'll be able to use any combination of horizontal 
-	  and vertical resolutions, and vertical refresh rates without having
-	  to specify your own timing parameters.  This is especially useful
-	  to maximize the performance of an aging display, or if you just 
-          have a display with nonstandard dimensions. A VESA compliant 
-	  monitor is recommended, but can still work with non-compliant ones.
-	  If you need or want this, then select this option. The timings may 
-	  not be compliant with Intel's recommended values. Use at your own 
-	  risk.
-
-          If you say N, the driver will revert to discrete video timings 
-	  using a set recommended by Intel in their documentation.
-  
-          If unsure, say N.
-
-config FB_I810_I2C
-	bool "Enable DDC Support"
-	depends on FB_I810 && FB_I810_GTF
-	select FB_DDC
-	help
-
-config FB_LE80578
-	tristate "Intel LE80578 (Vermilion) support"
-	depends on FB && PCI && X86
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This driver supports the LE80578 (Vermilion Range) chipset
-
-config FB_CARILLO_RANCH
-	tristate "Intel Carillo Ranch support"
-	depends on FB_LE80578 && FB && PCI && X86
-	help
-	  This driver supports the LE80578 (Carillo Ranch) board
-
-config FB_INTEL
-	tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
-	depends on FB && PCI && X86 && AGP_INTEL && EXPERT
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_BOOT_VESA_SUPPORT if FB_INTEL = y
-	depends on !DRM_I915
-	help
-	  This driver supports the on-board graphics built in to the Intel
-          830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
-          Say Y if you have and plan to use such a board.
-
-	  To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called intelfb.
-
-	  For more information, please read <file:Documentation/fb/intelfb.txt>
-
-config FB_INTEL_DEBUG
-	bool "Intel driver Debug Messages"
-	depends on FB_INTEL
-	---help---
-	  Say Y here if you want the Intel driver to output all sorts
-	  of debugging information to provide to the maintainer when
-	  something goes wrong.
-
-config FB_INTEL_I2C
-	bool "DDC/I2C for Intel framebuffer support"
-	depends on FB_INTEL
-	select FB_DDC
-	default y
-	help
-	  Say Y here if you want DDC/I2C support for your on-board Intel graphics.
-
-config FB_MATROX
-	tristate "Matrox acceleration"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_TILEBLITTING
-	select FB_MACMODES if PPC_PMAC
-	---help---
-	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
-	  Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
-	  Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
-	  Matrox G400, G450 or G550 card in your box.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called matroxfb.
-
-	  You can pass several parameters to the driver at boot time or at
-	  module load time. The parameters look like "video=matroxfb:XXX", and
-	  are described in <file:Documentation/fb/matroxfb.txt>.
-
-config FB_MATROX_MILLENIUM
-	bool "Millennium I/II support"
-	depends on FB_MATROX
-	help
-	  Say Y here if you have a Matrox Millennium or Matrox Millennium II
-	  video card. If you select "Advanced lowlevel driver options" below,
-	  you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
-	  packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
-	  also use font widths different from 8.
-
-config FB_MATROX_MYSTIQUE
-	bool "Mystique support"
-	depends on FB_MATROX
-	help
-	  Say Y here if you have a Matrox Mystique or Matrox Mystique 220
-	  video card. If you select "Advanced lowlevel driver options" below,
-	  you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
-	  packed pixel and 32 bpp packed pixel. You can also use font widths
-	  different from 8.
-
-config FB_MATROX_G
-	bool "G100/G200/G400/G450/G550 support"
-	depends on FB_MATROX
-	---help---
-	  Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
-	  video card. If you select "Advanced lowlevel driver options", you
-	  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
-	  pixel and 32 bpp packed pixel. You can also use font widths
-	  different from 8.
-
-	  If you need support for G400 secondary head, you must say Y to
-	  "Matrox I2C support" and "G400 second head support" right below.
-	  G450/G550 secondary head and digital output are supported without
-	  additional modules.
-
-	  The driver starts in monitor mode. You must use the matroxset tool 
-	  (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to 
-	  swap primary and secondary head outputs, or to change output mode.  
-	  Secondary head driver always start in 640x480 resolution and you 
-	  must use fbset to change it.
-
-	  Do not forget that second head supports only 16 and 32 bpp
-	  packed pixels, so it is a good idea to compile them into the kernel
-	  too. You can use only some font widths, as the driver uses generic
-	  painting procedures (the secondary head does not use acceleration
-	  engine).
-
-	  G450/G550 hardware can display TV picture only from secondary CRTC,
-	  and it performs no scaling, so picture must have 525 or 625 lines.
-
-config FB_MATROX_I2C
-	tristate "Matrox I2C support"
-	depends on FB_MATROX
-	select FB_DDC
-	---help---
-	  This drivers creates I2C buses which are needed for accessing the
-	  DDC (I2C) bus present on all Matroxes, an I2C bus which
-	  interconnects Matrox optional devices, like MGA-TVO on G200 and
-	  G400, and the secondary head DDC bus, present on G400 only.
-
-	  You can say Y or M here if you want to experiment with monitor
-	  detection code. You must say Y or M here if you want to use either
-	  second head of G400 or MGA-TVO on G200 or G400.
-
-	  If you compile it as module, it will create a module named
-	  i2c-matroxfb.
-
-config FB_MATROX_MAVEN
-	tristate "G400 second head support"
-	depends on FB_MATROX_G && FB_MATROX_I2C
-	---help---
-	  WARNING !!! This support does not work with G450 !!!
-
-	  Say Y or M here if you want to use a secondary head (meaning two
-	  monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary
-	  head is not compatible with accelerated XFree 3.3.x SVGA servers -
-	  secondary head output is blanked while you are in X. With XFree
-	  3.9.17 preview you can use both heads if you use SVGA over fbdev or
-	  the fbdev driver on first head and the fbdev driver on second head.
-
-	  If you compile it as module, two modules are created,
-	  matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
-	  both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
-	  also load i2c-matroxfb to get it to run.
-
-	  The driver starts in monitor mode and you must use the matroxset
-	  tool (available at
-	  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
-	  PAL or NTSC or to swap primary and secondary head outputs.
-	  Secondary head driver also always start in 640x480 resolution, you
-	  must use fbset to change it.
-
-	  Also do not forget that second head supports only 16 and 32 bpp
-	  packed pixels, so it is a good idea to compile them into the kernel
-	  too.  You can use only some font widths, as the driver uses generic
-	  painting procedures (the secondary head does not use acceleration
-	  engine).
-
-config FB_RADEON
-	tristate "ATI Radeon display support"
-	depends on FB && PCI
-	select FB_BACKLIGHT if FB_RADEON_BACKLIGHT
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MACMODES if PPC_OF
-	help
-	  Choose this option if you want to use an ATI Radeon graphics card as
-	  a framebuffer device.  There are both PCI and AGP versions.  You
-	  don't need to choose this to run the Radeon in plain VGA mode.
-
-	  There is a product page at
-	  http://products.amd.com/en-us/GraphicCardResult.aspx
-
-config FB_RADEON_I2C
-	bool "DDC/I2C for ATI Radeon support"
-	depends on FB_RADEON
-	select FB_DDC
-	default y
-	help
-	  Say Y here if you want DDC/I2C support for your Radeon board. 
-
-config FB_RADEON_BACKLIGHT
-	bool "Support for backlight control"
-	depends on FB_RADEON
-	default y
-	help
-	  Say Y here if you want to control the backlight of your display.
-
-config FB_RADEON_DEBUG
-	bool "Lots of debug output from Radeon driver"
-	depends on FB_RADEON
-	default n
-	help
-	  Say Y here if you want the Radeon driver to output all sorts
-	  of debugging information to provide to the maintainer when
-	  something goes wrong.
-
-config FB_ATY128
-	tristate "ATI Rage128 display support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
-	select FB_MACMODES if PPC_PMAC
-	help
-	  This driver supports graphics boards with the ATI Rage128 chips.
-	  Say Y if you have such a graphics board and read
-	  <file:Documentation/fb/aty128fb.txt>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called aty128fb.
-
-config FB_ATY128_BACKLIGHT
-	bool "Support for backlight control"
-	depends on FB_ATY128
-	default y
-	help
-	  Say Y here if you want to control the backlight of your display.
-
-config FB_ATY
-	tristate "ATI Mach64 display support" if PCI || ATARI
-	depends on FB && !SPARC32
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_BACKLIGHT if FB_ATY_BACKLIGHT
-	select FB_MACMODES if PPC
-	help
-	  This driver supports graphics boards with the ATI Mach64 chips.
-	  Say Y if you have such a graphics board.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called atyfb.
-
-config FB_ATY_CT
-	bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
-	depends on PCI && FB_ATY
-	default y if SPARC64 && PCI
-	help
-	  Say Y here to support use of ATI's 64-bit Rage boards (or other
-	  boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
-	  framebuffer device.  The ATI product support page for these boards
-	  is at <http://support.ati.com/products/pc/mach64/mach64.html>.
-
-config FB_ATY_GENERIC_LCD
-	bool "Mach64 generic LCD support"
-	depends on FB_ATY_CT
-	help
-	  Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
-	  Rage XC, or Rage XL chipset.
-
-config FB_ATY_GX
-	bool "Mach64 GX support" if PCI
-	depends on FB_ATY
-	default y if ATARI
-	help
-	  Say Y here to support use of the ATI Mach64 Graphics Expression
-	  board (or other boards based on the Mach64 GX chipset) as a
-	  framebuffer device.  The ATI product support page for these boards
-	  is at
-	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
-
-config FB_ATY_BACKLIGHT
-	bool "Support for backlight control"
-	depends on FB_ATY
-	default y
-	help
-	  Say Y here if you want to control the backlight of your display.
-
-config FB_S3
-	tristate "S3 Trio/Virge support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_TILEBLITTING
-	select FB_SVGALIB
-	select VGASTATE
-	select FONT_8x16 if FRAMEBUFFER_CONSOLE
-	---help---
-	  Driver for graphics boards with S3 Trio / S3 Virge chip.
-
-config FB_S3_DDC
-	bool "DDC for S3 support"
-	depends on FB_S3
-	select FB_DDC
-	default y
-	help
-	  Say Y here if you want DDC support for your S3 graphics card.
-
-config FB_SAVAGE
-	tristate "S3 Savage support"
-	depends on FB && PCI
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select VGASTATE
-	help
-	  This driver supports notebooks and computers with S3 Savage PCI/AGP
-	  chips.
-
-	  Say Y if you have such a graphics card.
-
-	  To compile this driver as a module, choose M here; the module
-	  will be called savagefb.
-
-config FB_SAVAGE_I2C
-       bool "Enable DDC2 Support"
-       depends on FB_SAVAGE
-       select FB_DDC
-       help
-	  This enables I2C support for S3 Savage Chipsets.  This is used
-	  only for getting EDID information from the attached display
-	  allowing for robust video mode handling and switching.
-
-	  Because fbdev-2.6 requires that drivers must be able to
-	  independently validate video mode parameters, you should say Y
-	  here.
-
-config FB_SAVAGE_ACCEL
-       bool "Enable Console Acceleration"
-       depends on FB_SAVAGE
-       default n
-       help
-          This option will compile in console acceleration support. If
-          the resulting framebuffer console has bothersome glitches, then
-          choose N here.
-
-config FB_SIS
-	tristate "SiS/XGI display support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_BOOT_VESA_SUPPORT if FB_SIS = y
-	help
-	  This is the frame buffer device driver for the SiS 300, 315, 330
-	  and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
-	  Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
-
-	  To compile this driver as a module, choose M here; the module
-	  will be called sisfb.
-
-config FB_SIS_300
-	bool "SiS 300 series support"
-	depends on FB_SIS
-	help
-	  Say Y here to support use of the SiS 300/305, 540, 630 and 730.
-
-config FB_SIS_315
-	bool "SiS 315/330/340 series and XGI support"
-	depends on FB_SIS
-	help
-	  Say Y here to support use of the SiS 315, 330 and 340 series
-	  (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
-	  as XGI V3XT, V5, V8 and Z7.
-
-config FB_VIA
-       tristate "VIA UniChrome (Pro) and Chrome9 display support"
-       depends on FB && PCI && X86
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       select I2C_ALGOBIT
-       select I2C
-       select GPIOLIB
-       help
-	  This is the frame buffer device driver for Graphics chips of VIA
-	  UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
-	  CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
- 	  /P4M900,VX800)
-	  Say Y if you have a VIA UniChrome graphics board.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called viafb.
-
-if FB_VIA
-
-config FB_VIA_DIRECT_PROCFS
-	bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
-	depends on FB_VIA
-	default n
-	help
-	  Allow direct hardware access to some output registers via procfs.
-	  This is dangerous but may provide the only chance to get the
-	  correct output device configuration.
-	  Its use is strongly discouraged.
-
-config FB_VIA_X_COMPATIBILITY
-	bool "X server compatibility"
-	depends on FB_VIA
-	default n
-	help
-	  This option reduces the functionality (power saving, ...) of the
-	  framebuffer to avoid negative impact on the OpenChrome X server.
-	  If you use any X server other than fbdev you should enable this
-	  otherwise it should be safe to disable it and allow using all
-	  features.
-
-endif
-
-config FB_NEOMAGIC
-	tristate "NeoMagic display support"
-	depends on FB && PCI
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select VGASTATE
-	help
-	  This driver supports notebooks with NeoMagic PCI chips.
-	  Say Y if you have such a graphics card. 
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called neofb.
-
-config FB_KYRO
-	tristate "IMG Kyro support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
-	  graphics board.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called kyrofb.
-
-config FB_3DFX
-	tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
-	depends on FB && PCI
-	select FB_CFB_IMAGEBLIT
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_MODE_HELPERS
-	help
-	  This driver supports graphics boards with the 3Dfx Banshee,
-	  Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
-	  such a graphics board.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called tdfxfb.
-
-config FB_3DFX_ACCEL
-	bool "3Dfx Acceleration functions"
-	depends on FB_3DFX
-	---help---
-	This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
-	device driver with acceleration functions.
-
-config FB_3DFX_I2C
-	bool "Enable DDC/I2C support"
-	depends on FB_3DFX
-	select FB_DDC
-	default y
-	help
-	  Say Y here if you want DDC/I2C support for your 3dfx Voodoo3.
-
-config FB_VOODOO1
-	tristate "3Dfx Voodoo Graphics (sst1) support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 
-	  Voodoo2 (cvg) based graphics card.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called sstfb.
-
-	  WARNING: Do not use any application that uses the 3D engine
-	  (namely glide) while using this driver.
-	  Please read the <file:Documentation/fb/sstfb.txt> for supported
-	  options and other important info  support.
-
-config FB_VT8623
-	tristate "VIA VT8623 support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_TILEBLITTING
-	select FB_SVGALIB
-	select VGASTATE
-	select FONT_8x16 if FRAMEBUFFER_CONSOLE
-	---help---
-	  Driver for CastleRock integrated graphics core in the
-	  VIA VT8623 [Apollo CLE266] chipset.
-
-config FB_TRIDENT
-	tristate "Trident/CyberXXX/CyberBlade support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  This is the frame buffer device driver for Trident PCI/AGP chipsets.
-	  Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
-	  and Blade XP.
-	  There are also integrated versions of these chips called CyberXXXX,
-	  CyberImage or CyberBlade. These chips are mostly found in laptops
-	  but also on some motherboards including early VIA EPIA motherboards.
-	  For more information, read <file:Documentation/fb/tridentfb.txt>
-
-	  Say Y if you have such a graphics board.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called tridentfb.
-
-config FB_ARK
-	tristate "ARK 2000PV support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_TILEBLITTING
-	select FB_SVGALIB
-	select VGASTATE
-	select FONT_8x16 if FRAMEBUFFER_CONSOLE
-	---help---
-	  Driver for PCI graphics boards with ARK 2000PV chip
-	  and ICS 5342 RAMDAC.
-
-config FB_PM3
-	tristate "Permedia3 support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the 3DLabs Permedia3
-	  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
-	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
-	  and maybe other boards.
-
-config FB_CARMINE
-	tristate "Fujitsu carmine frame buffer support"
-	depends on FB && PCI
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the Fujitsu Carmine chip.
-	  The driver provides two independent frame buffer devices.
-
-choice
-	depends on FB_CARMINE
-	prompt "DRAM timing"
-	default FB_CARMINE_DRAM_EVAL
-
-config FB_CARMINE_DRAM_EVAL
-	bool "Eval board timings"
-	help
-	  Use timings which work on the eval card.
-
-config CARMINE_DRAM_CUSTOM
-	bool "Custom board timings"
-	help
-	  Use custom board timings.
-endchoice
-
-config FB_AU1100
-	bool "Au1100 LCD Driver"
-	depends on (FB = y) && MIPS_ALCHEMY
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the framebuffer driver for the AMD Au1100 SOC.  It can drive
-	  various panels and CRTs by passing in kernel cmd line option
-	  au1100fb:panel=<name>.
-
-config FB_AU1200
-	bool "Au1200/Au1300 LCD Driver"
-	depends on (FB = y) && MIPS_ALCHEMY
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	help
-	  This is the framebuffer driver for the Au1200/Au1300 SOCs.
-	  It can drive various panels and CRTs by passing in kernel cmd line
-	  option au1200fb:panel=<name>.
-
-config FB_VT8500
-	bool "VIA VT8500 framebuffer support"
-	depends on (FB = y) && ARM && ARCH_VT8500
-	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
-	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
-	select FB_SYS_IMAGEBLIT
-	select FB_MODE_HELPERS
-	select VIDEOMODE_HELPERS
-	help
-	  This is the framebuffer driver for VIA VT8500 integrated LCD
-	  controller.
-
-config FB_WM8505
-	bool "Wondermedia WM8xxx-series frame buffer support"
-	depends on (FB = y) && ARM && ARCH_VT8500
-	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
-	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
-	select FB_SYS_IMAGEBLIT
-	select FB_MODE_HELPERS
-	select VIDEOMODE_HELPERS
-	help
-	  This is the framebuffer driver for WonderMedia WM8xxx-series
-	  integrated LCD controller. This driver covers the WM8505, WM8650
-	  and WM8850 SoCs.
-
-config FB_WMT_GE_ROPS
-	bool "VT8500/WM8xxx accelerated raster ops support"
-	depends on (FB = y) && (FB_VT8500 || FB_WM8505)
-	default n
-	help
-	  This adds support for accelerated raster operations on the
-	  VIA VT8500 and Wondermedia 85xx series SoCs.
-
-source "drivers/video/geode/Kconfig"
-
-config FB_HIT
-	tristate "HD64461 Frame Buffer support"
-	depends on FB && HD64461
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This is the frame buffer device driver for the Hitachi HD64461 LCD
-	  frame buffer card.
-
-config FB_PMAG_AA
-	bool "PMAG-AA TURBOchannel framebuffer support"
-	depends on (FB = y) && TC
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	help
-	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
-	  used mainly in the MIPS-based DECstation series.
-
-config FB_PMAG_BA
-	tristate "PMAG-BA TURBOchannel framebuffer support"
-	depends on FB && TC
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	help
-	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
-	  used mainly in the MIPS-based DECstation series.
-
-config FB_PMAGB_B
-	tristate "PMAGB-B TURBOchannel framebuffer support"
-	depends on FB && TC
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	help
-	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly
-	  in the MIPS-based DECstation series. The card is currently only
-	  supported in 1280x1024x8 mode.
-
-config FB_MAXINE
-	bool "Maxine (Personal DECstation) onboard framebuffer support"
-	depends on (FB = y) && MACH_DECSTATION
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	help
-	  Support for the onboard framebuffer (1024x768x8) in the Personal
-	  DECstation series (Personal DECstation 5000/20, /25, /33, /50,
-	  Codename "Maxine").
-
-config FB_G364
-	bool "G364 frame buffer support"
-	depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	help
-	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and
-	  Olivetti M700-10 systems.
-
-config FB_68328
-	bool "Motorola 68328 native frame buffer support"
-	depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328)
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	help
-	  Say Y here if you want to support the built-in frame buffer of
-	  the Motorola 68328 CPU family.
-
-config FB_PXA168
-	tristate "PXA168/910 LCD framebuffer support"
-	depends on FB && (CPU_PXA168 || CPU_PXA910)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for the built-in LCD controller in the Marvell
-	  MMP processor.
-
-config FB_PXA
-	tristate "PXA LCD framebuffer support"
-	depends on FB && ARCH_PXA
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for the built-in LCD controller in the Intel
-	  PXA2x0 processor.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want). The
-	  module will be called pxafb. If you want to compile it as a module,
-	  say M here and read <file:Documentation/kbuild/modules.txt>.
-
-	  If unsure, say N.
-
-config FB_PXA_OVERLAY
-	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
-	default n
-	depends on FB_PXA && (PXA27x || PXA3xx)
-
-config FB_PXA_SMARTPANEL
-	bool "PXA Smartpanel LCD support"
-	default n
-	depends on FB_PXA
-
-config FB_PXA_PARAMETERS
-	bool "PXA LCD command line parameters"
-	default n
-	depends on FB_PXA
-	---help---
-	  Enable the use of kernel command line or module parameters
-	  to configure the physical properties of the LCD panel when
-	  using the PXA LCD driver.
-
-	  This option allows you to override the panel parameters
-	  supplied by the platform in order to support multiple
-	  different models of flatpanel. If you will only be using a
-	  single model of flatpanel then you can safely leave this
-	  option disabled.
-
-	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
-
-config PXA3XX_GCU
-	tristate "PXA3xx 2D graphics accelerator driver"
-	depends on FB_PXA
-	help
-	  Kernelspace driver for the 2D graphics controller unit (GCU)
-	  found on PXA3xx processors. There is a counterpart driver in the
-	  DirectFB suite, see http://www.directfb.org/
-
-	  If you compile this as a module, it will be called pxa3xx_gcu.
-
-config FB_MBX
-	tristate "2700G LCD framebuffer support"
-	depends on FB && ARCH_PXA
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Framebuffer driver for the Intel 2700G (Marathon) Graphics
-	  Accelerator
-
-config FB_MBX_DEBUG
-       bool "Enable debugging info via debugfs"
-       depends on FB_MBX && DEBUG_FS
-       default n
-       ---help---
-         Enable this if you want debugging information using the debug
-         filesystem (debugfs)
-
-         If unsure, say N.
-
-config FB_FSL_DIU
-	tristate "Freescale DIU framebuffer support"
-	depends on FB && FSL_SOC
-	select FB_MODE_HELPERS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select PPC_LIB_RHEAP
-	---help---
-	  Framebuffer driver for the Freescale SoC DIU
-
-config FB_W100
-	tristate "W100 frame buffer support"
-	depends on FB && ARCH_PXA
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
-	  It can also drive the w3220 chip found on iPAQ hx4700.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want). The
-	  module will be called w100fb. If you want to compile it as a module,
-	  say M here and read <file:Documentation/kbuild/modules.txt>.
-
-	  If unsure, say N.
-
-config FB_SH_MOBILE_LCDC
-	tristate "SuperH Mobile LCDC framebuffer support"
-	depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select FB_DEFERRED_IO
-	select FB_BACKLIGHT
-	select SH_MIPI_DSI if SH_LCD_MIPI_DSI
-	---help---
-	  Frame buffer driver for the on-chip SH-Mobile LCD controller.
-
-config FB_SH_MOBILE_HDMI
-	tristate "SuperH Mobile HDMI controller support"
-	depends on FB_SH_MOBILE_LCDC
-	select FB_MODE_HELPERS
-	select SOUND
-	select SND
-	select SND_SOC
-	---help---
-	  Driver for the on-chip SH-Mobile HDMI controller.
-
-config FB_TMIO
-	tristate "Toshiba Mobile IO FrameBuffer support"
-	depends on FB && MFD_CORE
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for the Toshiba Mobile IO integrated as found
-	  on the Sharp SL-6000 series
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want). The
-	  module will be called tmiofb. If you want to compile it as a module,
-	  say M here and read <file:Documentation/kbuild/modules.txt>.
-
-	  If unsure, say N.
-
-config FB_TMIO_ACCELL
-	bool "tmiofb acceleration"
-	depends on FB_TMIO
-	default y
-
-config FB_S3C
-	tristate "Samsung S3C framebuffer support"
-	depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
-		ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for the built-in FB controller in the Samsung
-	  SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
-	  and the S3C64XX series such as the S3C6400 and S3C6410.
-
-	  These chips all have the same basic framebuffer design with the
-	  actual capabilities depending on the chip. For instance the S3C6400
-	  and S3C6410 support 4 hardware windows whereas the S3C24XX series
-	  currently only have two.
-
-	  Currently the support is only for the S3C6400 and S3C6410 SoCs.
-
-config FB_S3C_DEBUG_REGWRITE
-       bool "Debug register writes"
-       depends on FB_S3C
-       ---help---
-         Show all register writes via pr_debug()
-
-config FB_S3C2410
-	tristate "S3C2410 LCD framebuffer support"
-	depends on FB && ARCH_S3C24XX
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for the built-in LCD controller in the Samsung
-	  S3C2410 processor.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want). The
-	  module will be called s3c2410fb. If you want to compile it as a module,
-	  say M here and read <file:Documentation/kbuild/modules.txt>.
-
-	  If unsure, say N.
-config FB_S3C2410_DEBUG
-	bool "S3C2410 lcd debug messages"
-	depends on FB_S3C2410
-	help
-	  Turn on debugging messages. Note that you can set/unset at run time
-	  through sysfs
-
-config FB_NUC900
-        bool "NUC900 LCD framebuffer support"
-        depends on FB && ARCH_W90X900
-        select FB_CFB_FILLRECT
-        select FB_CFB_COPYAREA
-        select FB_CFB_IMAGEBLIT
-        ---help---
-          Frame buffer driver for the built-in LCD controller in the Nuvoton
-          NUC900 processor
-
-config GPM1040A0_320X240
-        bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
-        depends on FB_NUC900
-
-config FB_SM501
-	tristate "Silicon Motion SM501 framebuffer support"
-	depends on FB && MFD_SM501
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for the CRT and LCD controllers in the Silicon
-	  Motion SM501.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want). The
-	  module will be called sm501fb. If you want to compile it as a module,
-	  say M here and read <file:Documentation/kbuild/modules.txt>.
-
-	  If unsure, say N.
-
-config FB_SMSCUFX
-	tristate "SMSC UFX6000/7000 USB Framebuffer support"
-	depends on FB && USB
-	select FB_MODE_HELPERS
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select FB_DEFERRED_IO
-	---help---
-	  This is a kernel framebuffer driver for SMSC UFX USB devices.
-	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
-	  mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
-	  (USB 3.0) devices.
-	  To compile as a module, choose M here: the module name is smscufx.
-
-config FB_UDL
-	tristate "Displaylink USB Framebuffer support"
-	depends on FB && USB
-	select FB_MODE_HELPERS
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select FB_DEFERRED_IO
-	---help---
-	  This is a kernel framebuffer driver for DisplayLink USB devices.
-	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
-	  mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
-	  To compile as a module, choose M here: the module name is udlfb.
-
-config FB_IBM_GXT4500
-	tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors"
-	depends on FB && PPC
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Say Y here to enable support for the IBM GXT4000P/6000P and
-	  GXT4500P/6500P display adaptor based on Raster Engine RC1000,
-	  found on some IBM System P (pSeries) machines. This driver
-	  doesn't use Geometry Engine GT1000.
-
-config FB_PS3
-	tristate "PS3 GPU framebuffer driver"
-	depends on FB && PS3_PS3AV
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
-	---help---
-	  Include support for the virtual frame buffer in the PS3 platform.
-
-config FB_PS3_DEFAULT_SIZE_M
-	int "PS3 default frame buffer size (in MiB)"
-	depends on FB_PS3
-	default 9
-	---help---
-	  This is the default size (in MiB) of the virtual frame buffer in
-	  the PS3.
-	  The default value can be overridden on the kernel command line
-	  using the "ps3fb" option (e.g. "ps3fb=9M");
-
-config FB_XILINX
-	tristate "Xilinx frame buffer support"
-	depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Include support for the Xilinx ML300/ML403 reference design
-	  framebuffer. ML300 carries a 640*480 LCD display on the board,
-	  ML403 uses a standard DB15 VGA connector.
-
-config FB_GOLDFISH
-	tristate "Goldfish Framebuffer"
-	depends on FB && HAS_DMA
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Framebuffer driver for Goldfish Virtual Platform
-
-config FB_COBALT
-	tristate "Cobalt server LCD frame buffer support"
-	depends on FB && (MIPS_COBALT || MIPS_SEAD3)
-
-config FB_SH7760
-	bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
-	depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
-		|| CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Support for the SH7760/SH7763/SH7720/SH7721 integrated
-	  (D)STN/TFT LCD Controller.
-	  Supports display resolutions up to 1024x1024 pixel, grayscale and
-	  color operation, with depths ranging from 1 bpp to 8 bpp monochrome
-	  and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
-	  panels <= 320 pixel horizontal resolution.
-
-config FB_DA8XX
-	tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
-	depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_CFB_REV_PIXELS_IN_BYTE
-	select FB_MODE_HELPERS
-	select VIDEOMODE_HELPERS
-	---help---
-	  This is the frame buffer device driver for the TI LCD controller
-	  found on DA8xx/OMAP-L1xx/AM335x SoCs.
-	  If unsure, say N.
-
-config FB_VIRTUAL
-	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
-	depends on FB
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	---help---
-	  This is a `virtual' frame buffer device. It operates on a chunk of
-	  unswappable kernel memory instead of on the memory of a graphics
-	  board. This means you cannot see any output sent to this frame
-	  buffer device, while it does consume precious memory. The main use
-	  of this frame buffer device is testing and debugging the frame
-	  buffer subsystem. Do NOT enable it for normal systems! To protect
-	  the innocent, it has to be enabled explicitly at boot time using the
-	  kernel option `video=vfb:'.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called vfb. In order to load it, you must use
-	  the vfb_enable=1 option.
-
-	  If unsure, say N.
-
-config XEN_FBDEV_FRONTEND
-	tristate "Xen virtual frame buffer support"
-	depends on FB && XEN
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select FB_DEFERRED_IO
-	select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
-	select XEN_XENBUS_FRONTEND
-	default y
-	help
-	  This driver implements the front-end of the Xen virtual
-	  frame buffer driver.  It communicates with a back-end
-	  in another domain.
-
-config FB_METRONOME
-	tristate "E-Ink Metronome/8track controller support"
-	depends on FB
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select FB_DEFERRED_IO
-	help
-	  This driver implements support for the E-Ink Metronome
-	  controller. The pre-release name for this device was 8track
-	  and could also have been called by some vendors as PVI-nnnn.
-
-config FB_MB862XX
-	tristate "Fujitsu MB862xx GDC support"
-	depends on FB
-	depends on PCI || (OF && PPC)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
-
-choice
-	prompt "GDC variant"
-	depends on FB_MB862XX
-
-config FB_MB862XX_PCI_GDC
-	bool "Carmine/Coral-P(A) GDC"
-	depends on PCI
-	---help---
-	  This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
-	  PCI graphics controller devices.
-
-config FB_MB862XX_LIME
-	bool "Lime GDC"
-	depends on OF && PPC
-	select FB_FOREIGN_ENDIAN
-	select FB_LITTLE_ENDIAN
-	---help---
-	  Framebuffer support for Fujitsu Lime GDC on host CPU bus.
-
-endchoice
-
-config FB_MB862XX_I2C
-	bool "Support I2C bus on MB862XX GDC"
-	depends on FB_MB862XX && I2C
-	default y
-	help
-	  Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
-	  driver to support accessing I2C devices on controller's I2C bus.
-	  These are usually some video decoder chips.
-
-config FB_EP93XX
-	tristate "EP93XX frame buffer support"
-	depends on FB && ARCH_EP93XX
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Framebuffer driver for the Cirrus Logic EP93XX series of processors.
-	  This driver is also available as a module. The module will be called
-	  ep93xx-fb.
-
-config FB_PRE_INIT_FB
-	bool "Don't reinitialize, use bootloader's GDC/Display configuration"
-	depends on FB && FB_MB862XX_LIME
-	---help---
-	  Select this option if display contents should be inherited as set by
-	  the bootloader.
-
-config FB_MSM
-	tristate "MSM Framebuffer support"
-	depends on FB && ARCH_MSM
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-
-config FB_MX3
-	tristate "MX3 Framebuffer support"
-	depends on FB && MX3_IPU
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	default y
-	help
-	  This is a framebuffer device for the i.MX31 LCD Controller. So
-	  far only synchronous displays are supported. If you plan to use
-	  an LCD display with your i.MX31 system, say Y here.
-
-config FB_BROADSHEET
-	tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
-	depends on FB
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select FB_DEFERRED_IO
-	help
-	  This driver implements support for the E-Ink Broadsheet
-	  controller. The release name for this device was Epson S1D13521
-	  and could also have been called by other names when coupled with
-	  a bridge adapter.
-
-config FB_AUO_K190X
-	tristate "AUO-K190X EPD controller support"
-	depends on FB
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	select FB_DEFERRED_IO
-	help
-	  Provides support for epaper controllers from the K190X series
-	  of AUO. These controllers can be used to drive epaper displays
-	  from Sipix.
-
-	  This option enables the common support, shared by the individual
-	  controller drivers. You will also have to enable the driver
-	  for the controller type used in your device.
-
-config FB_AUO_K1900
-	tristate "AUO-K1900 EPD controller support"
-	depends on FB && FB_AUO_K190X
-	help
-	  This driver implements support for the AUO K1900 epd-controller.
-	  This controller can drive Sipix epaper displays but can only do
-	  serial updates, reducing the number of possible frames per second.
-
-config FB_AUO_K1901
-	tristate "AUO-K1901 EPD controller support"
-	depends on FB && FB_AUO_K190X
-	help
-	  This driver implements support for the AUO K1901 epd-controller.
-	  This controller can drive Sipix epaper displays and supports
-	  concurrent updates, making higher frames per second possible.
-
-config FB_JZ4740
-	tristate "JZ4740 LCD framebuffer support"
-	depends on FB && MACH_JZ4740
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	help
-	  Framebuffer support for the JZ4740 SoC.
-
-config FB_MXS
-	tristate "MXS LCD framebuffer support"
-	depends on FB && ARCH_MXS
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_MODE_HELPERS
-	select VIDEOMODE_HELPERS
-	help
-	  Framebuffer support for the MXS SoC.
-
-config FB_PUV3_UNIGFX
-	tristate "PKUnity v3 Unigfx framebuffer support"
-	depends on FB && UNICORE32 && ARCH_PUV3
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_SYS_FOPS
-	help
-	  Choose this option if you want to use the Unigfx device as a
-	  framebuffer device. Without the support of PCI & AGP.
-
-config FB_HYPERV
-	tristate "Microsoft Hyper-V Synthetic Video support"
-	depends on FB && HYPERV
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
-
-config FB_SIMPLE
-	bool "Simple framebuffer support"
-	depends on (FB = y)
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	help
-	  Say Y if you want support for a simple frame-buffer.
-
-	  This driver assumes that the display hardware has been initialized
-	  before the kernel boots, and the kernel will simply render to the
-	  pre-allocated frame buffer surface.
-
-	  Configuration re: surface address, size, and format must be provided
-	  through device tree, or plain old platform data.
-
-source "drivers/video/omap/Kconfig"
-source "drivers/video/omap2/Kconfig"
-source "drivers/video/exynos/Kconfig"
-source "drivers/video/mmp/Kconfig"
-source "drivers/video/backlight/Kconfig"
-
 if VT
 	source "drivers/video/console/Kconfig"
 endif
 
 if FB || SGI_NEWPORT_CONSOLE
 	source "drivers/video/logo/Kconfig"
+
 endif
 
-config FB_SH_MOBILE_MERAM
-	tristate "SuperH Mobile MERAM read ahead support"
-	depends on (SUPERH || ARCH_SHMOBILE)
-	select GENERIC_ALLOCATOR
-	---help---
-	  Enable MERAM support for the SuperH controller.
-
-	  This will allow for caching of the framebuffer to provide more
-	  reliable access under heavy main memory bus traffic situations.
-	  Up to 4 memory channels can be configured, allowing 4 RGB or
-	  2 YCbCr framebuffers to be configured.
-
-config FB_SSD1307
-	tristate "Solomon SSD1307 framebuffer support"
-	depends on FB && I2C
-	depends on OF
-	depends on GPIOLIB
-	select FB_SYS_FOPS
-	select FB_SYS_FILLRECT
-	select FB_SYS_COPYAREA
-	select FB_SYS_IMAGEBLIT
-	select FB_DEFERRED_IO
-	select PWM
-	help
-	  This driver implements support for the Solomon SSD1307
-	  OLED controller over I2C.
 
 endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 1be26fe..9ad3c17 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,175 +1,11 @@
-# Makefile for the Linux video drivers.
-# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
-# Rewritten to use lists instead of if-statements.
-
-# Each configuration option enables a list of files.
-
 obj-$(CONFIG_VGASTATE)            += vgastate.o
 obj-$(CONFIG_HDMI)                += hdmi.o
-obj-y                             += fb_notify.o
-obj-$(CONFIG_FB)                  += fb.o
-fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
-                                     modedb.o fbcvt.o
-fb-objs                           := $(fb-y)
 
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-y				  += backlight/
 
-obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/
-
-obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
-obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
-obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
-obj-$(CONFIG_FB_SYS_FILLRECT)  += sysfillrect.o
-obj-$(CONFIG_FB_SYS_COPYAREA)  += syscopyarea.o
-obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
-obj-$(CONFIG_FB_SYS_FOPS)      += fb_sys_fops.o
-obj-$(CONFIG_FB_SVGALIB)       += svgalib.o
-obj-$(CONFIG_FB_MACMODES)      += macmodes.o
-obj-$(CONFIG_FB_DDC)           += fb_ddc.o
-obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
-obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o
-
-# Hardware specific drivers go first
-obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
-obj-$(CONFIG_FB_ARC)              += arcfb.o
-obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
-obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
-obj-$(CONFIG_FB_GRVGA)            += grvga.o
-obj-$(CONFIG_FB_PM2)              += pm2fb.o
-obj-$(CONFIG_FB_PM3)		  += pm3fb.o
-
-obj-$(CONFIG_FB_I740)		  += i740fb.o
-obj-$(CONFIG_FB_MATROX)		  += matrox/
-obj-$(CONFIG_FB_RIVA)		  += riva/
-obj-$(CONFIG_FB_NVIDIA)		  += nvidia/
-obj-$(CONFIG_FB_ATY)		  += aty/ macmodes.o
-obj-$(CONFIG_FB_ATY128)		  += aty/ macmodes.o
-obj-$(CONFIG_FB_RADEON)		  += aty/
-obj-$(CONFIG_FB_SIS)		  += sis/
-obj-$(CONFIG_FB_VIA)		  += via/
-obj-$(CONFIG_FB_KYRO)             += kyro/
-obj-$(CONFIG_FB_SAVAGE)		  += savage/
-obj-$(CONFIG_FB_GEODE)		  += geode/
-obj-$(CONFIG_FB_MBX)		  += mbx/
-obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o
-obj-$(CONFIG_FB_3DFX)             += tdfxfb.o
-obj-$(CONFIG_FB_CONTROL)          += controlfb.o
-obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o
-obj-$(CONFIG_FB_VALKYRIE)         += valkyriefb.o
-obj-$(CONFIG_FB_CT65550)          += chipsfb.o
-obj-$(CONFIG_FB_IMSTT)            += imsttfb.o
-obj-$(CONFIG_FB_FM2)              += fm2fb.o
-obj-$(CONFIG_FB_VT8623)           += vt8623fb.o
-obj-$(CONFIG_FB_TRIDENT)          += tridentfb.o
-obj-$(CONFIG_FB_LE80578)          += vermilion/
-obj-$(CONFIG_FB_S3)               += s3fb.o
-obj-$(CONFIG_FB_ARK)              += arkfb.o
-obj-$(CONFIG_FB_STI)              += stifb.o
-obj-$(CONFIG_FB_FFB)              += ffb.o sbuslib.o
-obj-$(CONFIG_FB_CG6)              += cg6.o sbuslib.o
-obj-$(CONFIG_FB_CG3)              += cg3.o sbuslib.o
-obj-$(CONFIG_FB_BW2)              += bw2.o sbuslib.o
-obj-$(CONFIG_FB_CG14)             += cg14.o sbuslib.o
-obj-$(CONFIG_FB_P9100)            += p9100.o sbuslib.o
-obj-$(CONFIG_FB_TCX)              += tcx.o sbuslib.o
-obj-$(CONFIG_FB_LEO)              += leo.o sbuslib.o
-obj-$(CONFIG_FB_ACORN)            += acornfb.o
-obj-$(CONFIG_FB_ATARI)            += atafb.o c2p_iplan2.o atafb_mfb.o \
-                                     atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
-obj-$(CONFIG_FB_MAC)              += macfb.o
-obj-$(CONFIG_FB_HECUBA)           += hecubafb.o
-obj-$(CONFIG_FB_N411)             += n411.o
-obj-$(CONFIG_FB_HGA)              += hgafb.o
-obj-$(CONFIG_FB_XVR500)           += sunxvr500.o
-obj-$(CONFIG_FB_XVR2500)          += sunxvr2500.o
-obj-$(CONFIG_FB_XVR1000)          += sunxvr1000.o
-obj-$(CONFIG_FB_IGA)              += igafb.o
-obj-$(CONFIG_FB_APOLLO)           += dnfb.o
-obj-$(CONFIG_FB_Q40)              += q40fb.o
-obj-$(CONFIG_FB_TGA)              += tgafb.o
-obj-$(CONFIG_FB_HP300)            += hpfb.o
-obj-$(CONFIG_FB_G364)             += g364fb.o
-obj-$(CONFIG_FB_EP93XX)		  += ep93xx-fb.o
-obj-$(CONFIG_FB_SA1100)           += sa1100fb.o
-obj-$(CONFIG_FB_HIT)              += hitfb.o
-obj-$(CONFIG_FB_ATMEL)		  += atmel_lcdfb.o
-obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
-obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
-obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o
-obj-$(CONFIG_FB_GOLDFISH)         += goldfishfb.o
-obj-$(CONFIG_FB_68328)            += 68328fb.o
-obj-$(CONFIG_FB_GBE)              += gbefb.o
-obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o
-obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o
-obj-$(CONFIG_FB_PXA)		  += pxafb.o
-obj-$(CONFIG_FB_PXA168)		  += pxa168fb.o
-obj-$(CONFIG_PXA3XX_GCU)	  += pxa3xx-gcu.o
-obj-$(CONFIG_MMP_DISP)           += mmp/
-obj-$(CONFIG_FB_W100)		  += w100fb.o
-obj-$(CONFIG_FB_TMIO)		  += tmiofb.o
-obj-$(CONFIG_FB_AU1100)		  += au1100fb.o
-obj-$(CONFIG_FB_AU1200)		  += au1200fb.o
-obj-$(CONFIG_FB_VT8500)		  += vt8500lcdfb.o
-obj-$(CONFIG_FB_WM8505)		  += wm8505fb.o
-obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o
-obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o
-obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o
-obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o
-obj-$(CONFIG_FB_METRONOME)        += metronomefb.o
-obj-$(CONFIG_FB_BROADSHEET)       += broadsheetfb.o
-obj-$(CONFIG_FB_AUO_K190X)	  += auo_k190x.o
-obj-$(CONFIG_FB_AUO_K1900)	  += auo_k1900fb.o
-obj-$(CONFIG_FB_AUO_K1901)	  += auo_k1901fb.o
-obj-$(CONFIG_FB_S1D13XXX)	  += s1d13xxxfb.o
-obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
-obj-$(CONFIG_FB_IMX)              += imxfb.o
-obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
-obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
-obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
-obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
-obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
-obj-$(CONFIG_FB_PS3)		  += ps3fb.o
-obj-$(CONFIG_FB_SM501)            += sm501fb.o
-obj-$(CONFIG_FB_UDL)		  += udlfb.o
-obj-$(CONFIG_FB_SMSCUFX)	  += smscufx.o
-obj-$(CONFIG_FB_XILINX)           += xilinxfb.o
-obj-$(CONFIG_SH_MIPI_DSI)	  += sh_mipi_dsi.o
-obj-$(CONFIG_FB_SH_MOBILE_HDMI)	  += sh_mobile_hdmi.o
-obj-$(CONFIG_FB_SH_MOBILE_MERAM)  += sh_mobile_meram.o
-obj-$(CONFIG_FB_SH_MOBILE_LCDC)	  += sh_mobile_lcdcfb.o
-obj-$(CONFIG_FB_OMAP)             += omap/
-obj-y                             += omap2/
-obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o
-obj-$(CONFIG_FB_CARMINE)          += carminefb.o
-obj-$(CONFIG_FB_MB862XX)	  += mb862xx/
-obj-$(CONFIG_FB_MSM)              += msm/
-obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
-obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o
-obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
-obj-$(CONFIG_FB_HYPERV)		  += hyperv_fb.o
-obj-$(CONFIG_FB_OPENCORES)	  += ocfb.o
-
-# Platform or fallback drivers go here
-obj-$(CONFIG_FB_UVESA)            += uvesafb.o
-obj-$(CONFIG_FB_VESA)             += vesafb.o
-obj-$(CONFIG_FB_EFI)              += efifb.o
-obj-$(CONFIG_FB_VGA16)            += vga16fb.o
-obj-$(CONFIG_FB_OF)               += offb.o
-obj-$(CONFIG_FB_BF537_LQ035)      += bf537-lq035.o
-obj-$(CONFIG_FB_BF54X_LQ043)	  += bf54x-lq043fb.o
-obj-$(CONFIG_FB_BFIN_LQ035Q1)     += bfin-lq035q1-fb.o
-obj-$(CONFIG_FB_BFIN_T350MCQB)	  += bfin-t350mcqb-fb.o
-obj-$(CONFIG_FB_BFIN_7393)        += bfin_adv7393fb.o
-obj-$(CONFIG_FB_MX3)		  += mx3fb.o
-obj-$(CONFIG_FB_DA8XX)		  += da8xx-fb.o
-obj-$(CONFIG_FB_MXS)		  += mxsfb.o
-obj-$(CONFIG_FB_SSD1307)	  += ssd1307fb.o
-obj-$(CONFIG_FB_SIMPLE)           += simplefb.o
-
-# the test framebuffer is last
-obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
+obj-y				  += fbdev/
 
 obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
 ifeq ($(CONFIG_OF),y)
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 5f65ca3..026fd12 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -46,7 +46,7 @@
 
 #include <asm/io.h>
 
-#include "../sticore.h"
+#include "../fbdev/sticore.h"
 
 /* switching to graphics mode */
 #define BLANK 0
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index cecd3de..7da1ad0 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -28,7 +28,7 @@
 #include <asm/cacheflush.h>
 #include <asm/grfioctl.h>
 
-#include "../sticore.h"
+#include "../fbdev/sticore.h"
 
 #define STI_DRIVERVERSION "Version 0.9b"
 
diff --git a/drivers/video/68328fb.c b/drivers/video/fbdev/68328fb.c
similarity index 100%
rename from drivers/video/68328fb.c
rename to drivers/video/fbdev/68328fb.c
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
new file mode 100644
index 0000000..e1f4727
--- /dev/null
+++ b/drivers/video/fbdev/Kconfig
@@ -0,0 +1,2474 @@
+#
+# fbdev configuration
+#
+
+menuconfig FB
+	tristate "Support for frame buffer devices"
+	---help---
+	  The frame buffer device provides an abstraction for the graphics
+	  hardware. It represents the frame buffer of some video hardware and
+	  allows application software to access the graphics hardware through
+	  a well-defined interface, so the software doesn't need to know
+	  anything about the low-level (hardware register) stuff.
+
+	  Frame buffer devices work identically across the different
+	  architectures supported by Linux and make the implementation of
+	  application programs easier and more portable; at this point, an X
+	  server exists which uses the frame buffer device exclusively.
+	  On several non-X86 architectures, the frame buffer device is the
+	  only way to use the graphics hardware.
+
+	  The device is accessed through special device nodes, usually located
+	  in the /dev directory, i.e. /dev/fb*.
+
+	  You need an utility program called fbset to make full use of frame
+	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
+	  and the Framebuffer-HOWTO at
+	  <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more
+	  information.
+
+	  Say Y here and to the driver for your graphics board below if you
+	  are compiling a kernel for a non-x86 architecture.
+
+	  If you are compiling for the x86 architecture, you can say Y if you
+	  want to play with it, but it is not essential. Please note that
+	  running graphical applications that directly touch the hardware
+	  (e.g. an accelerated X server) and that are not frame buffer
+	  device-aware may cause unexpected results. If unsure, say N.
+
+config FIRMWARE_EDID
+       bool "Enable firmware EDID"
+       depends on FB
+       default n
+       ---help---
+         This enables access to the EDID transferred from the firmware.
+	 On the i386, this is from the Video BIOS. Enable this if DDC/I2C
+	 transfers do not work for your driver and if you are using
+	 nvidiafb, i810fb or savagefb.
+
+	 In general, choosing Y for this option is safe.  If you
+	 experience extremely long delays while booting before you get
+	 something on your display, try setting this to N.  Matrox cards in
+	 combination with certain motherboards and monitors are known to
+	 suffer from this problem.
+
+config FB_DDC
+       tristate
+       depends on FB
+       select I2C_ALGOBIT
+       select I2C
+       default n
+
+config FB_BOOT_VESA_SUPPORT
+	bool
+	depends on FB
+	default n
+	---help---
+	  If true, at least one selected framebuffer driver can take advantage
+	  of VESA video modes set at an early boot stage via the vga= parameter.
+
+config FB_CFB_FILLRECT
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the cfb_fillrect function for generic software rectangle
+	  filling. This is used by drivers that don't provide their own
+	  (accelerated) version.
+
+config FB_CFB_COPYAREA
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the cfb_copyarea function for generic software area copying.
+	  This is used by drivers that don't provide their own (accelerated)
+	  version.
+
+config FB_CFB_IMAGEBLIT
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the cfb_imageblit function for generic software image
+	  blitting. This is used by drivers that don't provide their own
+	  (accelerated) version.
+
+config FB_CFB_REV_PIXELS_IN_BYTE
+	bool
+	depends on FB
+	default n
+	---help---
+	  Allow generic frame-buffer functions to work on displays with 1, 2
+	  and 4 bits per pixel depths which has opposite order of pixels in
+	  byte order to bytes in long order.
+
+config FB_SYS_FILLRECT
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the sys_fillrect function for generic software rectangle
+	  filling. This is used by drivers that don't provide their own
+	  (accelerated) version and the framebuffer is in system RAM.
+
+config FB_SYS_COPYAREA
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the sys_copyarea function for generic software area copying.
+	  This is used by drivers that don't provide their own (accelerated)
+	  version and the framebuffer is in system RAM.
+
+config FB_SYS_IMAGEBLIT
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the sys_imageblit function for generic software image
+	  blitting. This is used by drivers that don't provide their own
+	  (accelerated) version and the framebuffer is in system RAM.
+
+menuconfig FB_FOREIGN_ENDIAN
+	bool "Framebuffer foreign endianness support"
+	depends on FB
+	---help---
+	  This menu will let you enable support for the framebuffers with
+	  non-native endianness (e.g. Little-Endian framebuffer on a
+	  Big-Endian machine). Most probably you don't have such hardware,
+	  so it's safe to say "n" here.
+
+choice
+	prompt "Choice endianness support"
+	depends on FB_FOREIGN_ENDIAN
+
+config FB_BOTH_ENDIAN
+	bool "Support for Big- and Little-Endian framebuffers"
+
+config FB_BIG_ENDIAN
+	bool "Support for Big-Endian framebuffers only"
+
+config FB_LITTLE_ENDIAN
+	bool "Support for Little-Endian framebuffers only"
+
+endchoice
+
+config FB_SYS_FOPS
+       tristate
+       depends on FB
+       default n
+
+config FB_DEFERRED_IO
+	bool
+	depends on FB
+
+config FB_HECUBA
+	tristate
+	depends on FB
+	depends on FB_DEFERRED_IO
+
+config FB_SVGALIB
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Common utility functions useful to fbdev drivers of VGA-based
+	  cards.
+
+config FB_MACMODES
+       tristate
+       depends on FB
+       default n
+
+config FB_BACKLIGHT
+	bool
+	depends on FB
+	select BACKLIGHT_LCD_SUPPORT
+	select BACKLIGHT_CLASS_DEVICE
+	default n
+
+config FB_MODE_HELPERS
+        bool "Enable Video Mode Handling Helpers"
+        depends on FB
+	default n
+	---help---
+	  This enables functions for handling video modes using the
+	  Generalized Timing Formula and the EDID parser. A few drivers rely
+          on this feature such as the radeonfb, rivafb, and the i810fb. If
+	  your driver does not take advantage of this feature, choosing Y will
+	  just increase the kernel size by about 5K.
+
+config FB_TILEBLITTING
+       bool "Enable Tile Blitting Support"
+       depends on FB
+       default n
+       ---help---
+         This enables tile blitting.  Tile blitting is a drawing technique
+	 where the screen is divided into rectangular sections (tiles), whereas
+	 the standard blitting divides the screen into pixels. Because the
+	 default drawing element is a tile, drawing functions will be passed
+	 parameters in terms of number of tiles instead of number of pixels.
+	 For example, to draw a single character, instead of using bitmaps,
+	 an index to an array of bitmaps will be used.  To clear or move a
+	 rectangular section of a screen, the rectangle will be described in
+	 terms of number of tiles in the x- and y-axis.
+
+	 This is particularly important to one driver, matroxfb.  If
+	 unsure, say N.
+
+comment "Frame buffer hardware drivers"
+	depends on FB
+
+config FB_GRVGA
+	tristate "Aeroflex Gaisler framebuffer support"
+	depends on FB && SPARC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
+
+config FB_CIRRUS
+	tristate "Cirrus Logic support"
+	depends on FB && (ZORRO || PCI)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  This enables support for Cirrus Logic GD542x/543x based boards on
+	  Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
+
+	  If you have a PCI-based system, this enables support for these
+	  chips: GD-543x, GD-544x, GD-5480.
+
+	  Please read the file <file:Documentation/fb/cirrusfb.txt>.
+
+	  Say N unless you have such a graphics board or plan to get one
+	  before you next recompile the kernel.
+
+config FB_PM2
+	tristate "Permedia2 support"
+	depends on FB && ((AMIGA && BROKEN) || PCI)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for cards based on
+	  the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
+	  The driver was tested on the following cards:
+		Diamond FireGL 1000 PRO AGP
+		ELSA Gloria Synergy PCI
+		Appian Jeronimo PRO (both heads) PCI
+		3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
+		Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
+		ASK Graphic Blaster Exxtreme AGP
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pm2fb.
+
+config FB_PM2_FIFO_DISCONNECT
+	bool "enable FIFO disconnect feature"
+	depends on FB_PM2 && PCI
+	help
+	  Support the Permedia2 FIFO disconnect feature.
+
+config FB_ARMCLCD
+	tristate "ARM PrimeCell PL110 support"
+	depends on ARM || ARM64 || COMPILE_TEST
+	depends on FB && ARM_AMBA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This framebuffer device driver is for the ARM PrimeCell PL110
+	  Colour LCD controller.  ARM PrimeCells provide the building
+	  blocks for System on a Chip devices.
+
+	  If you want to compile this as a module (=code which can be
+	  inserted into and removed from the running kernel), say M
+	  here and read <file:Documentation/kbuild/modules.txt>.  The module
+	  will be called amba-clcd.
+
+config FB_ACORN
+	bool "Acorn VIDC support"
+	depends on (FB = y) && ARM && ARCH_ACORN
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Acorn VIDC graphics
+	  hardware found in Acorn RISC PCs and other ARM-based machines.  If
+	  unsure, say N.
+
+config FB_CLPS711X
+	bool "CLPS711X LCD support"
+	depends on (FB = y) && ARM && ARCH_CLPS711X
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y to enable the Framebuffer driver for the CLPS7111 and
+	  EP7212 processors.
+
+config FB_SA1100
+	bool "SA-1100 LCD support"
+	depends on (FB = y) && ARM && ARCH_SA1100
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is a framebuffer device for the SA-1100 LCD Controller.
+	  See <http://www.linux-fbdev.org/> for information on framebuffer
+	  devices.
+
+	  If you plan to use the LCD display with your SA-1100 system, say
+	  Y here.
+
+config FB_IMX
+	tristate "Freescale i.MX1/21/25/27 LCD support"
+	depends on FB && ARCH_MXC
+	select BACKLIGHT_LCD_SUPPORT
+	select LCD_CLASS_DEVICE
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+
+config FB_CYBER2000
+	tristate "CyberPro 2000/2010/5000 support"
+	depends on FB && PCI && (BROKEN || !SPARC64)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This enables support for the Integraphics CyberPro 20x0 and 5000
+	  VGA chips used in the Rebel.com Netwinder and other machines.
+	  Say Y if you have a NetWinder or a graphics card containing this
+	  device, otherwise say N.
+
+config FB_CYBER2000_DDC
+	bool "DDC for CyberPro support"
+	depends on FB_CYBER2000
+	select FB_DDC
+	default y
+	help
+	  Say Y here if you want DDC support for your CyberPro graphics
+	  card. This is only I2C bus support, driver does not use EDID.
+
+config FB_CYBER2000_I2C
+	bool "CyberPro 2000/2010/5000 I2C support"
+	depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
+	select I2C_ALGOBIT
+	help
+	  Enable support for the I2C video decoder interface on the
+	  Integraphics CyberPro 20x0 and 5000 VGA chips.  This is used
+	  on the Netwinder machines for the SAA7111 video capture.
+
+config FB_APOLLO
+	bool
+	depends on (FB = y) && APOLLO
+	default y
+	select FB_CFB_FILLRECT
+	select FB_CFB_IMAGEBLIT
+
+config FB_Q40
+	bool
+	depends on (FB = y) && Q40
+	default y
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+
+config FB_AMIGA
+	tristate "Amiga native chipset support"
+	depends on FB && AMIGA
+	help
+	  This is the frame buffer device driver for the builtin graphics
+	  chipset found in Amigas.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called amifb.
+
+config FB_AMIGA_OCS
+	bool "Amiga OCS chipset support"
+	depends on FB_AMIGA
+	help
+	  This enables support for the original Agnus and Denise video chips,
+	  found in the Amiga 1000 and most A500's and A2000's. If you intend
+	  to run Linux on any of these systems, say Y; otherwise say N.
+
+config FB_AMIGA_ECS
+	bool "Amiga ECS chipset support"
+	depends on FB_AMIGA
+	help
+	  This enables support for the Enhanced Chip Set, found in later
+	  A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
+	  you intend to run Linux on any of these systems, say Y; otherwise
+	  say N.
+
+config FB_AMIGA_AGA
+	bool "Amiga AGA chipset support"
+	depends on FB_AMIGA
+	help
+	  This enables support for the Advanced Graphics Architecture (also
+	  known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
+	  and CD32. If you intend to run Linux on any of these systems, say Y;
+	  otherwise say N.
+
+config FB_FM2
+	bool "Amiga FrameMaster II/Rainbow II support"
+	depends on (FB = y) && ZORRO
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Amiga FrameMaster
+	  card from BSC (exhibited 1992 but not shipped as a CBM product).
+
+config FB_ARC
+	tristate "Arc Monochrome LCD board support"
+	depends on FB && X86
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	help
+	  This enables support for the Arc Monochrome LCD board. The board
+	  is based on the KS-108 lcd controller and is typically a matrix
+	  of 2*n chips. This driver was tested with a 128x64 panel. This
+	  driver supports it for use with x86 SBCs through a 16 bit GPIO
+	  interface (8 bit data, 8 bit control). If you anticipate using
+	  this driver, say Y or M; otherwise say N. You must specify the
+	  GPIO IO address to be used for setting control and data.
+
+config FB_ATARI
+	bool "Atari native chipset support"
+	depends on (FB = y) && ATARI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the builtin graphics
+	  chipset found in Ataris.
+
+config FB_OF
+	bool "Open Firmware frame buffer device support"
+	depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  Say Y if you want support with Open Firmware for your graphics
+	  board.
+
+config FB_CONTROL
+	bool "Apple \"control\" display support"
+	depends on (FB = y) && PPC_PMAC && PPC32
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  This driver supports a frame buffer for the graphics adapter in the
+	  Power Macintosh 7300 and others.
+
+config FB_PLATINUM
+	bool "Apple \"platinum\" display support"
+	depends on (FB = y) && PPC_PMAC && PPC32
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  This driver supports a frame buffer for the "platinum" graphics
+	  adapter in some Power Macintoshes.
+
+config FB_VALKYRIE
+	bool "Apple \"valkyrie\" display support"
+	depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  This driver supports a frame buffer for the "valkyrie" graphics
+	  adapter in some Power Macintoshes.
+
+config FB_CT65550
+	bool "Chips 65550 display support"
+	depends on (FB = y) && PPC32 && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Chips & Technologies
+	  65550 graphics chip in PowerBooks.
+
+config FB_ASILIANT
+	bool "Asiliant (Chips) 69000 display support"
+	depends on (FB = y) && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Asiliant 69030 chipset
+
+config FB_IMSTT
+	bool "IMS Twin Turbo display support"
+	depends on (FB = y) && PCI
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES if PPC
+	help
+	  The IMS Twin Turbo is a PCI-based frame buffer card bundled with
+	  many Macintosh and compatible computers.
+
+config FB_VGA16
+	tristate "VGA 16-color graphics support"
+	depends on FB && (X86 || PPC)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	select FONT_8x16 if FRAMEBUFFER_CONSOLE
+	help
+	  This is the frame buffer device driver for VGA 16 color graphic
+	  cards. Say Y if you have such a card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vga16fb.
+
+config FB_BF54X_LQ043
+	tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
+	depends on FB && (BF54x) && !BF542
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	 This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
+
+config FB_BFIN_T350MCQB
+	tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)"
+	depends on FB && BLACKFIN
+	select BFIN_GPTIMERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	 This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD
+	 This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
+	 It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
+
+config FB_BFIN_LQ035Q1
+	tristate "SHARP LQ035Q1DH02 TFT LCD"
+	depends on FB && BLACKFIN && SPI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select BFIN_GPTIMERS
+	help
+	  This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on
+	  the Blackfin Landscape LCD EZ-Extender Card.
+	  This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI
+	  It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bfin-lq035q1-fb.
+
+config FB_BF537_LQ035
+	tristate "SHARP LQ035 TFT LCD (BF537 STAMP)"
+	depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select BFIN_GPTIMERS
+	help
+	  This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD
+	  attached to a BF537.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bf537-lq035.
+
+config FB_BFIN_7393
+	tristate "Blackfin ADV7393 Video encoder"
+	depends on FB && BLACKFIN
+	select I2C
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer device for a ADV7393 video encoder
+	  attached to a Blackfin on the PPI port.
+	  If your Blackfin board has a ADV7393 select Y.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bfin_adv7393fb.
+
+choice
+	prompt  "Video mode support"
+	depends on FB_BFIN_7393
+	default NTSC
+
+config NTSC
+	bool 'NTSC 720x480'
+
+config PAL
+	bool 'PAL 720x576'
+
+config NTSC_640x480
+	bool 'NTSC 640x480 (Experimental)'
+
+config PAL_640x480
+	bool 'PAL 640x480 (Experimental)'
+
+config NTSC_YCBCR
+	bool 'NTSC 720x480 YCbCR input'
+
+config PAL_YCBCR
+	bool 'PAL 720x576 YCbCR input'
+
+endchoice
+
+choice
+	prompt  "Size of ADV7393 frame buffer memory Single/Double Size"
+	depends on (FB_BFIN_7393)
+	default ADV7393_1XMEM
+
+config ADV7393_1XMEM
+	bool 'Single'
+
+config ADV7393_2XMEM
+	bool 'Double'
+endchoice
+
+config FB_STI
+	tristate "HP STI frame buffer device support"
+	depends on FB && PARISC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select STI_CONSOLE
+	select VT
+	default y
+	---help---
+	  STI refers to the HP "Standard Text Interface" which is a set of
+	  BIOS routines contained in a ROM chip in HP PA-RISC based machines.
+	  Enabling this option will implement the linux framebuffer device
+	  using calls to the STI BIOS routines for initialisation.
+	
+	  If you enable this option, you will get a planar framebuffer device
+	  /dev/fb which will work on the most common HP graphic cards of the
+	  NGLE family, including the artist chips (in the 7xx and Bxxx series),
+	  HCRX, HCRX24, CRX, CRX24 and VisEG series.
+
+	  It is safe to enable this option, so you should probably say "Y".
+
+config FB_MAC
+	bool "Generic Macintosh display support"
+	depends on (FB = y) && MAC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+
+config FB_HP300
+	bool
+	depends on (FB = y) && DIO
+	select FB_CFB_IMAGEBLIT
+	default y
+
+config FB_TGA
+	tristate "TGA/SFB+ framebuffer support"
+	depends on FB && (ALPHA || TC)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select BITREVERSE
+	---help---
+	  This is the frame buffer device driver for generic TGA and SFB+
+	  graphic cards.  These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
+	  also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
+	  TURBOchannel cards, also known as PMAGD-A, -B and -C.
+
+	  Due to hardware limitations ZLX-E2 and E3 cards are not supported
+	  for DECstation 5000/200 systems.  Additionally due to firmware
+	  limitations these cards may cause troubles with booting DECstation
+	  5000/240 and /260 systems, but are fully supported under Linux if
+	  you manage to get it going. ;-)
+
+	  Say Y if you have one of those.
+
+config FB_UVESA
+	tristate "Userspace VESA VGA graphics support"
+	depends on FB && CONNECTOR
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	help
+	  This is the frame buffer driver for generic VBE 2.0 compliant
+	  graphic cards. It can also take advantage of VBE 3.0 features,
+	  such as refresh rate adjustment.
+
+	  This driver generally provides more features than vesafb but
+	  requires a userspace helper application called 'v86d'. See
+	  <file:Documentation/fb/uvesafb.txt> for more information.
+
+	  If unsure, say N.
+
+config FB_VESA
+	bool "VESA VGA graphics support"
+	depends on (FB = y) && X86
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_BOOT_VESA_SUPPORT
+	help
+	  This is the frame buffer device driver for generic VESA 2.0
+	  compliant graphic cards. The older VESA 1.2 cards are not supported.
+	  You will get a boot time penguin logo at no additional cost. Please
+	  read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
+
+config FB_EFI
+	bool "EFI-based Framebuffer Support"
+	depends on (FB = y) && X86 && EFI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the EFI frame buffer device driver. If the firmware on
+	  your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
+	  using the EFI framebuffer as your console.
+
+config FB_N411
+       tristate "N411 Apollo/Hecuba devkit support"
+       depends on FB && X86 && MMU
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       select FB_SYS_FOPS
+       select FB_DEFERRED_IO
+       select FB_HECUBA
+       help
+         This enables support for the Apollo display controller in its
+         Hecuba form using the n411 devkit.
+
+config FB_HGA
+	tristate "Hercules mono graphics support"
+	depends on FB && X86
+	help
+	  Say Y here if you have a Hercules mono graphics card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hgafb.
+
+	  As this card technology is at least 25 years old,
+	  most people will answer N here.
+
+config FB_GBE
+	bool "SGI Graphics Backend frame buffer support"
+	depends on (FB = y) && SGI_IP32
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+ 	help
+	  This is the frame buffer device driver for SGI Graphics Backend.
+	  This chip is used in SGI O2 and Visual Workstation 320/540.
+
+config FB_GBE_MEM
+	int "Video memory size in MB"
+	depends on FB_GBE
+	default 4
+	help
+	  This is the amount of memory reserved for the framebuffer,
+	  which can be any value between 1MB and 8MB.
+
+config FB_SBUS
+	bool "SBUS and UPA framebuffers"
+	depends on (FB = y) && SPARC
+	help
+	  Say Y if you want support for SBUS or UPA based frame buffer device.
+
+config FB_BW2
+	bool "BWtwo support"
+	depends on (FB = y) && (SPARC && FB_SBUS)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the BWtwo frame buffer.
+
+config FB_CG3
+	bool "CGthree support"
+	depends on (FB = y) && (SPARC && FB_SBUS)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the CGthree frame buffer.
+
+config FB_CG6
+	bool "CGsix (GX,TurboGX) support"
+	depends on (FB = y) && (SPARC && FB_SBUS)
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the CGsix (GX, TurboGX)
+	  frame buffer.
+
+config FB_FFB
+	bool "Creator/Creator3D/Elite3D support"
+	depends on FB_SBUS && SPARC64
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Creator, Creator3D,
+	  and Elite3D graphics boards.
+
+config FB_TCX
+	bool "TCX (SS4/SS5 only) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the TCX 24/8bit frame
+	  buffer.
+
+config FB_CG14
+	bool "CGfourteen (SX) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the CGfourteen frame
+	  buffer on Desktop SPARCsystems with the SX graphics option.
+
+config FB_P9100
+	bool "P9100 (Sparcbook 3 only) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the P9100 card
+	  supported on Sparcbook 3 machines.
+
+config FB_LEO
+	bool "Leo (ZX) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the SBUS-based Sun ZX
+	  (leo) frame buffer cards.
+
+config FB_IGA
+	bool "IGA 168x display support"
+	depends on (FB = y) && SPARC32
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer device for the INTERGRAPHICS 1680 and
+	  successor frame buffer cards.
+
+config FB_XVR500
+	bool "Sun XVR-500 3DLABS Wildcat support"
+	depends on (FB = y) && PCI && SPARC64
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer device for the Sun XVR-500 and similar
+	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver
+	  only works on sparc64 systems where the system firmware has
+	  mostly initialized the card already.  It is treated as a
+	  completely dumb framebuffer device.
+
+config FB_XVR2500
+	bool "Sun XVR-2500 3DLABS Wildcat support"
+	depends on (FB = y) && PCI && SPARC64
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer device for the Sun XVR-2500 and similar
+	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver
+	  only works on sparc64 systems where the system firmware has
+	  mostly initialized the card already.  It is treated as a
+	  completely dumb framebuffer device.
+
+config FB_XVR1000
+	bool "Sun XVR-1000 support"
+	depends on (FB = y) && SPARC64
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer device for the Sun XVR-1000 and similar
+	  graphics cards.  The driver only works on sparc64 systems where
+	  the system firmware has mostly initialized the card already.  It
+	  is treated as a completely dumb framebuffer device.
+
+config FB_PVR2
+	tristate "NEC PowerVR 2 display support"
+	depends on FB && SH_DREAMCAST
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Say Y here if you have a PowerVR 2 card in your box.  If you plan to
+	  run linux on your Dreamcast, you will have to say Y here.
+	  This driver may or may not work on other PowerVR 2 cards, but is
+	  totally untested.  Use at your own risk.  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pvr2fb.
+
+	  You can pass several parameters to the driver at boot time or at
+	  module load time.  The parameters look like "video=pvr2:XXX", where
+	  the meaning of XXX can be found at the end of the main source file
+	  (<file:drivers/video/pvr2fb.c>). Please see the file
+	  <file:Documentation/fb/pvr2fb.txt>.
+
+config FB_OPENCORES
+	tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
+	depends on FB && HAS_DMA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This enables support for the OpenCores VGA/LCD core.
+
+	  The OpenCores VGA/LCD core is typically used together with
+	  softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor
+	  systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs.
+
+	  The source code and specification for the core is available at
+	  <http://opencores.org/project,vga_lcd>
+
+config FB_S1D13XXX
+	tristate "Epson S1D13XXX framebuffer support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Support for S1D13XXX framebuffer device family (currently only
+	  working with S1D13806). Product specs at
+	  <http://vdc.epson.com/>
+
+config FB_ATMEL
+	tristate "AT91/AT32 LCD Controller support"
+	depends on FB && HAVE_FB_ATMEL
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	help
+	  This enables support for the AT91/AT32 LCD Controller.
+
+config FB_INTSRAM
+	bool "Frame Buffer in internal SRAM"
+	depends on FB_ATMEL && ARCH_AT91SAM9261
+	help
+	  Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
+	  to let frame buffer in external SDRAM.
+
+config FB_ATMEL_STN
+	bool "Use a STN display with AT91/AT32 LCD Controller"
+	depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
+	default n
+	help
+	  Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
+	  Controller. Say N if you want to connect a TFT.
+
+	  If unsure, say N.
+
+config FB_NVIDIA
+	tristate "nVidia Framebuffer Support"
+	depends on FB && PCI
+	select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select BITREVERSE
+	select VGASTATE
+	help
+	  This driver supports graphics boards with the nVidia chips, TNT
+	  and newer. For very old chipsets, such as the RIVA128, then use
+	  the rivafb.
+	  Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called nvidiafb.
+
+config FB_NVIDIA_I2C
+       bool "Enable DDC Support"
+       depends on FB_NVIDIA
+       select FB_DDC
+       help
+	  This enables I2C support for nVidia Chipsets.  This is used
+	  only for getting EDID information from the attached display
+	  allowing for robust video mode handling and switching.
+
+	  Because fbdev-2.6 requires that drivers must be able to
+	  independently validate video mode parameters, you should say Y
+	  here.
+
+config FB_NVIDIA_DEBUG
+	bool "Lots of debug output"
+	depends on FB_NVIDIA
+	default n
+	help
+	  Say Y here if you want the nVidia driver to output all sorts
+	  of debugging information to provide to the maintainer when
+	  something goes wrong.
+
+config FB_NVIDIA_BACKLIGHT
+	bool "Support for backlight control"
+	depends on FB_NVIDIA
+	default y
+	help
+	  Say Y here if you want to control the backlight of your display.
+
+config FB_RIVA
+	tristate "nVidia Riva support"
+	depends on FB && PCI
+	select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select BITREVERSE
+	select VGASTATE
+	help
+	  This driver supports graphics boards with the nVidia Riva/Geforce
+	  chips.
+	  Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rivafb.
+
+config FB_RIVA_I2C
+       bool "Enable DDC Support"
+       depends on FB_RIVA
+       select FB_DDC
+       help
+	  This enables I2C support for nVidia Chipsets.  This is used
+	  only for getting EDID information from the attached display
+	  allowing for robust video mode handling and switching.
+
+	  Because fbdev-2.6 requires that drivers must be able to
+	  independently validate video mode parameters, you should say Y
+	  here.
+
+config FB_RIVA_DEBUG
+	bool "Lots of debug output"
+	depends on FB_RIVA
+	default n
+	help
+	  Say Y here if you want the Riva driver to output all sorts
+	  of debugging information to provide to the maintainer when
+	  something goes wrong.
+
+config FB_RIVA_BACKLIGHT
+	bool "Support for backlight control"
+	depends on FB_RIVA
+	default y
+	help
+	  Say Y here if you want to control the backlight of your display.
+
+config FB_I740
+	tristate "Intel740 support"
+	depends on FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	select FB_DDC
+	help
+	  This driver supports graphics cards based on Intel740 chip.
+
+config FB_I810
+	tristate "Intel 810/815 support"
+	depends on FB && PCI && X86_32 && AGP_INTEL
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	help
+	  This driver supports the on-board graphics built in to the Intel 810 
+          and 815 chipsets.  Say Y if you have and plan to use such a board.
+
+          To compile this driver as a module, choose M here: the
+	  module will be called i810fb.
+
+          For more information, please read 
+	  <file:Documentation/fb/intel810.txt>
+
+config FB_I810_GTF
+	bool "use VESA Generalized Timing Formula"
+	depends on FB_I810
+	help
+	  If you say Y, then the VESA standard, Generalized Timing Formula 
+          or GTF, will be used to calculate the required video timing values
+	  per video mode.  Since the GTF allows nondiscrete timings 
+          (nondiscrete being a range of values as opposed to discrete being a
+          set of values), you'll be able to use any combination of horizontal 
+	  and vertical resolutions, and vertical refresh rates without having
+	  to specify your own timing parameters.  This is especially useful
+	  to maximize the performance of an aging display, or if you just 
+          have a display with nonstandard dimensions. A VESA compliant 
+	  monitor is recommended, but can still work with non-compliant ones.
+	  If you need or want this, then select this option. The timings may 
+	  not be compliant with Intel's recommended values. Use at your own 
+	  risk.
+
+          If you say N, the driver will revert to discrete video timings 
+	  using a set recommended by Intel in their documentation.
+  
+          If unsure, say N.
+
+config FB_I810_I2C
+	bool "Enable DDC Support"
+	depends on FB_I810 && FB_I810_GTF
+	select FB_DDC
+	help
+
+config FB_LE80578
+	tristate "Intel LE80578 (Vermilion) support"
+	depends on FB && PCI && X86
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This driver supports the LE80578 (Vermilion Range) chipset
+
+config FB_CARILLO_RANCH
+	tristate "Intel Carillo Ranch support"
+	depends on FB_LE80578 && FB && PCI && X86
+	help
+	  This driver supports the LE80578 (Carillo Ranch) board
+
+config FB_INTEL
+	tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
+	depends on FB && PCI && X86 && AGP_INTEL && EXPERT
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_BOOT_VESA_SUPPORT if FB_INTEL = y
+	depends on !DRM_I915
+	help
+	  This driver supports the on-board graphics built in to the Intel
+          830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
+          Say Y if you have and plan to use such a board.
+
+	  To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called intelfb.
+
+	  For more information, please read <file:Documentation/fb/intelfb.txt>
+
+config FB_INTEL_DEBUG
+	bool "Intel driver Debug Messages"
+	depends on FB_INTEL
+	---help---
+	  Say Y here if you want the Intel driver to output all sorts
+	  of debugging information to provide to the maintainer when
+	  something goes wrong.
+
+config FB_INTEL_I2C
+	bool "DDC/I2C for Intel framebuffer support"
+	depends on FB_INTEL
+	select FB_DDC
+	default y
+	help
+	  Say Y here if you want DDC/I2C support for your on-board Intel graphics.
+
+config FB_MATROX
+	tristate "Matrox acceleration"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_TILEBLITTING
+	select FB_MACMODES if PPC_PMAC
+	---help---
+	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
+	  Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
+	  Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
+	  Matrox G400, G450 or G550 card in your box.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called matroxfb.
+
+	  You can pass several parameters to the driver at boot time or at
+	  module load time. The parameters look like "video=matroxfb:XXX", and
+	  are described in <file:Documentation/fb/matroxfb.txt>.
+
+config FB_MATROX_MILLENIUM
+	bool "Millennium I/II support"
+	depends on FB_MATROX
+	help
+	  Say Y here if you have a Matrox Millennium or Matrox Millennium II
+	  video card. If you select "Advanced lowlevel driver options" below,
+	  you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
+	  packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
+	  also use font widths different from 8.
+
+config FB_MATROX_MYSTIQUE
+	bool "Mystique support"
+	depends on FB_MATROX
+	help
+	  Say Y here if you have a Matrox Mystique or Matrox Mystique 220
+	  video card. If you select "Advanced lowlevel driver options" below,
+	  you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
+	  packed pixel and 32 bpp packed pixel. You can also use font widths
+	  different from 8.
+
+config FB_MATROX_G
+	bool "G100/G200/G400/G450/G550 support"
+	depends on FB_MATROX
+	---help---
+	  Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
+	  video card. If you select "Advanced lowlevel driver options", you
+	  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
+	  pixel and 32 bpp packed pixel. You can also use font widths
+	  different from 8.
+
+	  If you need support for G400 secondary head, you must say Y to
+	  "Matrox I2C support" and "G400 second head support" right below.
+	  G450/G550 secondary head and digital output are supported without
+	  additional modules.
+
+	  The driver starts in monitor mode. You must use the matroxset tool 
+	  (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to 
+	  swap primary and secondary head outputs, or to change output mode.  
+	  Secondary head driver always start in 640x480 resolution and you 
+	  must use fbset to change it.
+
+	  Do not forget that second head supports only 16 and 32 bpp
+	  packed pixels, so it is a good idea to compile them into the kernel
+	  too. You can use only some font widths, as the driver uses generic
+	  painting procedures (the secondary head does not use acceleration
+	  engine).
+
+	  G450/G550 hardware can display TV picture only from secondary CRTC,
+	  and it performs no scaling, so picture must have 525 or 625 lines.
+
+config FB_MATROX_I2C
+	tristate "Matrox I2C support"
+	depends on FB_MATROX
+	select FB_DDC
+	---help---
+	  This drivers creates I2C buses which are needed for accessing the
+	  DDC (I2C) bus present on all Matroxes, an I2C bus which
+	  interconnects Matrox optional devices, like MGA-TVO on G200 and
+	  G400, and the secondary head DDC bus, present on G400 only.
+
+	  You can say Y or M here if you want to experiment with monitor
+	  detection code. You must say Y or M here if you want to use either
+	  second head of G400 or MGA-TVO on G200 or G400.
+
+	  If you compile it as module, it will create a module named
+	  i2c-matroxfb.
+
+config FB_MATROX_MAVEN
+	tristate "G400 second head support"
+	depends on FB_MATROX_G && FB_MATROX_I2C
+	---help---
+	  WARNING !!! This support does not work with G450 !!!
+
+	  Say Y or M here if you want to use a secondary head (meaning two
+	  monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary
+	  head is not compatible with accelerated XFree 3.3.x SVGA servers -
+	  secondary head output is blanked while you are in X. With XFree
+	  3.9.17 preview you can use both heads if you use SVGA over fbdev or
+	  the fbdev driver on first head and the fbdev driver on second head.
+
+	  If you compile it as module, two modules are created,
+	  matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
+	  both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
+	  also load i2c-matroxfb to get it to run.
+
+	  The driver starts in monitor mode and you must use the matroxset
+	  tool (available at
+	  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
+	  PAL or NTSC or to swap primary and secondary head outputs.
+	  Secondary head driver also always start in 640x480 resolution, you
+	  must use fbset to change it.
+
+	  Also do not forget that second head supports only 16 and 32 bpp
+	  packed pixels, so it is a good idea to compile them into the kernel
+	  too.  You can use only some font widths, as the driver uses generic
+	  painting procedures (the secondary head does not use acceleration
+	  engine).
+
+config FB_RADEON
+	tristate "ATI Radeon display support"
+	depends on FB && PCI
+	select FB_BACKLIGHT if FB_RADEON_BACKLIGHT
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES if PPC_OF
+	help
+	  Choose this option if you want to use an ATI Radeon graphics card as
+	  a framebuffer device.  There are both PCI and AGP versions.  You
+	  don't need to choose this to run the Radeon in plain VGA mode.
+
+	  There is a product page at
+	  http://products.amd.com/en-us/GraphicCardResult.aspx
+
+config FB_RADEON_I2C
+	bool "DDC/I2C for ATI Radeon support"
+	depends on FB_RADEON
+	select FB_DDC
+	default y
+	help
+	  Say Y here if you want DDC/I2C support for your Radeon board. 
+
+config FB_RADEON_BACKLIGHT
+	bool "Support for backlight control"
+	depends on FB_RADEON
+	default y
+	help
+	  Say Y here if you want to control the backlight of your display.
+
+config FB_RADEON_DEBUG
+	bool "Lots of debug output from Radeon driver"
+	depends on FB_RADEON
+	default n
+	help
+	  Say Y here if you want the Radeon driver to output all sorts
+	  of debugging information to provide to the maintainer when
+	  something goes wrong.
+
+config FB_ATY128
+	tristate "ATI Rage128 display support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
+	select FB_MACMODES if PPC_PMAC
+	help
+	  This driver supports graphics boards with the ATI Rage128 chips.
+	  Say Y if you have such a graphics board and read
+	  <file:Documentation/fb/aty128fb.txt>.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called aty128fb.
+
+config FB_ATY128_BACKLIGHT
+	bool "Support for backlight control"
+	depends on FB_ATY128
+	default y
+	help
+	  Say Y here if you want to control the backlight of your display.
+
+config FB_ATY
+	tristate "ATI Mach64 display support" if PCI || ATARI
+	depends on FB && !SPARC32
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_BACKLIGHT if FB_ATY_BACKLIGHT
+	select FB_MACMODES if PPC
+	help
+	  This driver supports graphics boards with the ATI Mach64 chips.
+	  Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called atyfb.
+
+config FB_ATY_CT
+	bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
+	depends on PCI && FB_ATY
+	default y if SPARC64 && PCI
+	help
+	  Say Y here to support use of ATI's 64-bit Rage boards (or other
+	  boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
+	  framebuffer device.  The ATI product support page for these boards
+	  is at <http://support.ati.com/products/pc/mach64/mach64.html>.
+
+config FB_ATY_GENERIC_LCD
+	bool "Mach64 generic LCD support"
+	depends on FB_ATY_CT
+	help
+	  Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
+	  Rage XC, or Rage XL chipset.
+
+config FB_ATY_GX
+	bool "Mach64 GX support" if PCI
+	depends on FB_ATY
+	default y if ATARI
+	help
+	  Say Y here to support use of the ATI Mach64 Graphics Expression
+	  board (or other boards based on the Mach64 GX chipset) as a
+	  framebuffer device.  The ATI product support page for these boards
+	  is at
+	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
+
+config FB_ATY_BACKLIGHT
+	bool "Support for backlight control"
+	depends on FB_ATY
+	default y
+	help
+	  Say Y here if you want to control the backlight of your display.
+
+config FB_S3
+	tristate "S3 Trio/Virge support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_TILEBLITTING
+	select FB_SVGALIB
+	select VGASTATE
+	select FONT_8x16 if FRAMEBUFFER_CONSOLE
+	---help---
+	  Driver for graphics boards with S3 Trio / S3 Virge chip.
+
+config FB_S3_DDC
+	bool "DDC for S3 support"
+	depends on FB_S3
+	select FB_DDC
+	default y
+	help
+	  Say Y here if you want DDC support for your S3 graphics card.
+
+config FB_SAVAGE
+	tristate "S3 Savage support"
+	depends on FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	help
+	  This driver supports notebooks and computers with S3 Savage PCI/AGP
+	  chips.
+
+	  Say Y if you have such a graphics card.
+
+	  To compile this driver as a module, choose M here; the module
+	  will be called savagefb.
+
+config FB_SAVAGE_I2C
+       bool "Enable DDC2 Support"
+       depends on FB_SAVAGE
+       select FB_DDC
+       help
+	  This enables I2C support for S3 Savage Chipsets.  This is used
+	  only for getting EDID information from the attached display
+	  allowing for robust video mode handling and switching.
+
+	  Because fbdev-2.6 requires that drivers must be able to
+	  independently validate video mode parameters, you should say Y
+	  here.
+
+config FB_SAVAGE_ACCEL
+       bool "Enable Console Acceleration"
+       depends on FB_SAVAGE
+       default n
+       help
+          This option will compile in console acceleration support. If
+          the resulting framebuffer console has bothersome glitches, then
+          choose N here.
+
+config FB_SIS
+	tristate "SiS/XGI display support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_BOOT_VESA_SUPPORT if FB_SIS = y
+	help
+	  This is the frame buffer device driver for the SiS 300, 315, 330
+	  and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
+	  Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
+
+	  To compile this driver as a module, choose M here; the module
+	  will be called sisfb.
+
+config FB_SIS_300
+	bool "SiS 300 series support"
+	depends on FB_SIS
+	help
+	  Say Y here to support use of the SiS 300/305, 540, 630 and 730.
+
+config FB_SIS_315
+	bool "SiS 315/330/340 series and XGI support"
+	depends on FB_SIS
+	help
+	  Say Y here to support use of the SiS 315, 330 and 340 series
+	  (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
+	  as XGI V3XT, V5, V8 and Z7.
+
+config FB_VIA
+       tristate "VIA UniChrome (Pro) and Chrome9 display support"
+       depends on FB && PCI && X86
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       select I2C_ALGOBIT
+       select I2C
+       select GPIOLIB
+       help
+	  This is the frame buffer device driver for Graphics chips of VIA
+	  UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
+	  CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
+ 	  /P4M900,VX800)
+	  Say Y if you have a VIA UniChrome graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called viafb.
+
+if FB_VIA
+
+config FB_VIA_DIRECT_PROCFS
+	bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
+	depends on FB_VIA
+	default n
+	help
+	  Allow direct hardware access to some output registers via procfs.
+	  This is dangerous but may provide the only chance to get the
+	  correct output device configuration.
+	  Its use is strongly discouraged.
+
+config FB_VIA_X_COMPATIBILITY
+	bool "X server compatibility"
+	depends on FB_VIA
+	default n
+	help
+	  This option reduces the functionality (power saving, ...) of the
+	  framebuffer to avoid negative impact on the OpenChrome X server.
+	  If you use any X server other than fbdev you should enable this
+	  otherwise it should be safe to disable it and allow using all
+	  features.
+
+endif
+
+config FB_NEOMAGIC
+	tristate "NeoMagic display support"
+	depends on FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	help
+	  This driver supports notebooks with NeoMagic PCI chips.
+	  Say Y if you have such a graphics card. 
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called neofb.
+
+config FB_KYRO
+	tristate "IMG Kyro support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
+	  graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called kyrofb.
+
+config FB_3DFX
+	tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
+	depends on FB && PCI
+	select FB_CFB_IMAGEBLIT
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_MODE_HELPERS
+	help
+	  This driver supports graphics boards with the 3Dfx Banshee,
+	  Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
+	  such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tdfxfb.
+
+config FB_3DFX_ACCEL
+	bool "3Dfx Acceleration functions"
+	depends on FB_3DFX
+	---help---
+	This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
+	device driver with acceleration functions.
+
+config FB_3DFX_I2C
+	bool "Enable DDC/I2C support"
+	depends on FB_3DFX
+	select FB_DDC
+	default y
+	help
+	  Say Y here if you want DDC/I2C support for your 3dfx Voodoo3.
+
+config FB_VOODOO1
+	tristate "3Dfx Voodoo Graphics (sst1) support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 
+	  Voodoo2 (cvg) based graphics card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sstfb.
+
+	  WARNING: Do not use any application that uses the 3D engine
+	  (namely glide) while using this driver.
+	  Please read the <file:Documentation/fb/sstfb.txt> for supported
+	  options and other important info  support.
+
+config FB_VT8623
+	tristate "VIA VT8623 support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_TILEBLITTING
+	select FB_SVGALIB
+	select VGASTATE
+	select FONT_8x16 if FRAMEBUFFER_CONSOLE
+	---help---
+	  Driver for CastleRock integrated graphics core in the
+	  VIA VT8623 [Apollo CLE266] chipset.
+
+config FB_TRIDENT
+	tristate "Trident/CyberXXX/CyberBlade support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  This is the frame buffer device driver for Trident PCI/AGP chipsets.
+	  Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
+	  and Blade XP.
+	  There are also integrated versions of these chips called CyberXXXX,
+	  CyberImage or CyberBlade. These chips are mostly found in laptops
+	  but also on some motherboards including early VIA EPIA motherboards.
+	  For more information, read <file:Documentation/fb/tridentfb.txt>
+
+	  Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tridentfb.
+
+config FB_ARK
+	tristate "ARK 2000PV support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_TILEBLITTING
+	select FB_SVGALIB
+	select VGASTATE
+	select FONT_8x16 if FRAMEBUFFER_CONSOLE
+	---help---
+	  Driver for PCI graphics boards with ARK 2000PV chip
+	  and ICS 5342 RAMDAC.
+
+config FB_PM3
+	tristate "Permedia3 support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the 3DLabs Permedia3
+	  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
+	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
+	  and maybe other boards.
+
+config FB_CARMINE
+	tristate "Fujitsu carmine frame buffer support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Fujitsu Carmine chip.
+	  The driver provides two independent frame buffer devices.
+
+choice
+	depends on FB_CARMINE
+	prompt "DRAM timing"
+	default FB_CARMINE_DRAM_EVAL
+
+config FB_CARMINE_DRAM_EVAL
+	bool "Eval board timings"
+	help
+	  Use timings which work on the eval card.
+
+config CARMINE_DRAM_CUSTOM
+	bool "Custom board timings"
+	help
+	  Use custom board timings.
+endchoice
+
+config FB_AU1100
+	bool "Au1100 LCD Driver"
+	depends on (FB = y) && MIPS_ALCHEMY
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer driver for the AMD Au1100 SOC.  It can drive
+	  various panels and CRTs by passing in kernel cmd line option
+	  au1100fb:panel=<name>.
+
+config FB_AU1200
+	bool "Au1200/Au1300 LCD Driver"
+	depends on (FB = y) && MIPS_ALCHEMY
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	help
+	  This is the framebuffer driver for the Au1200/Au1300 SOCs.
+	  It can drive various panels and CRTs by passing in kernel cmd line
+	  option au1200fb:panel=<name>.
+
+config FB_VT8500
+	bool "VIA VT8500 framebuffer support"
+	depends on (FB = y) && ARM && ARCH_VT8500
+	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
+	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
+	select FB_SYS_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	help
+	  This is the framebuffer driver for VIA VT8500 integrated LCD
+	  controller.
+
+config FB_WM8505
+	bool "Wondermedia WM8xxx-series frame buffer support"
+	depends on (FB = y) && ARM && ARCH_VT8500
+	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
+	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
+	select FB_SYS_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	help
+	  This is the framebuffer driver for WonderMedia WM8xxx-series
+	  integrated LCD controller. This driver covers the WM8505, WM8650
+	  and WM8850 SoCs.
+
+config FB_WMT_GE_ROPS
+	bool "VT8500/WM8xxx accelerated raster ops support"
+	depends on (FB = y) && (FB_VT8500 || FB_WM8505)
+	default n
+	help
+	  This adds support for accelerated raster operations on the
+	  VIA VT8500 and Wondermedia 85xx series SoCs.
+
+source "drivers/video/fbdev/geode/Kconfig"
+
+config FB_HIT
+	tristate "HD64461 Frame Buffer support"
+	depends on FB && HD64461
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Hitachi HD64461 LCD
+	  frame buffer card.
+
+config FB_PMAG_AA
+	bool "PMAG-AA TURBOchannel framebuffer support"
+	depends on (FB = y) && TC
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
+	  used mainly in the MIPS-based DECstation series.
+
+config FB_PMAG_BA
+	tristate "PMAG-BA TURBOchannel framebuffer support"
+	depends on FB && TC
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
+	  used mainly in the MIPS-based DECstation series.
+
+config FB_PMAGB_B
+	tristate "PMAGB-B TURBOchannel framebuffer support"
+	depends on FB && TC
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly
+	  in the MIPS-based DECstation series. The card is currently only
+	  supported in 1280x1024x8 mode.
+
+config FB_MAXINE
+	bool "Maxine (Personal DECstation) onboard framebuffer support"
+	depends on (FB = y) && MACH_DECSTATION
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the onboard framebuffer (1024x768x8) in the Personal
+	  DECstation series (Personal DECstation 5000/20, /25, /33, /50,
+	  Codename "Maxine").
+
+config FB_G364
+	bool "G364 frame buffer support"
+	depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and
+	  Olivetti M700-10 systems.
+
+config FB_68328
+	bool "Motorola 68328 native frame buffer support"
+	depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328)
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y here if you want to support the built-in frame buffer of
+	  the Motorola 68328 CPU family.
+
+config FB_PXA168
+	tristate "PXA168/910 LCD framebuffer support"
+	depends on FB && (CPU_PXA168 || CPU_PXA910)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the built-in LCD controller in the Marvell
+	  MMP processor.
+
+config FB_PXA
+	tristate "PXA LCD framebuffer support"
+	depends on FB && ARCH_PXA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the built-in LCD controller in the Intel
+	  PXA2x0 processor.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called pxafb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
+config FB_PXA_OVERLAY
+	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
+	default n
+	depends on FB_PXA && (PXA27x || PXA3xx)
+
+config FB_PXA_SMARTPANEL
+	bool "PXA Smartpanel LCD support"
+	default n
+	depends on FB_PXA
+
+config FB_PXA_PARAMETERS
+	bool "PXA LCD command line parameters"
+	default n
+	depends on FB_PXA
+	---help---
+	  Enable the use of kernel command line or module parameters
+	  to configure the physical properties of the LCD panel when
+	  using the PXA LCD driver.
+
+	  This option allows you to override the panel parameters
+	  supplied by the platform in order to support multiple
+	  different models of flatpanel. If you will only be using a
+	  single model of flatpanel then you can safely leave this
+	  option disabled.
+
+	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
+
+config PXA3XX_GCU
+	tristate "PXA3xx 2D graphics accelerator driver"
+	depends on FB_PXA
+	help
+	  Kernelspace driver for the 2D graphics controller unit (GCU)
+	  found on PXA3xx processors. There is a counterpart driver in the
+	  DirectFB suite, see http://www.directfb.org/
+
+	  If you compile this as a module, it will be called pxa3xx_gcu.
+
+config FB_MBX
+	tristate "2700G LCD framebuffer support"
+	depends on FB && ARCH_PXA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Framebuffer driver for the Intel 2700G (Marathon) Graphics
+	  Accelerator
+
+config FB_MBX_DEBUG
+       bool "Enable debugging info via debugfs"
+       depends on FB_MBX && DEBUG_FS
+       default n
+       ---help---
+         Enable this if you want debugging information using the debug
+         filesystem (debugfs)
+
+         If unsure, say N.
+
+config FB_FSL_DIU
+	tristate "Freescale DIU framebuffer support"
+	depends on FB && FSL_SOC
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select PPC_LIB_RHEAP
+	---help---
+	  Framebuffer driver for the Freescale SoC DIU
+
+config FB_W100
+	tristate "W100 frame buffer support"
+	depends on FB && ARCH_PXA
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+	  It can also drive the w3220 chip found on iPAQ hx4700.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called w100fb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
+config FB_SH_MOBILE_LCDC
+	tristate "SuperH Mobile LCDC framebuffer support"
+	depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	select FB_BACKLIGHT
+	select SH_MIPI_DSI if SH_LCD_MIPI_DSI
+	---help---
+	  Frame buffer driver for the on-chip SH-Mobile LCD controller.
+
+config FB_SH_MOBILE_HDMI
+	tristate "SuperH Mobile HDMI controller support"
+	depends on FB_SH_MOBILE_LCDC
+	select FB_MODE_HELPERS
+	select SOUND
+	select SND
+	select SND_SOC
+	---help---
+	  Driver for the on-chip SH-Mobile HDMI controller.
+
+config FB_TMIO
+	tristate "Toshiba Mobile IO FrameBuffer support"
+	depends on FB && MFD_CORE
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the Toshiba Mobile IO integrated as found
+	  on the Sharp SL-6000 series
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called tmiofb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
+config FB_TMIO_ACCELL
+	bool "tmiofb acceleration"
+	depends on FB_TMIO
+	default y
+
+config FB_S3C
+	tristate "Samsung S3C framebuffer support"
+	depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
+		ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the built-in FB controller in the Samsung
+	  SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
+	  and the S3C64XX series such as the S3C6400 and S3C6410.
+
+	  These chips all have the same basic framebuffer design with the
+	  actual capabilities depending on the chip. For instance the S3C6400
+	  and S3C6410 support 4 hardware windows whereas the S3C24XX series
+	  currently only have two.
+
+	  Currently the support is only for the S3C6400 and S3C6410 SoCs.
+
+config FB_S3C_DEBUG_REGWRITE
+       bool "Debug register writes"
+       depends on FB_S3C
+       ---help---
+         Show all register writes via pr_debug()
+
+config FB_S3C2410
+	tristate "S3C2410 LCD framebuffer support"
+	depends on FB && ARCH_S3C24XX
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the built-in LCD controller in the Samsung
+	  S3C2410 processor.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called s3c2410fb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+config FB_S3C2410_DEBUG
+	bool "S3C2410 lcd debug messages"
+	depends on FB_S3C2410
+	help
+	  Turn on debugging messages. Note that you can set/unset at run time
+	  through sysfs
+
+config FB_NUC900
+        bool "NUC900 LCD framebuffer support"
+        depends on FB && ARCH_W90X900
+        select FB_CFB_FILLRECT
+        select FB_CFB_COPYAREA
+        select FB_CFB_IMAGEBLIT
+        ---help---
+          Frame buffer driver for the built-in LCD controller in the Nuvoton
+          NUC900 processor
+
+config GPM1040A0_320X240
+        bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
+        depends on FB_NUC900
+
+config FB_SM501
+	tristate "Silicon Motion SM501 framebuffer support"
+	depends on FB && MFD_SM501
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the CRT and LCD controllers in the Silicon
+	  Motion SM501.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called sm501fb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
+config FB_SMSCUFX
+	tristate "SMSC UFX6000/7000 USB Framebuffer support"
+	depends on FB && USB
+	select FB_MODE_HELPERS
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	---help---
+	  This is a kernel framebuffer driver for SMSC UFX USB devices.
+	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+	  mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
+	  (USB 3.0) devices.
+	  To compile as a module, choose M here: the module name is smscufx.
+
+config FB_UDL
+	tristate "Displaylink USB Framebuffer support"
+	depends on FB && USB
+	select FB_MODE_HELPERS
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	---help---
+	  This is a kernel framebuffer driver for DisplayLink USB devices.
+	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+	  mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
+	  To compile as a module, choose M here: the module name is udlfb.
+
+config FB_IBM_GXT4500
+	tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors"
+	depends on FB && PPC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Say Y here to enable support for the IBM GXT4000P/6000P and
+	  GXT4500P/6500P display adaptor based on Raster Engine RC1000,
+	  found on some IBM System P (pSeries) machines. This driver
+	  doesn't use Geometry Engine GT1000.
+
+config FB_PS3
+	tristate "PS3 GPU framebuffer driver"
+	depends on FB && PS3_PS3AV
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
+	---help---
+	  Include support for the virtual frame buffer in the PS3 platform.
+
+config FB_PS3_DEFAULT_SIZE_M
+	int "PS3 default frame buffer size (in MiB)"
+	depends on FB_PS3
+	default 9
+	---help---
+	  This is the default size (in MiB) of the virtual frame buffer in
+	  the PS3.
+	  The default value can be overridden on the kernel command line
+	  using the "ps3fb" option (e.g. "ps3fb=9M");
+
+config FB_XILINX
+	tristate "Xilinx frame buffer support"
+	depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Include support for the Xilinx ML300/ML403 reference design
+	  framebuffer. ML300 carries a 640*480 LCD display on the board,
+	  ML403 uses a standard DB15 VGA connector.
+
+config FB_GOLDFISH
+	tristate "Goldfish Framebuffer"
+	depends on FB && HAS_DMA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Framebuffer driver for Goldfish Virtual Platform
+
+config FB_COBALT
+	tristate "Cobalt server LCD frame buffer support"
+	depends on FB && (MIPS_COBALT || MIPS_SEAD3)
+
+config FB_SH7760
+	bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
+	depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
+		|| CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Support for the SH7760/SH7763/SH7720/SH7721 integrated
+	  (D)STN/TFT LCD Controller.
+	  Supports display resolutions up to 1024x1024 pixel, grayscale and
+	  color operation, with depths ranging from 1 bpp to 8 bpp monochrome
+	  and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
+	  panels <= 320 pixel horizontal resolution.
+
+config FB_DA8XX
+	tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
+	depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_CFB_REV_PIXELS_IN_BYTE
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	---help---
+	  This is the frame buffer device driver for the TI LCD controller
+	  found on DA8xx/OMAP-L1xx/AM335x SoCs.
+	  If unsure, say N.
+
+config FB_VIRTUAL
+	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+	depends on FB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	---help---
+	  This is a `virtual' frame buffer device. It operates on a chunk of
+	  unswappable kernel memory instead of on the memory of a graphics
+	  board. This means you cannot see any output sent to this frame
+	  buffer device, while it does consume precious memory. The main use
+	  of this frame buffer device is testing and debugging the frame
+	  buffer subsystem. Do NOT enable it for normal systems! To protect
+	  the innocent, it has to be enabled explicitly at boot time using the
+	  kernel option `video=vfb:'.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vfb. In order to load it, you must use
+	  the vfb_enable=1 option.
+
+	  If unsure, say N.
+
+config XEN_FBDEV_FRONTEND
+	tristate "Xen virtual frame buffer support"
+	depends on FB && XEN
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
+	select XEN_XENBUS_FRONTEND
+	default y
+	help
+	  This driver implements the front-end of the Xen virtual
+	  frame buffer driver.  It communicates with a back-end
+	  in another domain.
+
+config FB_METRONOME
+	tristate "E-Ink Metronome/8track controller support"
+	depends on FB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	help
+	  This driver implements support for the E-Ink Metronome
+	  controller. The pre-release name for this device was 8track
+	  and could also have been called by some vendors as PVI-nnnn.
+
+config FB_MB862XX
+	tristate "Fujitsu MB862xx GDC support"
+	depends on FB
+	depends on PCI || (OF && PPC)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
+
+choice
+	prompt "GDC variant"
+	depends on FB_MB862XX
+
+config FB_MB862XX_PCI_GDC
+	bool "Carmine/Coral-P(A) GDC"
+	depends on PCI
+	---help---
+	  This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
+	  PCI graphics controller devices.
+
+config FB_MB862XX_LIME
+	bool "Lime GDC"
+	depends on OF && PPC
+	select FB_FOREIGN_ENDIAN
+	select FB_LITTLE_ENDIAN
+	---help---
+	  Framebuffer support for Fujitsu Lime GDC on host CPU bus.
+
+endchoice
+
+config FB_MB862XX_I2C
+	bool "Support I2C bus on MB862XX GDC"
+	depends on FB_MB862XX && I2C
+	default y
+	help
+	  Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
+	  driver to support accessing I2C devices on controller's I2C bus.
+	  These are usually some video decoder chips.
+
+config FB_EP93XX
+	tristate "EP93XX frame buffer support"
+	depends on FB && ARCH_EP93XX
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Framebuffer driver for the Cirrus Logic EP93XX series of processors.
+	  This driver is also available as a module. The module will be called
+	  ep93xx-fb.
+
+config FB_PRE_INIT_FB
+	bool "Don't reinitialize, use bootloader's GDC/Display configuration"
+	depends on FB && FB_MB862XX_LIME
+	---help---
+	  Select this option if display contents should be inherited as set by
+	  the bootloader.
+
+config FB_MSM
+	tristate "MSM Framebuffer support"
+	depends on FB && ARCH_MSM
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+
+config FB_MX3
+	tristate "MX3 Framebuffer support"
+	depends on FB && MX3_IPU
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	default y
+	help
+	  This is a framebuffer device for the i.MX31 LCD Controller. So
+	  far only synchronous displays are supported. If you plan to use
+	  an LCD display with your i.MX31 system, say Y here.
+
+config FB_BROADSHEET
+	tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
+	depends on FB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	help
+	  This driver implements support for the E-Ink Broadsheet
+	  controller. The release name for this device was Epson S1D13521
+	  and could also have been called by other names when coupled with
+	  a bridge adapter.
+
+config FB_AUO_K190X
+	tristate "AUO-K190X EPD controller support"
+	depends on FB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	help
+	  Provides support for epaper controllers from the K190X series
+	  of AUO. These controllers can be used to drive epaper displays
+	  from Sipix.
+
+	  This option enables the common support, shared by the individual
+	  controller drivers. You will also have to enable the driver
+	  for the controller type used in your device.
+
+config FB_AUO_K1900
+	tristate "AUO-K1900 EPD controller support"
+	depends on FB && FB_AUO_K190X
+	help
+	  This driver implements support for the AUO K1900 epd-controller.
+	  This controller can drive Sipix epaper displays but can only do
+	  serial updates, reducing the number of possible frames per second.
+
+config FB_AUO_K1901
+	tristate "AUO-K1901 EPD controller support"
+	depends on FB && FB_AUO_K190X
+	help
+	  This driver implements support for the AUO K1901 epd-controller.
+	  This controller can drive Sipix epaper displays and supports
+	  concurrent updates, making higher frames per second possible.
+
+config FB_JZ4740
+	tristate "JZ4740 LCD framebuffer support"
+	depends on FB && MACH_JZ4740
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	help
+	  Framebuffer support for the JZ4740 SoC.
+
+config FB_MXS
+	tristate "MXS LCD framebuffer support"
+	depends on FB && ARCH_MXS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	help
+	  Framebuffer support for the MXS SoC.
+
+config FB_PUV3_UNIGFX
+	tristate "PKUnity v3 Unigfx framebuffer support"
+	depends on FB && UNICORE32 && ARCH_PUV3
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	help
+	  Choose this option if you want to use the Unigfx device as a
+	  framebuffer device. Without the support of PCI & AGP.
+
+config FB_HYPERV
+	tristate "Microsoft Hyper-V Synthetic Video support"
+	depends on FB && HYPERV
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
+
+config FB_SIMPLE
+	bool "Simple framebuffer support"
+	depends on (FB = y)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y if you want support for a simple frame-buffer.
+
+	  This driver assumes that the display hardware has been initialized
+	  before the kernel boots, and the kernel will simply render to the
+	  pre-allocated frame buffer surface.
+
+	  Configuration re: surface address, size, and format must be provided
+	  through device tree, or plain old platform data.
+
+source "drivers/video/fbdev/omap/Kconfig"
+source "drivers/video/fbdev/omap2/Kconfig"
+source "drivers/video/fbdev/exynos/Kconfig"
+source "drivers/video/fbdev/mmp/Kconfig"
+
+config FB_SH_MOBILE_MERAM
+	tristate "SuperH Mobile MERAM read ahead support"
+	depends on (SUPERH || ARCH_SHMOBILE)
+	select GENERIC_ALLOCATOR
+	---help---
+	  Enable MERAM support for the SuperH controller.
+
+	  This will allow for caching of the framebuffer to provide more
+	  reliable access under heavy main memory bus traffic situations.
+	  Up to 4 memory channels can be configured, allowing 4 RGB or
+	  2 YCbCr framebuffers to be configured.
+
+config FB_SSD1307
+	tristate "Solomon SSD1307 framebuffer support"
+	depends on FB && I2C
+	depends on OF
+	depends on GPIOLIB
+	select FB_SYS_FOPS
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_DEFERRED_IO
+	select PWM
+	help
+	  This driver implements support for the Solomon SSD1307
+	  OLED controller over I2C.
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
new file mode 100644
index 0000000..0284f2a
--- /dev/null
+++ b/drivers/video/fbdev/Makefile
@@ -0,0 +1,152 @@
+# Makefile for the Linux video drivers.
+# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
+# Rewritten to use lists instead of if-statements.
+
+# Each configuration option enables a list of files.
+
+obj-y				+= core/
+
+obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/
+
+obj-$(CONFIG_FB_MACMODES)      += macmodes.o
+obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o
+
+# Hardware specific drivers go first
+obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
+obj-$(CONFIG_FB_ARC)              += arcfb.o
+obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
+obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
+obj-$(CONFIG_FB_GRVGA)            += grvga.o
+obj-$(CONFIG_FB_PM2)              += pm2fb.o
+obj-$(CONFIG_FB_PM3)		  += pm3fb.o
+
+obj-$(CONFIG_FB_I740)		  += i740fb.o
+obj-$(CONFIG_FB_MATROX)		  += matrox/
+obj-$(CONFIG_FB_RIVA)		  += riva/
+obj-$(CONFIG_FB_NVIDIA)		  += nvidia/
+obj-$(CONFIG_FB_ATY)		  += aty/ macmodes.o
+obj-$(CONFIG_FB_ATY128)		  += aty/ macmodes.o
+obj-$(CONFIG_FB_RADEON)		  += aty/
+obj-$(CONFIG_FB_SIS)		  += sis/
+obj-$(CONFIG_FB_VIA)		  += via/
+obj-$(CONFIG_FB_KYRO)             += kyro/
+obj-$(CONFIG_FB_SAVAGE)		  += savage/
+obj-$(CONFIG_FB_GEODE)		  += geode/
+obj-$(CONFIG_FB_MBX)		  += mbx/
+obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o
+obj-$(CONFIG_FB_3DFX)             += tdfxfb.o
+obj-$(CONFIG_FB_CONTROL)          += controlfb.o
+obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o
+obj-$(CONFIG_FB_VALKYRIE)         += valkyriefb.o
+obj-$(CONFIG_FB_CT65550)          += chipsfb.o
+obj-$(CONFIG_FB_IMSTT)            += imsttfb.o
+obj-$(CONFIG_FB_FM2)              += fm2fb.o
+obj-$(CONFIG_FB_VT8623)           += vt8623fb.o
+obj-$(CONFIG_FB_TRIDENT)          += tridentfb.o
+obj-$(CONFIG_FB_LE80578)          += vermilion/
+obj-$(CONFIG_FB_S3)               += s3fb.o
+obj-$(CONFIG_FB_ARK)              += arkfb.o
+obj-$(CONFIG_FB_STI)              += stifb.o
+obj-$(CONFIG_FB_FFB)              += ffb.o sbuslib.o
+obj-$(CONFIG_FB_CG6)              += cg6.o sbuslib.o
+obj-$(CONFIG_FB_CG3)              += cg3.o sbuslib.o
+obj-$(CONFIG_FB_BW2)              += bw2.o sbuslib.o
+obj-$(CONFIG_FB_CG14)             += cg14.o sbuslib.o
+obj-$(CONFIG_FB_P9100)            += p9100.o sbuslib.o
+obj-$(CONFIG_FB_TCX)              += tcx.o sbuslib.o
+obj-$(CONFIG_FB_LEO)              += leo.o sbuslib.o
+obj-$(CONFIG_FB_ACORN)            += acornfb.o
+obj-$(CONFIG_FB_ATARI)            += atafb.o c2p_iplan2.o atafb_mfb.o \
+                                     atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
+obj-$(CONFIG_FB_MAC)              += macfb.o
+obj-$(CONFIG_FB_HECUBA)           += hecubafb.o
+obj-$(CONFIG_FB_N411)             += n411.o
+obj-$(CONFIG_FB_HGA)              += hgafb.o
+obj-$(CONFIG_FB_XVR500)           += sunxvr500.o
+obj-$(CONFIG_FB_XVR2500)          += sunxvr2500.o
+obj-$(CONFIG_FB_XVR1000)          += sunxvr1000.o
+obj-$(CONFIG_FB_IGA)              += igafb.o
+obj-$(CONFIG_FB_APOLLO)           += dnfb.o
+obj-$(CONFIG_FB_Q40)              += q40fb.o
+obj-$(CONFIG_FB_TGA)              += tgafb.o
+obj-$(CONFIG_FB_HP300)            += hpfb.o
+obj-$(CONFIG_FB_G364)             += g364fb.o
+obj-$(CONFIG_FB_EP93XX)		  += ep93xx-fb.o
+obj-$(CONFIG_FB_SA1100)           += sa1100fb.o
+obj-$(CONFIG_FB_HIT)              += hitfb.o
+obj-$(CONFIG_FB_ATMEL)		  += atmel_lcdfb.o
+obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
+obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
+obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o
+obj-$(CONFIG_FB_GOLDFISH)         += goldfishfb.o
+obj-$(CONFIG_FB_68328)            += 68328fb.o
+obj-$(CONFIG_FB_GBE)              += gbefb.o
+obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o
+obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o
+obj-$(CONFIG_FB_PXA)		  += pxafb.o
+obj-$(CONFIG_FB_PXA168)		  += pxa168fb.o
+obj-$(CONFIG_PXA3XX_GCU)	  += pxa3xx-gcu.o
+obj-$(CONFIG_MMP_DISP)           += mmp/
+obj-$(CONFIG_FB_W100)		  += w100fb.o
+obj-$(CONFIG_FB_TMIO)		  += tmiofb.o
+obj-$(CONFIG_FB_AU1100)		  += au1100fb.o
+obj-$(CONFIG_FB_AU1200)		  += au1200fb.o
+obj-$(CONFIG_FB_VT8500)		  += vt8500lcdfb.o
+obj-$(CONFIG_FB_WM8505)		  += wm8505fb.o
+obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o
+obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o
+obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o
+obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o
+obj-$(CONFIG_FB_METRONOME)        += metronomefb.o
+obj-$(CONFIG_FB_BROADSHEET)       += broadsheetfb.o
+obj-$(CONFIG_FB_AUO_K190X)	  += auo_k190x.o
+obj-$(CONFIG_FB_AUO_K1900)	  += auo_k1900fb.o
+obj-$(CONFIG_FB_AUO_K1901)	  += auo_k1901fb.o
+obj-$(CONFIG_FB_S1D13XXX)	  += s1d13xxxfb.o
+obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
+obj-$(CONFIG_FB_IMX)              += imxfb.o
+obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
+obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
+obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
+obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
+obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
+obj-$(CONFIG_FB_PS3)		  += ps3fb.o
+obj-$(CONFIG_FB_SM501)            += sm501fb.o
+obj-$(CONFIG_FB_UDL)		  += udlfb.o
+obj-$(CONFIG_FB_SMSCUFX)	  += smscufx.o
+obj-$(CONFIG_FB_XILINX)           += xilinxfb.o
+obj-$(CONFIG_SH_MIPI_DSI)	  += sh_mipi_dsi.o
+obj-$(CONFIG_FB_SH_MOBILE_HDMI)	  += sh_mobile_hdmi.o
+obj-$(CONFIG_FB_SH_MOBILE_MERAM)  += sh_mobile_meram.o
+obj-$(CONFIG_FB_SH_MOBILE_LCDC)	  += sh_mobile_lcdcfb.o
+obj-$(CONFIG_FB_OMAP)             += omap/
+obj-y                             += omap2/
+obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o
+obj-$(CONFIG_FB_CARMINE)          += carminefb.o
+obj-$(CONFIG_FB_MB862XX)	  += mb862xx/
+obj-$(CONFIG_FB_MSM)              += msm/
+obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
+obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o
+obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
+obj-$(CONFIG_FB_HYPERV)		  += hyperv_fb.o
+obj-$(CONFIG_FB_OPENCORES)	  += ocfb.o
+
+# Platform or fallback drivers go here
+obj-$(CONFIG_FB_UVESA)            += uvesafb.o
+obj-$(CONFIG_FB_VESA)             += vesafb.o
+obj-$(CONFIG_FB_EFI)              += efifb.o
+obj-$(CONFIG_FB_VGA16)            += vga16fb.o
+obj-$(CONFIG_FB_OF)               += offb.o
+obj-$(CONFIG_FB_BF537_LQ035)      += bf537-lq035.o
+obj-$(CONFIG_FB_BF54X_LQ043)	  += bf54x-lq043fb.o
+obj-$(CONFIG_FB_BFIN_LQ035Q1)     += bfin-lq035q1-fb.o
+obj-$(CONFIG_FB_BFIN_T350MCQB)	  += bfin-t350mcqb-fb.o
+obj-$(CONFIG_FB_BFIN_7393)        += bfin_adv7393fb.o
+obj-$(CONFIG_FB_MX3)		  += mx3fb.o
+obj-$(CONFIG_FB_DA8XX)		  += da8xx-fb.o
+obj-$(CONFIG_FB_MXS)		  += mxsfb.o
+obj-$(CONFIG_FB_SSD1307)	  += ssd1307fb.o
+obj-$(CONFIG_FB_SIMPLE)           += simplefb.o
+
+# the test framebuffer is last
+obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
diff --git a/drivers/video/acornfb.c b/drivers/video/fbdev/acornfb.c
similarity index 100%
rename from drivers/video/acornfb.c
rename to drivers/video/fbdev/acornfb.c
diff --git a/drivers/video/acornfb.h b/drivers/video/fbdev/acornfb.h
similarity index 100%
rename from drivers/video/acornfb.h
rename to drivers/video/fbdev/acornfb.h
diff --git a/drivers/video/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
similarity index 100%
rename from drivers/video/amba-clcd.c
rename to drivers/video/fbdev/amba-clcd.c
diff --git a/drivers/video/amifb.c b/drivers/video/fbdev/amifb.c
similarity index 100%
rename from drivers/video/amifb.c
rename to drivers/video/fbdev/amifb.c
diff --git a/drivers/video/arcfb.c b/drivers/video/fbdev/arcfb.c
similarity index 100%
rename from drivers/video/arcfb.c
rename to drivers/video/fbdev/arcfb.c
diff --git a/drivers/video/arkfb.c b/drivers/video/fbdev/arkfb.c
similarity index 100%
rename from drivers/video/arkfb.c
rename to drivers/video/fbdev/arkfb.c
diff --git a/drivers/video/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c
similarity index 100%
rename from drivers/video/asiliantfb.c
rename to drivers/video/fbdev/asiliantfb.c
diff --git a/drivers/video/atafb.c b/drivers/video/fbdev/atafb.c
similarity index 100%
rename from drivers/video/atafb.c
rename to drivers/video/fbdev/atafb.c
diff --git a/drivers/video/atafb.h b/drivers/video/fbdev/atafb.h
similarity index 100%
rename from drivers/video/atafb.h
rename to drivers/video/fbdev/atafb.h
diff --git a/drivers/video/atafb_iplan2p2.c b/drivers/video/fbdev/atafb_iplan2p2.c
similarity index 100%
rename from drivers/video/atafb_iplan2p2.c
rename to drivers/video/fbdev/atafb_iplan2p2.c
diff --git a/drivers/video/atafb_iplan2p4.c b/drivers/video/fbdev/atafb_iplan2p4.c
similarity index 100%
rename from drivers/video/atafb_iplan2p4.c
rename to drivers/video/fbdev/atafb_iplan2p4.c
diff --git a/drivers/video/atafb_iplan2p8.c b/drivers/video/fbdev/atafb_iplan2p8.c
similarity index 100%
rename from drivers/video/atafb_iplan2p8.c
rename to drivers/video/fbdev/atafb_iplan2p8.c
diff --git a/drivers/video/atafb_mfb.c b/drivers/video/fbdev/atafb_mfb.c
similarity index 100%
rename from drivers/video/atafb_mfb.c
rename to drivers/video/fbdev/atafb_mfb.c
diff --git a/drivers/video/atafb_utils.h b/drivers/video/fbdev/atafb_utils.h
similarity index 100%
rename from drivers/video/atafb_utils.h
rename to drivers/video/fbdev/atafb_utils.h
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
similarity index 100%
rename from drivers/video/atmel_lcdfb.c
rename to drivers/video/fbdev/atmel_lcdfb.c
diff --git a/drivers/video/aty/Makefile b/drivers/video/fbdev/aty/Makefile
similarity index 100%
rename from drivers/video/aty/Makefile
rename to drivers/video/fbdev/aty/Makefile
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/fbdev/aty/ati_ids.h
similarity index 100%
rename from drivers/video/aty/ati_ids.h
rename to drivers/video/fbdev/aty/ati_ids.h
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
similarity index 100%
rename from drivers/video/aty/aty128fb.c
rename to drivers/video/fbdev/aty/aty128fb.c
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h
similarity index 100%
rename from drivers/video/aty/atyfb.h
rename to drivers/video/fbdev/aty/atyfb.h
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
similarity index 100%
rename from drivers/video/aty/atyfb_base.c
rename to drivers/video/fbdev/aty/atyfb_base.c
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c
similarity index 100%
rename from drivers/video/aty/mach64_accel.c
rename to drivers/video/fbdev/aty/mach64_accel.c
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c
similarity index 100%
rename from drivers/video/aty/mach64_ct.c
rename to drivers/video/fbdev/aty/mach64_ct.c
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c
similarity index 99%
rename from drivers/video/aty/mach64_cursor.c
rename to drivers/video/fbdev/aty/mach64_cursor.c
index 0fe02e2..2fa0317 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/fbdev/aty/mach64_cursor.c
@@ -5,7 +5,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include "../fb_draw.h"
+#include "../core/fb_draw.h"
 
 #include <asm/io.h>
 
diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/fbdev/aty/mach64_gx.c
similarity index 100%
rename from drivers/video/aty/mach64_gx.c
rename to drivers/video/fbdev/aty/mach64_gx.c
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/fbdev/aty/radeon_accel.c
similarity index 100%
rename from drivers/video/aty/radeon_accel.c
rename to drivers/video/fbdev/aty/radeon_accel.c
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c
similarity index 100%
rename from drivers/video/aty/radeon_backlight.c
rename to drivers/video/fbdev/aty/radeon_backlight.c
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
similarity index 100%
rename from drivers/video/aty/radeon_base.c
rename to drivers/video/fbdev/aty/radeon_base.c
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/fbdev/aty/radeon_i2c.c
similarity index 100%
rename from drivers/video/aty/radeon_i2c.c
rename to drivers/video/fbdev/aty/radeon_i2c.c
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c
similarity index 100%
rename from drivers/video/aty/radeon_monitor.c
rename to drivers/video/fbdev/aty/radeon_monitor.c
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/fbdev/aty/radeon_pm.c
similarity index 100%
rename from drivers/video/aty/radeon_pm.c
rename to drivers/video/fbdev/aty/radeon_pm.c
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/fbdev/aty/radeonfb.h
similarity index 100%
rename from drivers/video/aty/radeonfb.h
rename to drivers/video/fbdev/aty/radeonfb.h
diff --git a/drivers/video/au1100fb.c b/drivers/video/fbdev/au1100fb.c
similarity index 100%
rename from drivers/video/au1100fb.c
rename to drivers/video/fbdev/au1100fb.c
diff --git a/drivers/video/au1100fb.h b/drivers/video/fbdev/au1100fb.h
similarity index 100%
rename from drivers/video/au1100fb.h
rename to drivers/video/fbdev/au1100fb.h
diff --git a/drivers/video/au1200fb.c b/drivers/video/fbdev/au1200fb.c
similarity index 100%
rename from drivers/video/au1200fb.c
rename to drivers/video/fbdev/au1200fb.c
diff --git a/drivers/video/au1200fb.h b/drivers/video/fbdev/au1200fb.h
similarity index 100%
rename from drivers/video/au1200fb.h
rename to drivers/video/fbdev/au1200fb.h
diff --git a/drivers/video/auo_k1900fb.c b/drivers/video/fbdev/auo_k1900fb.c
similarity index 100%
rename from drivers/video/auo_k1900fb.c
rename to drivers/video/fbdev/auo_k1900fb.c
diff --git a/drivers/video/auo_k1901fb.c b/drivers/video/fbdev/auo_k1901fb.c
similarity index 100%
rename from drivers/video/auo_k1901fb.c
rename to drivers/video/fbdev/auo_k1901fb.c
diff --git a/drivers/video/auo_k190x.c b/drivers/video/fbdev/auo_k190x.c
similarity index 100%
rename from drivers/video/auo_k190x.c
rename to drivers/video/fbdev/auo_k190x.c
diff --git a/drivers/video/auo_k190x.h b/drivers/video/fbdev/auo_k190x.h
similarity index 100%
rename from drivers/video/auo_k190x.h
rename to drivers/video/fbdev/auo_k190x.h
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/fbdev/bf537-lq035.c
similarity index 100%
rename from drivers/video/bf537-lq035.c
rename to drivers/video/fbdev/bf537-lq035.c
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/fbdev/bf54x-lq043fb.c
similarity index 99%
rename from drivers/video/bf54x-lq043fb.c
rename to drivers/video/fbdev/bf54x-lq043fb.c
index 42b8f9d..e2c42ad 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/fbdev/bf54x-lq043fb.c
@@ -49,13 +49,13 @@
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 
 #include <asm/blackfin.h>
 #include <asm/irq.h>
 #include <asm/dpmc.h>
 #include <asm/dma-mapping.h>
 #include <asm/dma.h>
-#include <asm/gpio.h>
 #include <asm/portmux.h>
 
 #include <mach/bf54x-lq043.h>
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/fbdev/bfin-lq035q1-fb.c
similarity index 100%
rename from drivers/video/bfin-lq035q1-fb.c
rename to drivers/video/fbdev/bfin-lq035q1-fb.c
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/fbdev/bfin-t350mcqb-fb.c
similarity index 100%
rename from drivers/video/bfin-t350mcqb-fb.c
rename to drivers/video/fbdev/bfin-t350mcqb-fb.c
diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/fbdev/bfin_adv7393fb.c
similarity index 100%
rename from drivers/video/bfin_adv7393fb.c
rename to drivers/video/fbdev/bfin_adv7393fb.c
diff --git a/drivers/video/bfin_adv7393fb.h b/drivers/video/fbdev/bfin_adv7393fb.h
similarity index 100%
rename from drivers/video/bfin_adv7393fb.h
rename to drivers/video/fbdev/bfin_adv7393fb.h
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c
similarity index 100%
rename from drivers/video/broadsheetfb.c
rename to drivers/video/fbdev/broadsheetfb.c
diff --git a/drivers/video/bt431.h b/drivers/video/fbdev/bt431.h
similarity index 100%
rename from drivers/video/bt431.h
rename to drivers/video/fbdev/bt431.h
diff --git a/drivers/video/bt455.h b/drivers/video/fbdev/bt455.h
similarity index 100%
rename from drivers/video/bt455.h
rename to drivers/video/fbdev/bt455.h
diff --git a/drivers/video/bw2.c b/drivers/video/fbdev/bw2.c
similarity index 100%
rename from drivers/video/bw2.c
rename to drivers/video/fbdev/bw2.c
diff --git a/drivers/video/c2p.h b/drivers/video/fbdev/c2p.h
similarity index 100%
rename from drivers/video/c2p.h
rename to drivers/video/fbdev/c2p.h
diff --git a/drivers/video/c2p_core.h b/drivers/video/fbdev/c2p_core.h
similarity index 100%
rename from drivers/video/c2p_core.h
rename to drivers/video/fbdev/c2p_core.h
diff --git a/drivers/video/c2p_iplan2.c b/drivers/video/fbdev/c2p_iplan2.c
similarity index 100%
rename from drivers/video/c2p_iplan2.c
rename to drivers/video/fbdev/c2p_iplan2.c
diff --git a/drivers/video/c2p_planar.c b/drivers/video/fbdev/c2p_planar.c
similarity index 100%
rename from drivers/video/c2p_planar.c
rename to drivers/video/fbdev/c2p_planar.c
diff --git a/drivers/video/carminefb.c b/drivers/video/fbdev/carminefb.c
similarity index 100%
rename from drivers/video/carminefb.c
rename to drivers/video/fbdev/carminefb.c
diff --git a/drivers/video/carminefb.h b/drivers/video/fbdev/carminefb.h
similarity index 100%
rename from drivers/video/carminefb.h
rename to drivers/video/fbdev/carminefb.h
diff --git a/drivers/video/carminefb_regs.h b/drivers/video/fbdev/carminefb_regs.h
similarity index 100%
rename from drivers/video/carminefb_regs.h
rename to drivers/video/fbdev/carminefb_regs.h
diff --git a/drivers/video/cg14.c b/drivers/video/fbdev/cg14.c
similarity index 100%
rename from drivers/video/cg14.c
rename to drivers/video/fbdev/cg14.c
diff --git a/drivers/video/cg3.c b/drivers/video/fbdev/cg3.c
similarity index 100%
rename from drivers/video/cg3.c
rename to drivers/video/fbdev/cg3.c
diff --git a/drivers/video/cg6.c b/drivers/video/fbdev/cg6.c
similarity index 100%
rename from drivers/video/cg6.c
rename to drivers/video/fbdev/cg6.c
diff --git a/drivers/video/chipsfb.c b/drivers/video/fbdev/chipsfb.c
similarity index 100%
rename from drivers/video/chipsfb.c
rename to drivers/video/fbdev/chipsfb.c
diff --git a/drivers/video/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
similarity index 100%
rename from drivers/video/cirrusfb.c
rename to drivers/video/fbdev/cirrusfb.c
diff --git a/drivers/video/clps711xfb.c b/drivers/video/fbdev/clps711xfb.c
similarity index 100%
rename from drivers/video/clps711xfb.c
rename to drivers/video/fbdev/clps711xfb.c
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c
similarity index 100%
rename from drivers/video/cobalt_lcdfb.c
rename to drivers/video/fbdev/cobalt_lcdfb.c
diff --git a/drivers/video/controlfb.c b/drivers/video/fbdev/controlfb.c
similarity index 100%
rename from drivers/video/controlfb.c
rename to drivers/video/fbdev/controlfb.c
diff --git a/drivers/video/controlfb.h b/drivers/video/fbdev/controlfb.h
similarity index 100%
rename from drivers/video/controlfb.h
rename to drivers/video/fbdev/controlfb.h
diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
new file mode 100644
index 0000000..fa30653
--- /dev/null
+++ b/drivers/video/fbdev/core/Makefile
@@ -0,0 +1,16 @@
+obj-y                             += fb_notify.o
+obj-$(CONFIG_FB)                  += fb.o
+fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
+                                     modedb.o fbcvt.o
+fb-objs                           := $(fb-y)
+
+obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
+obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
+obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
+obj-$(CONFIG_FB_SYS_FILLRECT)  += sysfillrect.o
+obj-$(CONFIG_FB_SYS_COPYAREA)  += syscopyarea.o
+obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
+obj-$(CONFIG_FB_SYS_FOPS)      += fb_sys_fops.o
+obj-$(CONFIG_FB_SVGALIB)       += svgalib.o
+obj-$(CONFIG_FB_DDC)           += fb_ddc.o
+obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/fbdev/core/cfbcopyarea.c
similarity index 100%
rename from drivers/video/cfbcopyarea.c
rename to drivers/video/fbdev/core/cfbcopyarea.c
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/fbdev/core/cfbfillrect.c
similarity index 100%
rename from drivers/video/cfbfillrect.c
rename to drivers/video/fbdev/core/cfbfillrect.c
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c
similarity index 100%
rename from drivers/video/cfbimgblt.c
rename to drivers/video/fbdev/core/cfbimgblt.c
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fbdev/core/fb_ddc.c
similarity index 98%
rename from drivers/video/fb_ddc.c
rename to drivers/video/fbdev/core/fb_ddc.c
index 2b106f0..94322cc 100644
--- a/drivers/video/fb_ddc.c
+++ b/drivers/video/fbdev/core/fb_ddc.c
@@ -15,7 +15,7 @@
 #include <linux/i2c-algo-bit.h>
 #include <linux/slab.h>
 
-#include "edid.h"
+#include "../edid.h"
 
 #define DDC_ADDR	0x50
 
diff --git a/drivers/video/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c
similarity index 100%
rename from drivers/video/fb_defio.c
rename to drivers/video/fbdev/core/fb_defio.c
diff --git a/drivers/video/fb_draw.h b/drivers/video/fbdev/core/fb_draw.h
similarity index 100%
rename from drivers/video/fb_draw.h
rename to drivers/video/fbdev/core/fb_draw.h
diff --git a/drivers/video/fb_notify.c b/drivers/video/fbdev/core/fb_notify.c
similarity index 100%
rename from drivers/video/fb_notify.c
rename to drivers/video/fbdev/core/fb_notify.c
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c
similarity index 100%
rename from drivers/video/fb_sys_fops.c
rename to drivers/video/fbdev/core/fb_sys_fops.c
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
similarity index 100%
rename from drivers/video/fbcmap.c
rename to drivers/video/fbdev/core/fbcmap.c
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c
similarity index 100%
rename from drivers/video/fbcvt.c
rename to drivers/video/fbdev/core/fbcvt.c
diff --git a/drivers/video/fbmem.c b/drivers/video/fbdev/core/fbmem.c
similarity index 100%
rename from drivers/video/fbmem.c
rename to drivers/video/fbdev/core/fbmem.c
diff --git a/drivers/video/fbmon.c b/drivers/video/fbdev/core/fbmon.c
similarity index 99%
rename from drivers/video/fbmon.c
rename to drivers/video/fbdev/core/fbmon.c
index 6103fa6..c204ebe 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -37,7 +37,7 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #endif
-#include "edid.h"
+#include "../edid.h"
 
 /*
  * EDID parser
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
similarity index 100%
rename from drivers/video/fbsysfs.c
rename to drivers/video/fbdev/core/fbsysfs.c
diff --git a/drivers/video/modedb.c b/drivers/video/fbdev/core/modedb.c
similarity index 100%
rename from drivers/video/modedb.c
rename to drivers/video/fbdev/core/modedb.c
diff --git a/drivers/video/svgalib.c b/drivers/video/fbdev/core/svgalib.c
similarity index 100%
rename from drivers/video/svgalib.c
rename to drivers/video/fbdev/core/svgalib.c
diff --git a/drivers/video/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c
similarity index 100%
rename from drivers/video/syscopyarea.c
rename to drivers/video/fbdev/core/syscopyarea.c
diff --git a/drivers/video/sysfillrect.c b/drivers/video/fbdev/core/sysfillrect.c
similarity index 100%
rename from drivers/video/sysfillrect.c
rename to drivers/video/fbdev/core/sysfillrect.c
diff --git a/drivers/video/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c
similarity index 100%
rename from drivers/video/sysimgblt.c
rename to drivers/video/fbdev/core/sysimgblt.c
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
similarity index 100%
rename from drivers/video/cyber2000fb.c
rename to drivers/video/fbdev/cyber2000fb.c
diff --git a/drivers/video/cyber2000fb.h b/drivers/video/fbdev/cyber2000fb.h
similarity index 100%
rename from drivers/video/cyber2000fb.h
rename to drivers/video/fbdev/cyber2000fb.h
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
similarity index 99%
rename from drivers/video/da8xx-fb.c
rename to drivers/video/fbdev/da8xx-fb.c
index 0c0ba92..6b23508 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -663,15 +663,7 @@
 			(green << info->var.green.offset) |
 			(blue << info->var.blue.offset);
 
-		switch (info->var.bits_per_pixel) {
-		case 16:
-			((u16 *) (info->pseudo_palette))[regno] = v;
-			break;
-		case 24:
-		case 32:
-			((u32 *) (info->pseudo_palette))[regno] = v;
-			break;
-		}
+		((u32 *) (info->pseudo_palette))[regno] = v;
 		if (palette[0] != 0x4000) {
 			update_hw = 1;
 			palette[0] = 0x4000;
diff --git a/drivers/video/dnfb.c b/drivers/video/fbdev/dnfb.c
similarity index 100%
rename from drivers/video/dnfb.c
rename to drivers/video/fbdev/dnfb.c
diff --git a/drivers/video/edid.h b/drivers/video/fbdev/edid.h
similarity index 100%
rename from drivers/video/edid.h
rename to drivers/video/fbdev/edid.h
diff --git a/drivers/video/efifb.c b/drivers/video/fbdev/efifb.c
similarity index 100%
rename from drivers/video/efifb.c
rename to drivers/video/fbdev/efifb.c
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
similarity index 100%
rename from drivers/video/ep93xx-fb.c
rename to drivers/video/fbdev/ep93xx-fb.c
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/fbdev/exynos/Kconfig
similarity index 100%
rename from drivers/video/exynos/Kconfig
rename to drivers/video/fbdev/exynos/Kconfig
diff --git a/drivers/video/exynos/Makefile b/drivers/video/fbdev/exynos/Makefile
similarity index 100%
rename from drivers/video/exynos/Makefile
rename to drivers/video/fbdev/exynos/Makefile
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
similarity index 100%
rename from drivers/video/exynos/exynos_mipi_dsi.c
rename to drivers/video/fbdev/exynos/exynos_mipi_dsi.c
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
similarity index 100%
rename from drivers/video/exynos/exynos_mipi_dsi_common.c
rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
similarity index 100%
rename from drivers/video/exynos/exynos_mipi_dsi_common.h
rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c
similarity index 100%
rename from drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h
similarity index 100%
rename from drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h
diff --git a/drivers/video/exynos/exynos_mipi_dsi_regs.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h
similarity index 100%
rename from drivers/video/exynos/exynos_mipi_dsi_regs.h
rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h
diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/fbdev/exynos/s6e8ax0.c
similarity index 100%
rename from drivers/video/exynos/s6e8ax0.c
rename to drivers/video/fbdev/exynos/s6e8ax0.c
diff --git a/drivers/video/fb-puv3.c b/drivers/video/fbdev/fb-puv3.c
similarity index 100%
rename from drivers/video/fb-puv3.c
rename to drivers/video/fbdev/fb-puv3.c
diff --git a/drivers/video/ffb.c b/drivers/video/fbdev/ffb.c
similarity index 100%
rename from drivers/video/ffb.c
rename to drivers/video/fbdev/ffb.c
diff --git a/drivers/video/fm2fb.c b/drivers/video/fbdev/fm2fb.c
similarity index 100%
rename from drivers/video/fm2fb.c
rename to drivers/video/fbdev/fm2fb.c
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c
similarity index 100%
rename from drivers/video/fsl-diu-fb.c
rename to drivers/video/fbdev/fsl-diu-fb.c
diff --git a/drivers/video/g364fb.c b/drivers/video/fbdev/g364fb.c
similarity index 100%
rename from drivers/video/g364fb.c
rename to drivers/video/fbdev/g364fb.c
diff --git a/drivers/video/gbefb.c b/drivers/video/fbdev/gbefb.c
similarity index 100%
rename from drivers/video/gbefb.c
rename to drivers/video/fbdev/gbefb.c
diff --git a/drivers/video/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig
similarity index 100%
rename from drivers/video/geode/Kconfig
rename to drivers/video/fbdev/geode/Kconfig
diff --git a/drivers/video/geode/Makefile b/drivers/video/fbdev/geode/Makefile
similarity index 100%
rename from drivers/video/geode/Makefile
rename to drivers/video/fbdev/geode/Makefile
diff --git a/drivers/video/geode/display_gx.c b/drivers/video/fbdev/geode/display_gx.c
similarity index 100%
rename from drivers/video/geode/display_gx.c
rename to drivers/video/fbdev/geode/display_gx.c
diff --git a/drivers/video/geode/display_gx1.c b/drivers/video/fbdev/geode/display_gx1.c
similarity index 100%
rename from drivers/video/geode/display_gx1.c
rename to drivers/video/fbdev/geode/display_gx1.c
diff --git a/drivers/video/geode/display_gx1.h b/drivers/video/fbdev/geode/display_gx1.h
similarity index 100%
rename from drivers/video/geode/display_gx1.h
rename to drivers/video/fbdev/geode/display_gx1.h
diff --git a/drivers/video/geode/geodefb.h b/drivers/video/fbdev/geode/geodefb.h
similarity index 100%
rename from drivers/video/geode/geodefb.h
rename to drivers/video/fbdev/geode/geodefb.h
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c
similarity index 100%
rename from drivers/video/geode/gx1fb_core.c
rename to drivers/video/fbdev/geode/gx1fb_core.c
diff --git a/drivers/video/geode/gxfb.h b/drivers/video/fbdev/geode/gxfb.h
similarity index 100%
rename from drivers/video/geode/gxfb.h
rename to drivers/video/fbdev/geode/gxfb.h
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c
similarity index 100%
rename from drivers/video/geode/gxfb_core.c
rename to drivers/video/fbdev/geode/gxfb_core.c
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/fbdev/geode/lxfb.h
similarity index 100%
rename from drivers/video/geode/lxfb.h
rename to drivers/video/fbdev/geode/lxfb.h
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c
similarity index 100%
rename from drivers/video/geode/lxfb_core.c
rename to drivers/video/fbdev/geode/lxfb_core.c
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/fbdev/geode/lxfb_ops.c
similarity index 100%
rename from drivers/video/geode/lxfb_ops.c
rename to drivers/video/fbdev/geode/lxfb_ops.c
diff --git a/drivers/video/geode/suspend_gx.c b/drivers/video/fbdev/geode/suspend_gx.c
similarity index 100%
rename from drivers/video/geode/suspend_gx.c
rename to drivers/video/fbdev/geode/suspend_gx.c
diff --git a/drivers/video/geode/video_cs5530.c b/drivers/video/fbdev/geode/video_cs5530.c
similarity index 100%
rename from drivers/video/geode/video_cs5530.c
rename to drivers/video/fbdev/geode/video_cs5530.c
diff --git a/drivers/video/geode/video_cs5530.h b/drivers/video/fbdev/geode/video_cs5530.h
similarity index 100%
rename from drivers/video/geode/video_cs5530.h
rename to drivers/video/fbdev/geode/video_cs5530.h
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/fbdev/geode/video_gx.c
similarity index 100%
rename from drivers/video/geode/video_gx.c
rename to drivers/video/fbdev/geode/video_gx.c
diff --git a/drivers/video/goldfishfb.c b/drivers/video/fbdev/goldfishfb.c
similarity index 100%
rename from drivers/video/goldfishfb.c
rename to drivers/video/fbdev/goldfishfb.c
diff --git a/drivers/video/grvga.c b/drivers/video/fbdev/grvga.c
similarity index 100%
rename from drivers/video/grvga.c
rename to drivers/video/fbdev/grvga.c
diff --git a/drivers/video/gxt4500.c b/drivers/video/fbdev/gxt4500.c
similarity index 100%
rename from drivers/video/gxt4500.c
rename to drivers/video/fbdev/gxt4500.c
diff --git a/drivers/video/hecubafb.c b/drivers/video/fbdev/hecubafb.c
similarity index 100%
rename from drivers/video/hecubafb.c
rename to drivers/video/fbdev/hecubafb.c
diff --git a/drivers/video/hgafb.c b/drivers/video/fbdev/hgafb.c
similarity index 100%
rename from drivers/video/hgafb.c
rename to drivers/video/fbdev/hgafb.c
diff --git a/drivers/video/hitfb.c b/drivers/video/fbdev/hitfb.c
similarity index 100%
rename from drivers/video/hitfb.c
rename to drivers/video/fbdev/hitfb.c
diff --git a/drivers/video/hpfb.c b/drivers/video/fbdev/hpfb.c
similarity index 100%
rename from drivers/video/hpfb.c
rename to drivers/video/fbdev/hpfb.c
diff --git a/drivers/video/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
similarity index 100%
rename from drivers/video/hyperv_fb.c
rename to drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/video/i740_reg.h b/drivers/video/fbdev/i740_reg.h
similarity index 100%
rename from drivers/video/i740_reg.h
rename to drivers/video/fbdev/i740_reg.h
diff --git a/drivers/video/i740fb.c b/drivers/video/fbdev/i740fb.c
similarity index 100%
rename from drivers/video/i740fb.c
rename to drivers/video/fbdev/i740fb.c
diff --git a/drivers/video/i810/Makefile b/drivers/video/fbdev/i810/Makefile
similarity index 100%
rename from drivers/video/i810/Makefile
rename to drivers/video/fbdev/i810/Makefile
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/fbdev/i810/i810-i2c.c
similarity index 100%
rename from drivers/video/i810/i810-i2c.c
rename to drivers/video/fbdev/i810/i810-i2c.c
diff --git a/drivers/video/i810/i810.h b/drivers/video/fbdev/i810/i810.h
similarity index 100%
rename from drivers/video/i810/i810.h
rename to drivers/video/fbdev/i810/i810.h
diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/fbdev/i810/i810_accel.c
similarity index 100%
rename from drivers/video/i810/i810_accel.c
rename to drivers/video/fbdev/i810/i810_accel.c
diff --git a/drivers/video/i810/i810_dvt.c b/drivers/video/fbdev/i810/i810_dvt.c
similarity index 100%
rename from drivers/video/i810/i810_dvt.c
rename to drivers/video/fbdev/i810/i810_dvt.c
diff --git a/drivers/video/i810/i810_gtf.c b/drivers/video/fbdev/i810/i810_gtf.c
similarity index 100%
rename from drivers/video/i810/i810_gtf.c
rename to drivers/video/fbdev/i810/i810_gtf.c
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c
similarity index 100%
rename from drivers/video/i810/i810_main.c
rename to drivers/video/fbdev/i810/i810_main.c
diff --git a/drivers/video/i810/i810_main.h b/drivers/video/fbdev/i810/i810_main.h
similarity index 100%
rename from drivers/video/i810/i810_main.h
rename to drivers/video/fbdev/i810/i810_main.h
diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/fbdev/i810/i810_regs.h
similarity index 100%
rename from drivers/video/i810/i810_regs.h
rename to drivers/video/fbdev/i810/i810_regs.h
diff --git a/drivers/video/igafb.c b/drivers/video/fbdev/igafb.c
similarity index 100%
rename from drivers/video/igafb.c
rename to drivers/video/fbdev/igafb.c
diff --git a/drivers/video/imsttfb.c b/drivers/video/fbdev/imsttfb.c
similarity index 100%
rename from drivers/video/imsttfb.c
rename to drivers/video/fbdev/imsttfb.c
diff --git a/drivers/video/imxfb.c b/drivers/video/fbdev/imxfb.c
similarity index 100%
rename from drivers/video/imxfb.c
rename to drivers/video/fbdev/imxfb.c
diff --git a/drivers/video/intelfb/Makefile b/drivers/video/fbdev/intelfb/Makefile
similarity index 100%
rename from drivers/video/intelfb/Makefile
rename to drivers/video/fbdev/intelfb/Makefile
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/fbdev/intelfb/intelfb.h
similarity index 100%
rename from drivers/video/intelfb/intelfb.h
rename to drivers/video/fbdev/intelfb/intelfb.h
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/fbdev/intelfb/intelfb_i2c.c
similarity index 100%
rename from drivers/video/intelfb/intelfb_i2c.c
rename to drivers/video/fbdev/intelfb/intelfb_i2c.c
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c
similarity index 100%
rename from drivers/video/intelfb/intelfbdrv.c
rename to drivers/video/fbdev/intelfb/intelfbdrv.c
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/fbdev/intelfb/intelfbhw.c
similarity index 100%
rename from drivers/video/intelfb/intelfbhw.c
rename to drivers/video/fbdev/intelfb/intelfbhw.c
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/fbdev/intelfb/intelfbhw.h
similarity index 100%
rename from drivers/video/intelfb/intelfbhw.h
rename to drivers/video/fbdev/intelfb/intelfbhw.h
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/fbdev/jz4740_fb.c
similarity index 100%
rename from drivers/video/jz4740_fb.c
rename to drivers/video/fbdev/jz4740_fb.c
diff --git a/drivers/video/kyro/Makefile b/drivers/video/fbdev/kyro/Makefile
similarity index 100%
rename from drivers/video/kyro/Makefile
rename to drivers/video/fbdev/kyro/Makefile
diff --git a/drivers/video/kyro/STG4000InitDevice.c b/drivers/video/fbdev/kyro/STG4000InitDevice.c
similarity index 100%
rename from drivers/video/kyro/STG4000InitDevice.c
rename to drivers/video/fbdev/kyro/STG4000InitDevice.c
diff --git a/drivers/video/kyro/STG4000Interface.h b/drivers/video/fbdev/kyro/STG4000Interface.h
similarity index 100%
rename from drivers/video/kyro/STG4000Interface.h
rename to drivers/video/fbdev/kyro/STG4000Interface.h
diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/fbdev/kyro/STG4000OverlayDevice.c
similarity index 100%
rename from drivers/video/kyro/STG4000OverlayDevice.c
rename to drivers/video/fbdev/kyro/STG4000OverlayDevice.c
diff --git a/drivers/video/kyro/STG4000Ramdac.c b/drivers/video/fbdev/kyro/STG4000Ramdac.c
similarity index 100%
rename from drivers/video/kyro/STG4000Ramdac.c
rename to drivers/video/fbdev/kyro/STG4000Ramdac.c
diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/fbdev/kyro/STG4000Reg.h
similarity index 100%
rename from drivers/video/kyro/STG4000Reg.h
rename to drivers/video/fbdev/kyro/STG4000Reg.h
diff --git a/drivers/video/kyro/STG4000VTG.c b/drivers/video/fbdev/kyro/STG4000VTG.c
similarity index 100%
rename from drivers/video/kyro/STG4000VTG.c
rename to drivers/video/fbdev/kyro/STG4000VTG.c
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
similarity index 100%
rename from drivers/video/kyro/fbdev.c
rename to drivers/video/fbdev/kyro/fbdev.c
diff --git a/drivers/video/leo.c b/drivers/video/fbdev/leo.c
similarity index 100%
rename from drivers/video/leo.c
rename to drivers/video/fbdev/leo.c
diff --git a/drivers/video/macfb.c b/drivers/video/fbdev/macfb.c
similarity index 100%
rename from drivers/video/macfb.c
rename to drivers/video/fbdev/macfb.c
diff --git a/drivers/video/macmodes.c b/drivers/video/fbdev/macmodes.c
similarity index 100%
rename from drivers/video/macmodes.c
rename to drivers/video/fbdev/macmodes.c
diff --git a/drivers/video/macmodes.h b/drivers/video/fbdev/macmodes.h
similarity index 100%
rename from drivers/video/macmodes.h
rename to drivers/video/fbdev/macmodes.h
diff --git a/drivers/video/matrox/Makefile b/drivers/video/fbdev/matrox/Makefile
similarity index 100%
rename from drivers/video/matrox/Makefile
rename to drivers/video/fbdev/matrox/Makefile
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/fbdev/matrox/g450_pll.c
similarity index 100%
rename from drivers/video/matrox/g450_pll.c
rename to drivers/video/fbdev/matrox/g450_pll.c
diff --git a/drivers/video/matrox/g450_pll.h b/drivers/video/fbdev/matrox/g450_pll.h
similarity index 100%
rename from drivers/video/matrox/g450_pll.h
rename to drivers/video/fbdev/matrox/g450_pll.h
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/fbdev/matrox/i2c-matroxfb.c
similarity index 100%
rename from drivers/video/matrox/i2c-matroxfb.c
rename to drivers/video/fbdev/matrox/i2c-matroxfb.c
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/fbdev/matrox/matroxfb_DAC1064.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_DAC1064.c
rename to drivers/video/fbdev/matrox/matroxfb_DAC1064.c
diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_DAC1064.h
rename to drivers/video/fbdev/matrox/matroxfb_DAC1064.h
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_Ti3026.c
rename to drivers/video/fbdev/matrox/matroxfb_Ti3026.c
diff --git a/drivers/video/matrox/matroxfb_Ti3026.h b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_Ti3026.h
rename to drivers/video/fbdev/matrox/matroxfb_Ti3026.h
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/fbdev/matrox/matroxfb_accel.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_accel.c
rename to drivers/video/fbdev/matrox/matroxfb_accel.c
diff --git a/drivers/video/matrox/matroxfb_accel.h b/drivers/video/fbdev/matrox/matroxfb_accel.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_accel.h
rename to drivers/video/fbdev/matrox/matroxfb_accel.h
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_base.c
rename to drivers/video/fbdev/matrox/matroxfb_base.c
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_base.h
rename to drivers/video/fbdev/matrox/matroxfb_base.h
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/fbdev/matrox/matroxfb_crtc2.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_crtc2.c
rename to drivers/video/fbdev/matrox/matroxfb_crtc2.c
diff --git a/drivers/video/matrox/matroxfb_crtc2.h b/drivers/video/fbdev/matrox/matroxfb_crtc2.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_crtc2.h
rename to drivers/video/fbdev/matrox/matroxfb_crtc2.h
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/fbdev/matrox/matroxfb_g450.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_g450.c
rename to drivers/video/fbdev/matrox/matroxfb_g450.c
diff --git a/drivers/video/matrox/matroxfb_g450.h b/drivers/video/fbdev/matrox/matroxfb_g450.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_g450.h
rename to drivers/video/fbdev/matrox/matroxfb_g450.h
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_maven.c
rename to drivers/video/fbdev/matrox/matroxfb_maven.c
diff --git a/drivers/video/matrox/matroxfb_maven.h b/drivers/video/fbdev/matrox/matroxfb_maven.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_maven.h
rename to drivers/video/fbdev/matrox/matroxfb_maven.h
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/fbdev/matrox/matroxfb_misc.c
similarity index 100%
rename from drivers/video/matrox/matroxfb_misc.c
rename to drivers/video/fbdev/matrox/matroxfb_misc.c
diff --git a/drivers/video/matrox/matroxfb_misc.h b/drivers/video/fbdev/matrox/matroxfb_misc.h
similarity index 100%
rename from drivers/video/matrox/matroxfb_misc.h
rename to drivers/video/fbdev/matrox/matroxfb_misc.h
diff --git a/drivers/video/maxinefb.c b/drivers/video/fbdev/maxinefb.c
similarity index 100%
rename from drivers/video/maxinefb.c
rename to drivers/video/fbdev/maxinefb.c
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/fbdev/mb862xx/Makefile
similarity index 100%
rename from drivers/video/mb862xx/Makefile
rename to drivers/video/fbdev/mb862xx/Makefile
diff --git a/drivers/video/mb862xx/mb862xx-i2c.c b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c
similarity index 100%
rename from drivers/video/mb862xx/mb862xx-i2c.c
rename to drivers/video/fbdev/mb862xx/mb862xx-i2c.c
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/fbdev/mb862xx/mb862xx_reg.h
similarity index 100%
rename from drivers/video/mb862xx/mb862xx_reg.h
rename to drivers/video/fbdev/mb862xx/mb862xx_reg.h
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/fbdev/mb862xx/mb862xxfb.h
similarity index 100%
rename from drivers/video/mb862xx/mb862xxfb.h
rename to drivers/video/fbdev/mb862xx/mb862xxfb.h
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c
similarity index 100%
rename from drivers/video/mb862xx/mb862xxfb_accel.c
rename to drivers/video/fbdev/mb862xx/mb862xxfb_accel.c
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.h b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h
similarity index 100%
rename from drivers/video/mb862xx/mb862xxfb_accel.h
rename to drivers/video/fbdev/mb862xx/mb862xxfb_accel.h
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
similarity index 100%
rename from drivers/video/mb862xx/mb862xxfbdrv.c
rename to drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
diff --git a/drivers/video/mbx/Makefile b/drivers/video/fbdev/mbx/Makefile
similarity index 100%
rename from drivers/video/mbx/Makefile
rename to drivers/video/fbdev/mbx/Makefile
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/fbdev/mbx/mbxdebugfs.c
similarity index 100%
rename from drivers/video/mbx/mbxdebugfs.c
rename to drivers/video/fbdev/mbx/mbxdebugfs.c
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c
similarity index 100%
rename from drivers/video/mbx/mbxfb.c
rename to drivers/video/fbdev/mbx/mbxfb.c
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/fbdev/mbx/reg_bits.h
similarity index 100%
rename from drivers/video/mbx/reg_bits.h
rename to drivers/video/fbdev/mbx/reg_bits.h
diff --git a/drivers/video/mbx/regs.h b/drivers/video/fbdev/mbx/regs.h
similarity index 100%
rename from drivers/video/mbx/regs.h
rename to drivers/video/fbdev/mbx/regs.h
diff --git a/drivers/video/metronomefb.c b/drivers/video/fbdev/metronomefb.c
similarity index 100%
rename from drivers/video/metronomefb.c
rename to drivers/video/fbdev/metronomefb.c
diff --git a/drivers/video/mmp/Kconfig b/drivers/video/fbdev/mmp/Kconfig
similarity index 61%
rename from drivers/video/mmp/Kconfig
rename to drivers/video/fbdev/mmp/Kconfig
index e9ea39e..d4a4ffc 100644
--- a/drivers/video/mmp/Kconfig
+++ b/drivers/video/fbdev/mmp/Kconfig
@@ -5,7 +5,7 @@
 	  Marvell Display Subsystem support.
 
 if MMP_DISP
-source "drivers/video/mmp/hw/Kconfig"
-source "drivers/video/mmp/panel/Kconfig"
-source "drivers/video/mmp/fb/Kconfig"
+source "drivers/video/fbdev/mmp/hw/Kconfig"
+source "drivers/video/fbdev/mmp/panel/Kconfig"
+source "drivers/video/fbdev/mmp/fb/Kconfig"
 endif
diff --git a/drivers/video/mmp/Makefile b/drivers/video/fbdev/mmp/Makefile
similarity index 100%
rename from drivers/video/mmp/Makefile
rename to drivers/video/fbdev/mmp/Makefile
diff --git a/drivers/video/mmp/core.c b/drivers/video/fbdev/mmp/core.c
similarity index 100%
rename from drivers/video/mmp/core.c
rename to drivers/video/fbdev/mmp/core.c
diff --git a/drivers/video/mmp/fb/Kconfig b/drivers/video/fbdev/mmp/fb/Kconfig
similarity index 100%
rename from drivers/video/mmp/fb/Kconfig
rename to drivers/video/fbdev/mmp/fb/Kconfig
diff --git a/drivers/video/mmp/fb/Makefile b/drivers/video/fbdev/mmp/fb/Makefile
similarity index 100%
rename from drivers/video/mmp/fb/Makefile
rename to drivers/video/fbdev/mmp/fb/Makefile
diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c
similarity index 100%
rename from drivers/video/mmp/fb/mmpfb.c
rename to drivers/video/fbdev/mmp/fb/mmpfb.c
diff --git a/drivers/video/mmp/fb/mmpfb.h b/drivers/video/fbdev/mmp/fb/mmpfb.h
similarity index 100%
rename from drivers/video/mmp/fb/mmpfb.h
rename to drivers/video/fbdev/mmp/fb/mmpfb.h
diff --git a/drivers/video/mmp/hw/Kconfig b/drivers/video/fbdev/mmp/hw/Kconfig
similarity index 100%
rename from drivers/video/mmp/hw/Kconfig
rename to drivers/video/fbdev/mmp/hw/Kconfig
diff --git a/drivers/video/mmp/hw/Makefile b/drivers/video/fbdev/mmp/hw/Makefile
similarity index 100%
rename from drivers/video/mmp/hw/Makefile
rename to drivers/video/fbdev/mmp/hw/Makefile
diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
similarity index 100%
rename from drivers/video/mmp/hw/mmp_ctrl.c
rename to drivers/video/fbdev/mmp/hw/mmp_ctrl.c
diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/fbdev/mmp/hw/mmp_ctrl.h
similarity index 100%
rename from drivers/video/mmp/hw/mmp_ctrl.h
rename to drivers/video/fbdev/mmp/hw/mmp_ctrl.h
diff --git a/drivers/video/mmp/hw/mmp_spi.c b/drivers/video/fbdev/mmp/hw/mmp_spi.c
similarity index 100%
rename from drivers/video/mmp/hw/mmp_spi.c
rename to drivers/video/fbdev/mmp/hw/mmp_spi.c
diff --git a/drivers/video/mmp/panel/Kconfig b/drivers/video/fbdev/mmp/panel/Kconfig
similarity index 100%
rename from drivers/video/mmp/panel/Kconfig
rename to drivers/video/fbdev/mmp/panel/Kconfig
diff --git a/drivers/video/mmp/panel/Makefile b/drivers/video/fbdev/mmp/panel/Makefile
similarity index 100%
rename from drivers/video/mmp/panel/Makefile
rename to drivers/video/fbdev/mmp/panel/Makefile
diff --git a/drivers/video/mmp/panel/tpo_tj032md01bw.c b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c
similarity index 100%
rename from drivers/video/mmp/panel/tpo_tj032md01bw.c
rename to drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c
diff --git a/drivers/video/msm/Makefile b/drivers/video/fbdev/msm/Makefile
similarity index 100%
rename from drivers/video/msm/Makefile
rename to drivers/video/fbdev/msm/Makefile
diff --git a/drivers/video/msm/mddi.c b/drivers/video/fbdev/msm/mddi.c
similarity index 100%
rename from drivers/video/msm/mddi.c
rename to drivers/video/fbdev/msm/mddi.c
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c
similarity index 100%
rename from drivers/video/msm/mddi_client_dummy.c
rename to drivers/video/fbdev/msm/mddi_client_dummy.c
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/fbdev/msm/mddi_client_nt35399.c
similarity index 100%
rename from drivers/video/msm/mddi_client_nt35399.c
rename to drivers/video/fbdev/msm/mddi_client_nt35399.c
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/fbdev/msm/mddi_client_toshiba.c
similarity index 100%
rename from drivers/video/msm/mddi_client_toshiba.c
rename to drivers/video/fbdev/msm/mddi_client_toshiba.c
diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/fbdev/msm/mddi_hw.h
similarity index 100%
rename from drivers/video/msm/mddi_hw.h
rename to drivers/video/fbdev/msm/mddi_hw.h
diff --git a/drivers/video/msm/mdp.c b/drivers/video/fbdev/msm/mdp.c
similarity index 100%
rename from drivers/video/msm/mdp.c
rename to drivers/video/fbdev/msm/mdp.c
diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/fbdev/msm/mdp_csc_table.h
similarity index 100%
rename from drivers/video/msm/mdp_csc_table.h
rename to drivers/video/fbdev/msm/mdp_csc_table.h
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/fbdev/msm/mdp_hw.h
similarity index 100%
rename from drivers/video/msm/mdp_hw.h
rename to drivers/video/fbdev/msm/mdp_hw.h
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/fbdev/msm/mdp_ppp.c
similarity index 100%
rename from drivers/video/msm/mdp_ppp.c
rename to drivers/video/fbdev/msm/mdp_ppp.c
diff --git a/drivers/video/msm/mdp_scale_tables.c b/drivers/video/fbdev/msm/mdp_scale_tables.c
similarity index 100%
rename from drivers/video/msm/mdp_scale_tables.c
rename to drivers/video/fbdev/msm/mdp_scale_tables.c
diff --git a/drivers/video/msm/mdp_scale_tables.h b/drivers/video/fbdev/msm/mdp_scale_tables.h
similarity index 100%
rename from drivers/video/msm/mdp_scale_tables.h
rename to drivers/video/fbdev/msm/mdp_scale_tables.h
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/fbdev/msm/msm_fb.c
similarity index 100%
rename from drivers/video/msm/msm_fb.c
rename to drivers/video/fbdev/msm/msm_fb.c
diff --git a/drivers/video/mx3fb.c b/drivers/video/fbdev/mx3fb.c
similarity index 100%
rename from drivers/video/mx3fb.c
rename to drivers/video/fbdev/mx3fb.c
diff --git a/drivers/video/mxsfb.c b/drivers/video/fbdev/mxsfb.c
similarity index 100%
rename from drivers/video/mxsfb.c
rename to drivers/video/fbdev/mxsfb.c
diff --git a/drivers/video/n411.c b/drivers/video/fbdev/n411.c
similarity index 100%
rename from drivers/video/n411.c
rename to drivers/video/fbdev/n411.c
diff --git a/drivers/video/neofb.c b/drivers/video/fbdev/neofb.c
similarity index 100%
rename from drivers/video/neofb.c
rename to drivers/video/fbdev/neofb.c
diff --git a/drivers/video/nuc900fb.c b/drivers/video/fbdev/nuc900fb.c
similarity index 100%
rename from drivers/video/nuc900fb.c
rename to drivers/video/fbdev/nuc900fb.c
diff --git a/drivers/video/nuc900fb.h b/drivers/video/fbdev/nuc900fb.h
similarity index 100%
rename from drivers/video/nuc900fb.h
rename to drivers/video/fbdev/nuc900fb.h
diff --git a/drivers/video/nvidia/Makefile b/drivers/video/fbdev/nvidia/Makefile
similarity index 100%
rename from drivers/video/nvidia/Makefile
rename to drivers/video/fbdev/nvidia/Makefile
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/fbdev/nvidia/nv_accel.c
similarity index 100%
rename from drivers/video/nvidia/nv_accel.c
rename to drivers/video/fbdev/nvidia/nv_accel.c
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/fbdev/nvidia/nv_backlight.c
similarity index 100%
rename from drivers/video/nvidia/nv_backlight.c
rename to drivers/video/fbdev/nvidia/nv_backlight.c
diff --git a/drivers/video/nvidia/nv_dma.h b/drivers/video/fbdev/nvidia/nv_dma.h
similarity index 100%
rename from drivers/video/nvidia/nv_dma.h
rename to drivers/video/fbdev/nvidia/nv_dma.h
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/fbdev/nvidia/nv_hw.c
similarity index 100%
rename from drivers/video/nvidia/nv_hw.c
rename to drivers/video/fbdev/nvidia/nv_hw.c
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/fbdev/nvidia/nv_i2c.c
similarity index 100%
rename from drivers/video/nvidia/nv_i2c.c
rename to drivers/video/fbdev/nvidia/nv_i2c.c
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/fbdev/nvidia/nv_local.h
similarity index 100%
rename from drivers/video/nvidia/nv_local.h
rename to drivers/video/fbdev/nvidia/nv_local.h
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/fbdev/nvidia/nv_of.c
similarity index 100%
rename from drivers/video/nvidia/nv_of.c
rename to drivers/video/fbdev/nvidia/nv_of.c
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/fbdev/nvidia/nv_proto.h
similarity index 100%
rename from drivers/video/nvidia/nv_proto.h
rename to drivers/video/fbdev/nvidia/nv_proto.h
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c
similarity index 100%
rename from drivers/video/nvidia/nv_setup.c
rename to drivers/video/fbdev/nvidia/nv_setup.c
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/fbdev/nvidia/nv_type.h
similarity index 100%
rename from drivers/video/nvidia/nv_type.h
rename to drivers/video/fbdev/nvidia/nv_type.h
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
similarity index 100%
rename from drivers/video/nvidia/nvidia.c
rename to drivers/video/fbdev/nvidia/nvidia.c
diff --git a/drivers/video/ocfb.c b/drivers/video/fbdev/ocfb.c
similarity index 100%
rename from drivers/video/ocfb.c
rename to drivers/video/fbdev/ocfb.c
diff --git a/drivers/video/offb.c b/drivers/video/fbdev/offb.c
similarity index 100%
rename from drivers/video/offb.c
rename to drivers/video/fbdev/offb.c
diff --git a/drivers/video/omap/Kconfig b/drivers/video/fbdev/omap/Kconfig
similarity index 100%
rename from drivers/video/omap/Kconfig
rename to drivers/video/fbdev/omap/Kconfig
diff --git a/drivers/video/omap/Makefile b/drivers/video/fbdev/omap/Makefile
similarity index 100%
rename from drivers/video/omap/Makefile
rename to drivers/video/fbdev/omap/Makefile
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c
similarity index 100%
rename from drivers/video/omap/hwa742.c
rename to drivers/video/fbdev/omap/hwa742.c
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/fbdev/omap/lcd_ams_delta.c
similarity index 100%
rename from drivers/video/omap/lcd_ams_delta.c
rename to drivers/video/fbdev/omap/lcd_ams_delta.c
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c
similarity index 100%
rename from drivers/video/omap/lcd_h3.c
rename to drivers/video/fbdev/omap/lcd_h3.c
diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/fbdev/omap/lcd_htcherald.c
similarity index 100%
rename from drivers/video/omap/lcd_htcherald.c
rename to drivers/video/fbdev/omap/lcd_htcherald.c
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/fbdev/omap/lcd_inn1510.c
similarity index 100%
rename from drivers/video/omap/lcd_inn1510.c
rename to drivers/video/fbdev/omap/lcd_inn1510.c
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/fbdev/omap/lcd_inn1610.c
similarity index 100%
rename from drivers/video/omap/lcd_inn1610.c
rename to drivers/video/fbdev/omap/lcd_inn1610.c
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c
similarity index 100%
rename from drivers/video/omap/lcd_mipid.c
rename to drivers/video/fbdev/omap/lcd_mipid.c
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/fbdev/omap/lcd_osk.c
similarity index 100%
rename from drivers/video/omap/lcd_osk.c
rename to drivers/video/fbdev/omap/lcd_osk.c
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/fbdev/omap/lcd_palmte.c
similarity index 100%
rename from drivers/video/omap/lcd_palmte.c
rename to drivers/video/fbdev/omap/lcd_palmte.c
diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/fbdev/omap/lcd_palmtt.c
similarity index 100%
rename from drivers/video/omap/lcd_palmtt.c
rename to drivers/video/fbdev/omap/lcd_palmtt.c
diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/fbdev/omap/lcd_palmz71.c
similarity index 100%
rename from drivers/video/omap/lcd_palmz71.c
rename to drivers/video/fbdev/omap/lcd_palmz71.c
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/fbdev/omap/lcdc.c
similarity index 100%
rename from drivers/video/omap/lcdc.c
rename to drivers/video/fbdev/omap/lcdc.c
diff --git a/drivers/video/omap/lcdc.h b/drivers/video/fbdev/omap/lcdc.h
similarity index 100%
rename from drivers/video/omap/lcdc.h
rename to drivers/video/fbdev/omap/lcdc.h
diff --git a/drivers/video/omap/omapfb.h b/drivers/video/fbdev/omap/omapfb.h
similarity index 100%
rename from drivers/video/omap/omapfb.h
rename to drivers/video/fbdev/omap/omapfb.h
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c
similarity index 100%
rename from drivers/video/omap/omapfb_main.c
rename to drivers/video/fbdev/omap/omapfb_main.c
diff --git a/drivers/video/omap/sossi.c b/drivers/video/fbdev/omap/sossi.c
similarity index 100%
rename from drivers/video/omap/sossi.c
rename to drivers/video/fbdev/omap/sossi.c
diff --git a/drivers/video/fbdev/omap2/Kconfig b/drivers/video/fbdev/omap2/Kconfig
new file mode 100644
index 0000000..c22955d
--- /dev/null
+++ b/drivers/video/fbdev/omap2/Kconfig
@@ -0,0 +1,10 @@
+config OMAP2_VRFB
+	bool
+
+if ARCH_OMAP2PLUS
+
+source "drivers/video/fbdev/omap2/dss/Kconfig"
+source "drivers/video/fbdev/omap2/omapfb/Kconfig"
+source "drivers/video/fbdev/omap2/displays-new/Kconfig"
+
+endif
diff --git a/drivers/video/omap2/Makefile b/drivers/video/fbdev/omap2/Makefile
similarity index 100%
rename from drivers/video/omap2/Makefile
rename to drivers/video/fbdev/omap2/Makefile
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/fbdev/omap2/displays-new/Kconfig
similarity index 100%
rename from drivers/video/omap2/displays-new/Kconfig
rename to drivers/video/fbdev/omap2/displays-new/Kconfig
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/fbdev/omap2/displays-new/Makefile
similarity index 100%
rename from drivers/video/omap2/displays-new/Makefile
rename to drivers/video/fbdev/omap2/displays-new/Makefile
diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
similarity index 100%
rename from drivers/video/omap2/displays-new/connector-analog-tv.c
rename to drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
similarity index 100%
rename from drivers/video/omap2/displays-new/connector-dvi.c
rename to drivers/video/fbdev/omap2/displays-new/connector-dvi.c
diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
similarity index 100%
rename from drivers/video/omap2/displays-new/connector-hdmi.c
rename to drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
diff --git a/drivers/video/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
similarity index 100%
rename from drivers/video/omap2/displays-new/encoder-tfp410.c
rename to drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
diff --git a/drivers/video/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
similarity index 100%
rename from drivers/video/omap2/displays-new/encoder-tpd12s015.c
rename to drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
diff --git a/drivers/video/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-dpi.c
rename to drivers/video/fbdev/omap2/displays-new/panel-dpi.c
diff --git a/drivers/video/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-dsi-cm.c
rename to drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
diff --git a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c
rename to drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
diff --git a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
rename to drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
diff --git a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
rename to drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
diff --git a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-sony-acx565akm.c
rename to drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
rename to drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
similarity index 100%
rename from drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
rename to drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig
similarity index 100%
rename from drivers/video/omap2/dss/Kconfig
rename to drivers/video/fbdev/omap2/dss/Kconfig
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile
similarity index 100%
rename from drivers/video/omap2/dss/Makefile
rename to drivers/video/fbdev/omap2/dss/Makefile
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/fbdev/omap2/dss/apply.c
similarity index 100%
rename from drivers/video/omap2/dss/apply.c
rename to drivers/video/fbdev/omap2/dss/apply.c
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c
similarity index 100%
rename from drivers/video/omap2/dss/core.c
rename to drivers/video/fbdev/omap2/dss/core.c
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/fbdev/omap2/dss/dispc-compat.c
similarity index 100%
rename from drivers/video/omap2/dss/dispc-compat.c
rename to drivers/video/fbdev/omap2/dss/dispc-compat.c
diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/fbdev/omap2/dss/dispc-compat.h
similarity index 100%
rename from drivers/video/omap2/dss/dispc-compat.h
rename to drivers/video/fbdev/omap2/dss/dispc-compat.h
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
similarity index 98%
rename from drivers/video/omap2/dss/dispc.c
rename to drivers/video/fbdev/omap2/dss/dispc.c
index 2bbdb7f..f18397c 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -101,6 +101,8 @@
 	void __iomem    *base;
 
 	int irq;
+	irq_handler_t user_handler;
+	void *user_data;
 
 	unsigned long core_clk_rate;
 	unsigned long tv_pclk_rate;
@@ -113,6 +115,8 @@
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
 	const struct dispc_features *feat;
+
+	bool is_enabled;
 } dispc;
 
 enum omap_color_component {
@@ -141,12 +145,18 @@
 	DISPC_MGR_FLD_NUM,
 };
 
+struct dispc_reg_field {
+	u16 reg;
+	u8 high;
+	u8 low;
+};
+
 static const struct {
 	const char *name;
 	u32 vsync_irq;
 	u32 framedone_irq;
 	u32 sync_lost_irq;
-	struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
+	struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];
 } mgr_desc[] = {
 	[OMAP_DSS_CHANNEL_LCD] = {
 		.name		= "LCD",
@@ -238,13 +248,13 @@
 
 static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
 {
-	const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+	const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
 	return REG_GET(rfld.reg, rfld.high, rfld.low);
 }
 
 static void mgr_fld_write(enum omap_channel channel,
 					enum mgr_reg_fields regfld, int val) {
-	const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+	const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
 	REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
 }
 
@@ -3669,16 +3679,44 @@
 	return 0;
 }
 
+static irqreturn_t dispc_irq_handler(int irq, void *arg)
+{
+	if (!dispc.is_enabled)
+		return IRQ_NONE;
+
+	return dispc.user_handler(irq, dispc.user_data);
+}
+
 int dispc_request_irq(irq_handler_t handler, void *dev_id)
 {
-	return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
-			     IRQF_SHARED, "OMAP DISPC", dev_id);
+	int r;
+
+	if (dispc.user_handler != NULL)
+		return -EBUSY;
+
+	dispc.user_handler = handler;
+	dispc.user_data = dev_id;
+
+	/* ensure the dispc_irq_handler sees the values above */
+	smp_wmb();
+
+	r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
+			     IRQF_SHARED, "OMAP DISPC", &dispc);
+	if (r) {
+		dispc.user_handler = NULL;
+		dispc.user_data = NULL;
+	}
+
+	return r;
 }
 EXPORT_SYMBOL(dispc_request_irq);
 
 void dispc_free_irq(void *dev_id)
 {
-	devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
+	devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);
+
+	dispc.user_handler = NULL;
+	dispc.user_data = NULL;
 }
 EXPORT_SYMBOL(dispc_free_irq);
 
@@ -3750,6 +3788,12 @@
 
 static int dispc_runtime_suspend(struct device *dev)
 {
+	dispc.is_enabled = false;
+	/* ensure the dispc_irq_handler sees the is_enabled value */
+	smp_wmb();
+	/* wait for current handler to finish before turning the DISPC off */
+	synchronize_irq(dispc.irq);
+
 	dispc_save_context();
 
 	return 0;
@@ -3763,12 +3807,15 @@
 	 * _omap_dispc_initial_config(). We can thus use it to detect if
 	 * we have lost register context.
 	 */
-	if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY)
-		return 0;
+	if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
+		_omap_dispc_initial_config();
 
-	_omap_dispc_initial_config();
+		dispc_restore_context();
+	}
 
-	dispc_restore_context();
+	dispc.is_enabled = true;
+	/* ensure the dispc_irq_handler sees the is_enabled value */
+	smp_wmb();
 
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/fbdev/omap2/dss/dispc.h
similarity index 100%
rename from drivers/video/omap2/dss/dispc.h
rename to drivers/video/fbdev/omap2/dss/dispc.h
diff --git a/drivers/video/omap2/dss/dispc_coefs.c b/drivers/video/fbdev/omap2/dss/dispc_coefs.c
similarity index 100%
rename from drivers/video/omap2/dss/dispc_coefs.c
rename to drivers/video/fbdev/omap2/dss/dispc_coefs.c
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/fbdev/omap2/dss/display-sysfs.c
similarity index 100%
rename from drivers/video/omap2/dss/display-sysfs.c
rename to drivers/video/fbdev/omap2/dss/display-sysfs.c
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/fbdev/omap2/dss/display.c
similarity index 100%
rename from drivers/video/omap2/dss/display.c
rename to drivers/video/fbdev/omap2/dss/display.c
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
similarity index 100%
rename from drivers/video/omap2/dss/dpi.c
rename to drivers/video/fbdev/omap2/dss/dpi.c
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
similarity index 99%
rename from drivers/video/omap2/dss/dsi.c
rename to drivers/video/fbdev/omap2/dss/dsi.c
index 121d104..8be9b04 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -297,6 +297,8 @@
 
 	int irq;
 
+	bool is_enabled;
+
 	struct clk *dss_clk;
 	struct clk *sys_clk;
 
@@ -795,6 +797,9 @@
 	dsidev = (struct platform_device *) arg;
 	dsi = dsi_get_dsidrv_data(dsidev);
 
+	if (!dsi->is_enabled)
+		return IRQ_NONE;
+
 	spin_lock(&dsi->irq_lock);
 
 	irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
@@ -5671,6 +5676,15 @@
 
 static int dsi_runtime_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
+
+	dsi->is_enabled = false;
+	/* ensure the irq handler sees the is_enabled value */
+	smp_wmb();
+	/* wait for current handler to finish before turning the DSI off */
+	synchronize_irq(dsi->irq);
+
 	dispc_runtime_put();
 
 	return 0;
@@ -5678,12 +5692,18 @@
 
 static int dsi_runtime_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
 	int r;
 
 	r = dispc_runtime_get();
 	if (r)
 		return r;
 
+	dsi->is_enabled = true;
+	/* ensure the irq handler sees the is_enabled value */
+	smp_wmb();
+
 	return 0;
 }
 
diff --git a/drivers/video/omap2/dss/dss-of.c b/drivers/video/fbdev/omap2/dss/dss-of.c
similarity index 100%
rename from drivers/video/omap2/dss/dss-of.c
rename to drivers/video/fbdev/omap2/dss/dss-of.c
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
similarity index 99%
rename from drivers/video/omap2/dss/dss.c
rename to drivers/video/fbdev/omap2/dss/dss.c
index 825c019..d55266c 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -457,7 +457,7 @@
 	fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
 
 	for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
-		fck = prate / fckd * m;
+		fck = DIV_ROUND_UP(prate, fckd) * m;
 
 		if (func(fck, data))
 			return true;
@@ -506,7 +506,7 @@
 
 		fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
 				max_dss_fck);
-		fck = prate / fck_div * dss.feat->dss_fck_multiplier;
+		fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
 	}
 
 	r = dss_set_fck_rate(fck);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
similarity index 99%
rename from drivers/video/omap2/dss/dss.h
rename to drivers/video/fbdev/omap2/dss/dss.h
index 918fec1..560078f 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -131,12 +131,6 @@
 	u16 lp_clk_div;
 };
 
-struct reg_field {
-	u16 reg;
-	u8 high;
-	u8 low;
-};
-
 struct dss_lcd_mgr_config {
 	enum dss_io_pad_mode io_pad_mode;
 
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c
similarity index 100%
rename from drivers/video/omap2/dss/dss_features.c
rename to drivers/video/fbdev/omap2/dss/dss_features.c
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/fbdev/omap2/dss/dss_features.h
similarity index 100%
rename from drivers/video/omap2/dss/dss_features.h
rename to drivers/video/fbdev/omap2/dss/dss_features.h
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
similarity index 100%
rename from drivers/video/omap2/dss/hdmi.h
rename to drivers/video/fbdev/omap2/dss/hdmi.h
diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
similarity index 100%
rename from drivers/video/omap2/dss/hdmi4.c
rename to drivers/video/fbdev/omap2/dss/hdmi4.c
diff --git a/drivers/video/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
similarity index 100%
rename from drivers/video/omap2/dss/hdmi4_core.c
rename to drivers/video/fbdev/omap2/dss/hdmi4_core.c
diff --git a/drivers/video/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
similarity index 100%
rename from drivers/video/omap2/dss/hdmi4_core.h
rename to drivers/video/fbdev/omap2/dss/hdmi4_core.h
diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c
similarity index 98%
rename from drivers/video/omap2/dss/hdmi_common.c
rename to drivers/video/fbdev/omap2/dss/hdmi_common.c
index b11afac..0b12a3f 100644
--- a/drivers/video/omap2/dss/hdmi_common.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c
@@ -347,17 +347,17 @@
 	case 96000:
 	case 192000:
 		if (deep_color == 125)
-			if (pclk == 27027 || pclk == 74250)
+			if (pclk == 27027000 || pclk == 74250000)
 				deep_color_correct = true;
 		if (deep_color == 150)
-			if (pclk == 27027)
+			if (pclk == 27027000)
 				deep_color_correct = true;
 		break;
 	case 44100:
 	case 88200:
 	case 176400:
 		if (deep_color == 125)
-			if (pclk == 27027)
+			if (pclk == 27027000)
 				deep_color_correct = true;
 		break;
 	default:
@@ -418,7 +418,7 @@
 		}
 	}
 	/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
-	*cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
+	*cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10);
 
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
similarity index 100%
rename from drivers/video/omap2/dss/hdmi_phy.c
rename to drivers/video/fbdev/omap2/dss/hdmi_phy.c
diff --git a/drivers/video/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
similarity index 100%
rename from drivers/video/omap2/dss/hdmi_pll.c
rename to drivers/video/fbdev/omap2/dss/hdmi_pll.c
diff --git a/drivers/video/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c
similarity index 100%
rename from drivers/video/omap2/dss/hdmi_wp.c
rename to drivers/video/fbdev/omap2/dss/hdmi_wp.c
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/fbdev/omap2/dss/manager-sysfs.c
similarity index 100%
rename from drivers/video/omap2/dss/manager-sysfs.c
rename to drivers/video/fbdev/omap2/dss/manager-sysfs.c
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/fbdev/omap2/dss/manager.c
similarity index 100%
rename from drivers/video/omap2/dss/manager.c
rename to drivers/video/fbdev/omap2/dss/manager.c
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c
similarity index 100%
rename from drivers/video/omap2/dss/output.c
rename to drivers/video/fbdev/omap2/dss/output.c
diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/fbdev/omap2/dss/overlay-sysfs.c
similarity index 100%
rename from drivers/video/omap2/dss/overlay-sysfs.c
rename to drivers/video/fbdev/omap2/dss/overlay-sysfs.c
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/fbdev/omap2/dss/overlay.c
similarity index 100%
rename from drivers/video/omap2/dss/overlay.c
rename to drivers/video/fbdev/omap2/dss/overlay.c
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c
similarity index 100%
rename from drivers/video/omap2/dss/rfbi.c
rename to drivers/video/fbdev/omap2/dss/rfbi.c
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c
similarity index 100%
rename from drivers/video/omap2/dss/sdi.c
rename to drivers/video/fbdev/omap2/dss/sdi.c
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c
similarity index 100%
rename from drivers/video/omap2/dss/venc.c
rename to drivers/video/fbdev/omap2/dss/venc.c
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/fbdev/omap2/dss/venc_panel.c
similarity index 100%
rename from drivers/video/omap2/dss/venc_panel.c
rename to drivers/video/fbdev/omap2/dss/venc_panel.c
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig
similarity index 100%
rename from drivers/video/omap2/omapfb/Kconfig
rename to drivers/video/fbdev/omap2/omapfb/Kconfig
diff --git a/drivers/video/omap2/omapfb/Makefile b/drivers/video/fbdev/omap2/omapfb/Makefile
similarity index 100%
rename from drivers/video/omap2/omapfb/Makefile
rename to drivers/video/fbdev/omap2/omapfb/Makefile
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
similarity index 100%
rename from drivers/video/omap2/omapfb/omapfb-ioctl.c
rename to drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
similarity index 100%
rename from drivers/video/omap2/omapfb/omapfb-main.c
rename to drivers/video/fbdev/omap2/omapfb/omapfb-main.c
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
similarity index 100%
rename from drivers/video/omap2/omapfb/omapfb-sysfs.c
rename to drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/fbdev/omap2/omapfb/omapfb.h
similarity index 100%
rename from drivers/video/omap2/omapfb/omapfb.h
rename to drivers/video/fbdev/omap2/omapfb/omapfb.h
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/fbdev/omap2/vrfb.c
similarity index 100%
rename from drivers/video/omap2/vrfb.c
rename to drivers/video/fbdev/omap2/vrfb.c
diff --git a/drivers/video/p9100.c b/drivers/video/fbdev/p9100.c
similarity index 100%
rename from drivers/video/p9100.c
rename to drivers/video/fbdev/p9100.c
diff --git a/drivers/video/platinumfb.c b/drivers/video/fbdev/platinumfb.c
similarity index 100%
rename from drivers/video/platinumfb.c
rename to drivers/video/fbdev/platinumfb.c
diff --git a/drivers/video/platinumfb.h b/drivers/video/fbdev/platinumfb.h
similarity index 100%
rename from drivers/video/platinumfb.h
rename to drivers/video/fbdev/platinumfb.h
diff --git a/drivers/video/pm2fb.c b/drivers/video/fbdev/pm2fb.c
similarity index 100%
rename from drivers/video/pm2fb.c
rename to drivers/video/fbdev/pm2fb.c
diff --git a/drivers/video/pm3fb.c b/drivers/video/fbdev/pm3fb.c
similarity index 100%
rename from drivers/video/pm3fb.c
rename to drivers/video/fbdev/pm3fb.c
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c
similarity index 100%
rename from drivers/video/pmag-aa-fb.c
rename to drivers/video/fbdev/pmag-aa-fb.c
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/fbdev/pmag-ba-fb.c
similarity index 100%
rename from drivers/video/pmag-ba-fb.c
rename to drivers/video/fbdev/pmag-ba-fb.c
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/fbdev/pmagb-b-fb.c
similarity index 100%
rename from drivers/video/pmagb-b-fb.c
rename to drivers/video/fbdev/pmagb-b-fb.c
diff --git a/drivers/video/ps3fb.c b/drivers/video/fbdev/ps3fb.c
similarity index 100%
rename from drivers/video/ps3fb.c
rename to drivers/video/fbdev/ps3fb.c
diff --git a/drivers/video/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
similarity index 100%
rename from drivers/video/pvr2fb.c
rename to drivers/video/fbdev/pvr2fb.c
diff --git a/drivers/video/pxa168fb.c b/drivers/video/fbdev/pxa168fb.c
similarity index 100%
rename from drivers/video/pxa168fb.c
rename to drivers/video/fbdev/pxa168fb.c
diff --git a/drivers/video/pxa168fb.h b/drivers/video/fbdev/pxa168fb.h
similarity index 100%
rename from drivers/video/pxa168fb.h
rename to drivers/video/fbdev/pxa168fb.h
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c
similarity index 100%
rename from drivers/video/pxa3xx-gcu.c
rename to drivers/video/fbdev/pxa3xx-gcu.c
diff --git a/drivers/video/pxa3xx-gcu.h b/drivers/video/fbdev/pxa3xx-gcu.h
similarity index 100%
rename from drivers/video/pxa3xx-gcu.h
rename to drivers/video/fbdev/pxa3xx-gcu.h
diff --git a/drivers/video/pxafb.c b/drivers/video/fbdev/pxafb.c
similarity index 100%
rename from drivers/video/pxafb.c
rename to drivers/video/fbdev/pxafb.c
diff --git a/drivers/video/pxafb.h b/drivers/video/fbdev/pxafb.h
similarity index 100%
rename from drivers/video/pxafb.h
rename to drivers/video/fbdev/pxafb.h
diff --git a/drivers/video/q40fb.c b/drivers/video/fbdev/q40fb.c
similarity index 100%
rename from drivers/video/q40fb.c
rename to drivers/video/fbdev/q40fb.c
diff --git a/drivers/video/riva/Makefile b/drivers/video/fbdev/riva/Makefile
similarity index 100%
rename from drivers/video/riva/Makefile
rename to drivers/video/fbdev/riva/Makefile
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
similarity index 100%
rename from drivers/video/riva/fbdev.c
rename to drivers/video/fbdev/riva/fbdev.c
diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/fbdev/riva/nv_driver.c
similarity index 100%
rename from drivers/video/riva/nv_driver.c
rename to drivers/video/fbdev/riva/nv_driver.c
diff --git a/drivers/video/riva/nv_type.h b/drivers/video/fbdev/riva/nv_type.h
similarity index 100%
rename from drivers/video/riva/nv_type.h
rename to drivers/video/fbdev/riva/nv_type.h
diff --git a/drivers/video/riva/nvreg.h b/drivers/video/fbdev/riva/nvreg.h
similarity index 100%
rename from drivers/video/riva/nvreg.h
rename to drivers/video/fbdev/riva/nvreg.h
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c
similarity index 100%
rename from drivers/video/riva/riva_hw.c
rename to drivers/video/fbdev/riva/riva_hw.c
diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/fbdev/riva/riva_hw.h
similarity index 100%
rename from drivers/video/riva/riva_hw.h
rename to drivers/video/fbdev/riva/riva_hw.h
diff --git a/drivers/video/riva/riva_tbl.h b/drivers/video/fbdev/riva/riva_tbl.h
similarity index 100%
rename from drivers/video/riva/riva_tbl.h
rename to drivers/video/fbdev/riva/riva_tbl.h
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/fbdev/riva/rivafb-i2c.c
similarity index 100%
rename from drivers/video/riva/rivafb-i2c.c
rename to drivers/video/fbdev/riva/rivafb-i2c.c
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/fbdev/riva/rivafb.h
similarity index 100%
rename from drivers/video/riva/rivafb.h
rename to drivers/video/fbdev/riva/rivafb.h
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c
similarity index 100%
rename from drivers/video/s1d13xxxfb.c
rename to drivers/video/fbdev/s1d13xxxfb.c
diff --git a/drivers/video/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c
similarity index 100%
rename from drivers/video/s3c-fb.c
rename to drivers/video/fbdev/s3c-fb.c
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c
similarity index 100%
rename from drivers/video/s3c2410fb.c
rename to drivers/video/fbdev/s3c2410fb.c
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/fbdev/s3c2410fb.h
similarity index 100%
rename from drivers/video/s3c2410fb.h
rename to drivers/video/fbdev/s3c2410fb.h
diff --git a/drivers/video/s3fb.c b/drivers/video/fbdev/s3fb.c
similarity index 100%
rename from drivers/video/s3fb.c
rename to drivers/video/fbdev/s3fb.c
diff --git a/drivers/video/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c
similarity index 100%
rename from drivers/video/sa1100fb.c
rename to drivers/video/fbdev/sa1100fb.c
diff --git a/drivers/video/sa1100fb.h b/drivers/video/fbdev/sa1100fb.h
similarity index 100%
rename from drivers/video/sa1100fb.h
rename to drivers/video/fbdev/sa1100fb.h
diff --git a/drivers/video/savage/Makefile b/drivers/video/fbdev/savage/Makefile
similarity index 100%
rename from drivers/video/savage/Makefile
rename to drivers/video/fbdev/savage/Makefile
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/fbdev/savage/savagefb-i2c.c
similarity index 100%
rename from drivers/video/savage/savagefb-i2c.c
rename to drivers/video/fbdev/savage/savagefb-i2c.c
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/fbdev/savage/savagefb.h
similarity index 100%
rename from drivers/video/savage/savagefb.h
rename to drivers/video/fbdev/savage/savagefb.h
diff --git a/drivers/video/savage/savagefb_accel.c b/drivers/video/fbdev/savage/savagefb_accel.c
similarity index 100%
rename from drivers/video/savage/savagefb_accel.c
rename to drivers/video/fbdev/savage/savagefb_accel.c
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
similarity index 100%
rename from drivers/video/savage/savagefb_driver.c
rename to drivers/video/fbdev/savage/savagefb_driver.c
diff --git a/drivers/video/sbuslib.c b/drivers/video/fbdev/sbuslib.c
similarity index 100%
rename from drivers/video/sbuslib.c
rename to drivers/video/fbdev/sbuslib.c
diff --git a/drivers/video/sbuslib.h b/drivers/video/fbdev/sbuslib.h
similarity index 100%
rename from drivers/video/sbuslib.h
rename to drivers/video/fbdev/sbuslib.h
diff --git a/drivers/video/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c
similarity index 100%
rename from drivers/video/sh7760fb.c
rename to drivers/video/fbdev/sh7760fb.c
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/fbdev/sh_mipi_dsi.c
similarity index 100%
rename from drivers/video/sh_mipi_dsi.c
rename to drivers/video/fbdev/sh_mipi_dsi.c
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/fbdev/sh_mobile_hdmi.c
similarity index 100%
rename from drivers/video/sh_mobile_hdmi.c
rename to drivers/video/fbdev/sh_mobile_hdmi.c
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
similarity index 100%
rename from drivers/video/sh_mobile_lcdcfb.c
rename to drivers/video/fbdev/sh_mobile_lcdcfb.c
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/fbdev/sh_mobile_lcdcfb.h
similarity index 100%
rename from drivers/video/sh_mobile_lcdcfb.h
rename to drivers/video/fbdev/sh_mobile_lcdcfb.h
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/fbdev/sh_mobile_meram.c
similarity index 100%
rename from drivers/video/sh_mobile_meram.c
rename to drivers/video/fbdev/sh_mobile_meram.c
diff --git a/drivers/video/simplefb.c b/drivers/video/fbdev/simplefb.c
similarity index 100%
rename from drivers/video/simplefb.c
rename to drivers/video/fbdev/simplefb.c
diff --git a/drivers/video/sis/300vtbl.h b/drivers/video/fbdev/sis/300vtbl.h
similarity index 100%
rename from drivers/video/sis/300vtbl.h
rename to drivers/video/fbdev/sis/300vtbl.h
diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/fbdev/sis/310vtbl.h
similarity index 100%
rename from drivers/video/sis/310vtbl.h
rename to drivers/video/fbdev/sis/310vtbl.h
diff --git a/drivers/video/sis/Makefile b/drivers/video/fbdev/sis/Makefile
similarity index 100%
rename from drivers/video/sis/Makefile
rename to drivers/video/fbdev/sis/Makefile
diff --git a/drivers/video/sis/init.c b/drivers/video/fbdev/sis/init.c
similarity index 100%
rename from drivers/video/sis/init.c
rename to drivers/video/fbdev/sis/init.c
diff --git a/drivers/video/sis/init.h b/drivers/video/fbdev/sis/init.h
similarity index 100%
rename from drivers/video/sis/init.h
rename to drivers/video/fbdev/sis/init.h
diff --git a/drivers/video/sis/init301.c b/drivers/video/fbdev/sis/init301.c
similarity index 100%
rename from drivers/video/sis/init301.c
rename to drivers/video/fbdev/sis/init301.c
diff --git a/drivers/video/sis/init301.h b/drivers/video/fbdev/sis/init301.h
similarity index 100%
rename from drivers/video/sis/init301.h
rename to drivers/video/fbdev/sis/init301.h
diff --git a/drivers/video/sis/initdef.h b/drivers/video/fbdev/sis/initdef.h
similarity index 100%
rename from drivers/video/sis/initdef.h
rename to drivers/video/fbdev/sis/initdef.h
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/fbdev/sis/initextlfb.c
similarity index 100%
rename from drivers/video/sis/initextlfb.c
rename to drivers/video/fbdev/sis/initextlfb.c
diff --git a/drivers/video/sis/oem300.h b/drivers/video/fbdev/sis/oem300.h
similarity index 100%
rename from drivers/video/sis/oem300.h
rename to drivers/video/fbdev/sis/oem300.h
diff --git a/drivers/video/sis/oem310.h b/drivers/video/fbdev/sis/oem310.h
similarity index 100%
rename from drivers/video/sis/oem310.h
rename to drivers/video/fbdev/sis/oem310.h
diff --git a/drivers/video/sis/sis.h b/drivers/video/fbdev/sis/sis.h
similarity index 100%
rename from drivers/video/sis/sis.h
rename to drivers/video/fbdev/sis/sis.h
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/fbdev/sis/sis_accel.c
similarity index 100%
rename from drivers/video/sis/sis_accel.c
rename to drivers/video/fbdev/sis/sis_accel.c
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/fbdev/sis/sis_accel.h
similarity index 100%
rename from drivers/video/sis/sis_accel.h
rename to drivers/video/fbdev/sis/sis_accel.h
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
similarity index 100%
rename from drivers/video/sis/sis_main.c
rename to drivers/video/fbdev/sis/sis_main.c
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/fbdev/sis/sis_main.h
similarity index 100%
rename from drivers/video/sis/sis_main.h
rename to drivers/video/fbdev/sis/sis_main.h
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/fbdev/sis/vgatypes.h
similarity index 100%
rename from drivers/video/sis/vgatypes.h
rename to drivers/video/fbdev/sis/vgatypes.h
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/fbdev/sis/vstruct.h
similarity index 100%
rename from drivers/video/sis/vstruct.h
rename to drivers/video/fbdev/sis/vstruct.h
diff --git a/drivers/video/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c
similarity index 100%
rename from drivers/video/skeletonfb.c
rename to drivers/video/fbdev/skeletonfb.c
diff --git a/drivers/video/sm501fb.c b/drivers/video/fbdev/sm501fb.c
similarity index 100%
rename from drivers/video/sm501fb.c
rename to drivers/video/fbdev/sm501fb.c
diff --git a/drivers/video/smscufx.c b/drivers/video/fbdev/smscufx.c
similarity index 100%
rename from drivers/video/smscufx.c
rename to drivers/video/fbdev/smscufx.c
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
similarity index 100%
rename from drivers/video/ssd1307fb.c
rename to drivers/video/fbdev/ssd1307fb.c
diff --git a/drivers/video/sstfb.c b/drivers/video/fbdev/sstfb.c
similarity index 100%
rename from drivers/video/sstfb.c
rename to drivers/video/fbdev/sstfb.c
diff --git a/drivers/video/sticore.h b/drivers/video/fbdev/sticore.h
similarity index 100%
rename from drivers/video/sticore.h
rename to drivers/video/fbdev/sticore.h
diff --git a/drivers/video/stifb.c b/drivers/video/fbdev/stifb.c
similarity index 100%
rename from drivers/video/stifb.c
rename to drivers/video/fbdev/stifb.c
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c
similarity index 100%
rename from drivers/video/sunxvr1000.c
rename to drivers/video/fbdev/sunxvr1000.c
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/fbdev/sunxvr2500.c
similarity index 100%
rename from drivers/video/sunxvr2500.c
rename to drivers/video/fbdev/sunxvr2500.c
diff --git a/drivers/video/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c
similarity index 100%
rename from drivers/video/sunxvr500.c
rename to drivers/video/fbdev/sunxvr500.c
diff --git a/drivers/video/tcx.c b/drivers/video/fbdev/tcx.c
similarity index 100%
rename from drivers/video/tcx.c
rename to drivers/video/fbdev/tcx.c
diff --git a/drivers/video/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
similarity index 100%
rename from drivers/video/tdfxfb.c
rename to drivers/video/fbdev/tdfxfb.c
diff --git a/drivers/video/tgafb.c b/drivers/video/fbdev/tgafb.c
similarity index 100%
rename from drivers/video/tgafb.c
rename to drivers/video/fbdev/tgafb.c
diff --git a/drivers/video/tmiofb.c b/drivers/video/fbdev/tmiofb.c
similarity index 100%
rename from drivers/video/tmiofb.c
rename to drivers/video/fbdev/tmiofb.c
diff --git a/drivers/video/tridentfb.c b/drivers/video/fbdev/tridentfb.c
similarity index 100%
rename from drivers/video/tridentfb.c
rename to drivers/video/fbdev/tridentfb.c
diff --git a/drivers/video/udlfb.c b/drivers/video/fbdev/udlfb.c
similarity index 100%
rename from drivers/video/udlfb.c
rename to drivers/video/fbdev/udlfb.c
diff --git a/drivers/video/uvesafb.c b/drivers/video/fbdev/uvesafb.c
similarity index 100%
rename from drivers/video/uvesafb.c
rename to drivers/video/fbdev/uvesafb.c
diff --git a/drivers/video/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
similarity index 100%
rename from drivers/video/valkyriefb.c
rename to drivers/video/fbdev/valkyriefb.c
diff --git a/drivers/video/valkyriefb.h b/drivers/video/fbdev/valkyriefb.h
similarity index 100%
rename from drivers/video/valkyriefb.h
rename to drivers/video/fbdev/valkyriefb.h
diff --git a/drivers/video/vermilion/Makefile b/drivers/video/fbdev/vermilion/Makefile
similarity index 100%
rename from drivers/video/vermilion/Makefile
rename to drivers/video/fbdev/vermilion/Makefile
diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/fbdev/vermilion/cr_pll.c
similarity index 100%
rename from drivers/video/vermilion/cr_pll.c
rename to drivers/video/fbdev/vermilion/cr_pll.c
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c
similarity index 100%
rename from drivers/video/vermilion/vermilion.c
rename to drivers/video/fbdev/vermilion/vermilion.c
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/fbdev/vermilion/vermilion.h
similarity index 100%
rename from drivers/video/vermilion/vermilion.h
rename to drivers/video/fbdev/vermilion/vermilion.h
diff --git a/drivers/video/vesafb.c b/drivers/video/fbdev/vesafb.c
similarity index 100%
rename from drivers/video/vesafb.c
rename to drivers/video/fbdev/vesafb.c
diff --git a/drivers/video/vfb.c b/drivers/video/fbdev/vfb.c
similarity index 100%
rename from drivers/video/vfb.c
rename to drivers/video/fbdev/vfb.c
diff --git a/drivers/video/vga16fb.c b/drivers/video/fbdev/vga16fb.c
similarity index 100%
rename from drivers/video/vga16fb.c
rename to drivers/video/fbdev/vga16fb.c
diff --git a/drivers/video/via/Makefile b/drivers/video/fbdev/via/Makefile
similarity index 100%
rename from drivers/video/via/Makefile
rename to drivers/video/fbdev/via/Makefile
diff --git a/drivers/video/via/accel.c b/drivers/video/fbdev/via/accel.c
similarity index 100%
rename from drivers/video/via/accel.c
rename to drivers/video/fbdev/via/accel.c
diff --git a/drivers/video/via/accel.h b/drivers/video/fbdev/via/accel.h
similarity index 100%
rename from drivers/video/via/accel.h
rename to drivers/video/fbdev/via/accel.h
diff --git a/drivers/video/via/chip.h b/drivers/video/fbdev/via/chip.h
similarity index 100%
rename from drivers/video/via/chip.h
rename to drivers/video/fbdev/via/chip.h
diff --git a/drivers/video/via/debug.h b/drivers/video/fbdev/via/debug.h
similarity index 100%
rename from drivers/video/via/debug.h
rename to drivers/video/fbdev/via/debug.h
diff --git a/drivers/video/via/dvi.c b/drivers/video/fbdev/via/dvi.c
similarity index 100%
rename from drivers/video/via/dvi.c
rename to drivers/video/fbdev/via/dvi.c
diff --git a/drivers/video/via/dvi.h b/drivers/video/fbdev/via/dvi.h
similarity index 100%
rename from drivers/video/via/dvi.h
rename to drivers/video/fbdev/via/dvi.h
diff --git a/drivers/video/via/global.c b/drivers/video/fbdev/via/global.c
similarity index 100%
rename from drivers/video/via/global.c
rename to drivers/video/fbdev/via/global.c
diff --git a/drivers/video/via/global.h b/drivers/video/fbdev/via/global.h
similarity index 100%
rename from drivers/video/via/global.h
rename to drivers/video/fbdev/via/global.h
diff --git a/drivers/video/via/hw.c b/drivers/video/fbdev/via/hw.c
similarity index 100%
rename from drivers/video/via/hw.c
rename to drivers/video/fbdev/via/hw.c
diff --git a/drivers/video/via/hw.h b/drivers/video/fbdev/via/hw.h
similarity index 100%
rename from drivers/video/via/hw.h
rename to drivers/video/fbdev/via/hw.h
diff --git a/drivers/video/via/ioctl.c b/drivers/video/fbdev/via/ioctl.c
similarity index 100%
rename from drivers/video/via/ioctl.c
rename to drivers/video/fbdev/via/ioctl.c
diff --git a/drivers/video/via/ioctl.h b/drivers/video/fbdev/via/ioctl.h
similarity index 100%
rename from drivers/video/via/ioctl.h
rename to drivers/video/fbdev/via/ioctl.h
diff --git a/drivers/video/via/lcd.c b/drivers/video/fbdev/via/lcd.c
similarity index 100%
rename from drivers/video/via/lcd.c
rename to drivers/video/fbdev/via/lcd.c
diff --git a/drivers/video/via/lcd.h b/drivers/video/fbdev/via/lcd.h
similarity index 100%
rename from drivers/video/via/lcd.h
rename to drivers/video/fbdev/via/lcd.h
diff --git a/drivers/video/via/share.h b/drivers/video/fbdev/via/share.h
similarity index 100%
rename from drivers/video/via/share.h
rename to drivers/video/fbdev/via/share.h
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/fbdev/via/tblDPASetting.c
similarity index 100%
rename from drivers/video/via/tblDPASetting.c
rename to drivers/video/fbdev/via/tblDPASetting.c
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/fbdev/via/tblDPASetting.h
similarity index 100%
rename from drivers/video/via/tblDPASetting.h
rename to drivers/video/fbdev/via/tblDPASetting.h
diff --git a/drivers/video/via/via-core.c b/drivers/video/fbdev/via/via-core.c
similarity index 100%
rename from drivers/video/via/via-core.c
rename to drivers/video/fbdev/via/via-core.c
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/fbdev/via/via-gpio.c
similarity index 100%
rename from drivers/video/via/via-gpio.c
rename to drivers/video/fbdev/via/via-gpio.c
diff --git a/drivers/video/via/via_aux.c b/drivers/video/fbdev/via/via_aux.c
similarity index 100%
rename from drivers/video/via/via_aux.c
rename to drivers/video/fbdev/via/via_aux.c
diff --git a/drivers/video/via/via_aux.h b/drivers/video/fbdev/via/via_aux.h
similarity index 100%
rename from drivers/video/via/via_aux.h
rename to drivers/video/fbdev/via/via_aux.h
diff --git a/drivers/video/via/via_aux_ch7301.c b/drivers/video/fbdev/via/via_aux_ch7301.c
similarity index 100%
rename from drivers/video/via/via_aux_ch7301.c
rename to drivers/video/fbdev/via/via_aux_ch7301.c
diff --git a/drivers/video/via/via_aux_edid.c b/drivers/video/fbdev/via/via_aux_edid.c
similarity index 100%
rename from drivers/video/via/via_aux_edid.c
rename to drivers/video/fbdev/via/via_aux_edid.c
diff --git a/drivers/video/via/via_aux_sii164.c b/drivers/video/fbdev/via/via_aux_sii164.c
similarity index 100%
rename from drivers/video/via/via_aux_sii164.c
rename to drivers/video/fbdev/via/via_aux_sii164.c
diff --git a/drivers/video/via/via_aux_vt1621.c b/drivers/video/fbdev/via/via_aux_vt1621.c
similarity index 100%
rename from drivers/video/via/via_aux_vt1621.c
rename to drivers/video/fbdev/via/via_aux_vt1621.c
diff --git a/drivers/video/via/via_aux_vt1622.c b/drivers/video/fbdev/via/via_aux_vt1622.c
similarity index 100%
rename from drivers/video/via/via_aux_vt1622.c
rename to drivers/video/fbdev/via/via_aux_vt1622.c
diff --git a/drivers/video/via/via_aux_vt1625.c b/drivers/video/fbdev/via/via_aux_vt1625.c
similarity index 100%
rename from drivers/video/via/via_aux_vt1625.c
rename to drivers/video/fbdev/via/via_aux_vt1625.c
diff --git a/drivers/video/via/via_aux_vt1631.c b/drivers/video/fbdev/via/via_aux_vt1631.c
similarity index 100%
rename from drivers/video/via/via_aux_vt1631.c
rename to drivers/video/fbdev/via/via_aux_vt1631.c
diff --git a/drivers/video/via/via_aux_vt1632.c b/drivers/video/fbdev/via/via_aux_vt1632.c
similarity index 100%
rename from drivers/video/via/via_aux_vt1632.c
rename to drivers/video/fbdev/via/via_aux_vt1632.c
diff --git a/drivers/video/via/via_aux_vt1636.c b/drivers/video/fbdev/via/via_aux_vt1636.c
similarity index 100%
rename from drivers/video/via/via_aux_vt1636.c
rename to drivers/video/fbdev/via/via_aux_vt1636.c
diff --git a/drivers/video/via/via_clock.c b/drivers/video/fbdev/via/via_clock.c
similarity index 100%
rename from drivers/video/via/via_clock.c
rename to drivers/video/fbdev/via/via_clock.c
diff --git a/drivers/video/via/via_clock.h b/drivers/video/fbdev/via/via_clock.h
similarity index 100%
rename from drivers/video/via/via_clock.h
rename to drivers/video/fbdev/via/via_clock.h
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/fbdev/via/via_i2c.c
similarity index 100%
rename from drivers/video/via/via_i2c.c
rename to drivers/video/fbdev/via/via_i2c.c
diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/fbdev/via/via_modesetting.c
similarity index 100%
rename from drivers/video/via/via_modesetting.c
rename to drivers/video/fbdev/via/via_modesetting.c
diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/fbdev/via/via_modesetting.h
similarity index 100%
rename from drivers/video/via/via_modesetting.h
rename to drivers/video/fbdev/via/via_modesetting.h
diff --git a/drivers/video/via/via_utility.c b/drivers/video/fbdev/via/via_utility.c
similarity index 100%
rename from drivers/video/via/via_utility.c
rename to drivers/video/fbdev/via/via_utility.c
diff --git a/drivers/video/via/via_utility.h b/drivers/video/fbdev/via/via_utility.h
similarity index 100%
rename from drivers/video/via/via_utility.h
rename to drivers/video/fbdev/via/via_utility.h
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
similarity index 100%
rename from drivers/video/via/viafbdev.c
rename to drivers/video/fbdev/via/viafbdev.c
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/fbdev/via/viafbdev.h
similarity index 100%
rename from drivers/video/via/viafbdev.h
rename to drivers/video/fbdev/via/viafbdev.h
diff --git a/drivers/video/via/viamode.c b/drivers/video/fbdev/via/viamode.c
similarity index 100%
rename from drivers/video/via/viamode.c
rename to drivers/video/fbdev/via/viamode.c
diff --git a/drivers/video/via/viamode.h b/drivers/video/fbdev/via/viamode.h
similarity index 100%
rename from drivers/video/via/viamode.h
rename to drivers/video/fbdev/via/viamode.h
diff --git a/drivers/video/via/vt1636.c b/drivers/video/fbdev/via/vt1636.c
similarity index 100%
rename from drivers/video/via/vt1636.c
rename to drivers/video/fbdev/via/vt1636.c
diff --git a/drivers/video/via/vt1636.h b/drivers/video/fbdev/via/vt1636.h
similarity index 100%
rename from drivers/video/via/vt1636.h
rename to drivers/video/fbdev/via/vt1636.h
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c
similarity index 100%
rename from drivers/video/vt8500lcdfb.c
rename to drivers/video/fbdev/vt8500lcdfb.c
diff --git a/drivers/video/vt8500lcdfb.h b/drivers/video/fbdev/vt8500lcdfb.h
similarity index 100%
rename from drivers/video/vt8500lcdfb.h
rename to drivers/video/fbdev/vt8500lcdfb.h
diff --git a/drivers/video/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
similarity index 100%
rename from drivers/video/vt8623fb.c
rename to drivers/video/fbdev/vt8623fb.c
diff --git a/drivers/video/w100fb.c b/drivers/video/fbdev/w100fb.c
similarity index 100%
rename from drivers/video/w100fb.c
rename to drivers/video/fbdev/w100fb.c
diff --git a/drivers/video/w100fb.h b/drivers/video/fbdev/w100fb.h
similarity index 100%
rename from drivers/video/w100fb.h
rename to drivers/video/fbdev/w100fb.h
diff --git a/drivers/video/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c
similarity index 100%
rename from drivers/video/wm8505fb.c
rename to drivers/video/fbdev/wm8505fb.c
diff --git a/drivers/video/wm8505fb_regs.h b/drivers/video/fbdev/wm8505fb_regs.h
similarity index 100%
rename from drivers/video/wm8505fb_regs.h
rename to drivers/video/fbdev/wm8505fb_regs.h
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c
similarity index 99%
rename from drivers/video/wmt_ge_rops.c
rename to drivers/video/fbdev/wmt_ge_rops.c
index b0a9f34..9df6fe7 100644
--- a/drivers/video/wmt_ge_rops.c
+++ b/drivers/video/fbdev/wmt_ge_rops.c
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 #include <linux/fb.h>
 #include <linux/platform_device.h>
-#include "fb_draw.h"
+#include "core/fb_draw.h"
 
 #define GE_COMMAND_OFF		0x00
 #define GE_DEPTH_OFF		0x04
diff --git a/drivers/video/wmt_ge_rops.h b/drivers/video/fbdev/wmt_ge_rops.h
similarity index 100%
rename from drivers/video/wmt_ge_rops.h
rename to drivers/video/fbdev/wmt_ge_rops.h
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
similarity index 100%
rename from drivers/video/xen-fbfront.c
rename to drivers/video/fbdev/xen-fbfront.c
diff --git a/drivers/video/xilinxfb.c b/drivers/video/fbdev/xilinxfb.c
similarity index 100%
rename from drivers/video/xilinxfb.c
rename to drivers/video/fbdev/xilinxfb.c
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
deleted file mode 100644
index 63b23f8..0000000
--- a/drivers/video/omap2/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config OMAP2_VRFB
-	bool
-
-if ARCH_OMAP2PLUS
-
-source "drivers/video/omap2/dss/Kconfig"
-source "drivers/video/omap2/omapfb/Kconfig"
-source "drivers/video/omap2/displays-new/Kconfig"
-
-endif
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index 06990c6..61e706c0 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -320,7 +320,7 @@
 	struct pci_dev *pdev;
 	struct tsi148_driver *bridge;
 
-	pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+	pdev = to_pci_dev(tsi148_bridge->parent);
 
 	bridge = tsi148_bridge->driver_priv;
 
@@ -433,9 +433,7 @@
 		iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
 
 		if (sync != 0) {
-			pdev = container_of(tsi148_bridge->parent,
-				struct pci_dev, dev);
-
+			pdev = to_pci_dev(tsi148_bridge->parent);
 			synchronize_irq(pdev->irq);
 		}
 	} else {
@@ -741,7 +739,7 @@
 	reg_join(vme_bound_high, vme_bound_low, &vme_bound);
 	reg_join(pci_offset_high, pci_offset_low, &pci_offset);
 
-	*pci_base = (dma_addr_t)vme_base + pci_offset;
+	*pci_base = (dma_addr_t)(*vme_base + pci_offset);
 
 	*enabled = 0;
 	*aspace = 0;
@@ -814,7 +812,7 @@
 
 	tsi148_bridge = image->parent;
 
-	pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+	pdev = to_pci_dev(tsi148_bridge->parent);
 
 	existing_size = (unsigned long long)(image->bus_resource.end -
 		image->bus_resource.start);
@@ -910,11 +908,15 @@
 	unsigned long long pci_bound, vme_offset, pci_base;
 	struct vme_bridge *tsi148_bridge;
 	struct tsi148_driver *bridge;
+	struct pci_bus_region region;
+	struct pci_dev *pdev;
 
 	tsi148_bridge = image->parent;
 
 	bridge = tsi148_bridge->driver_priv;
 
+	pdev = to_pci_dev(tsi148_bridge->parent);
+
 	/* Verify input data */
 	if (vme_base & 0xFFFF) {
 		dev_err(tsi148_bridge->parent, "Invalid VME Window "
@@ -949,7 +951,9 @@
 		pci_bound = 0;
 		vme_offset = 0;
 	} else {
-		pci_base = (unsigned long long)image->bus_resource.start;
+		pcibios_resource_to_bus(pdev->bus, &region,
+					&image->bus_resource);
+		pci_base = region.start;
 
 		/*
 		 * Bound address is a valid address for the window, adjust
@@ -2232,7 +2236,7 @@
 	struct pci_dev *pdev;
 
 	/* Find pci_dev container of dev */
-	pdev = container_of(parent, struct pci_dev, dev);
+	pdev = to_pci_dev(parent);
 
 	return pci_alloc_consistent(pdev, size, dma);
 }
@@ -2243,7 +2247,7 @@
 	struct pci_dev *pdev;
 
 	/* Find pci_dev container of dev */
-	pdev = container_of(parent, struct pci_dev, dev);
+	pdev = to_pci_dev(parent);
 
 	pci_free_consistent(pdev, size, vaddr, dma);
 }
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index b96f61b..ff52618 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -614,27 +614,11 @@
 	return err;
 }
 
-/*
- * Handle sysfs file creation and removal here, before userspace is told that
- * the device is added / removed from the system
- */
-static int w1_bus_notify(struct notifier_block *nb, unsigned long action,
-			 void *data)
+static int w1_family_notify(unsigned long action, struct w1_slave *sl)
 {
-	struct device *dev = data;
-	struct w1_slave *sl;
 	struct w1_family_ops *fops;
 	int err;
 
-	/*
-	 * Only care about slave devices at the moment.  Yes, we should use a
-	 * separate "type" for this, but for now, look at the release function
-	 * to know which type it is...
-	 */
-	if (dev->release != w1_slave_release)
-		return 0;
-
-	sl = dev_to_w1_slave(dev);
 	fops = sl->family->fops;
 
 	if (!fops)
@@ -673,10 +657,6 @@
 	return 0;
 }
 
-static struct notifier_block w1_bus_nb = {
-	.notifier_call = w1_bus_notify,
-};
-
 static int __w1_attach_slave_device(struct w1_slave *sl)
 {
 	int err;
@@ -698,6 +678,9 @@
 	dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__,
 		dev_name(&sl->dev), sl);
 
+	/* suppress for w1_family_notify before sending KOBJ_ADD */
+	dev_set_uevent_suppress(&sl->dev, true);
+
 	err = device_register(&sl->dev);
 	if (err < 0) {
 		dev_err(&sl->dev,
@@ -705,7 +688,7 @@
 			dev_name(&sl->dev), err);
 		return err;
 	}
-
+	w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl);
 
 	dev_set_uevent_suppress(&sl->dev, false);
 	kobject_uevent(&sl->dev.kobj, KOBJ_ADD);
@@ -799,6 +782,7 @@
 		msg.type = W1_SLAVE_REMOVE;
 		w1_netlink_send(sl->master, &msg);
 
+		w1_family_notify(BUS_NOTIFY_DEL_DEVICE, sl);
 		device_unregister(&sl->dev);
 		#ifdef DEBUG
 		memset(sl, 0, sizeof(*sl));
@@ -1186,10 +1170,6 @@
 		goto err_out_exit_init;
 	}
 
-	retval = bus_register_notifier(&w1_bus_type, &w1_bus_nb);
-	if (retval)
-		goto err_out_bus_unregister;
-
 	retval = driver_register(&w1_master_driver);
 	if (retval) {
 		printk(KERN_ERR
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 5234964..a02704a 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -300,12 +300,6 @@
 	struct w1_netlink_msg *w;
 	u32 *id;
 
-	if (mcmd->type != W1_LIST_MASTERS) {
-		printk(KERN_NOTICE "%s: msg: %x.%x, wrong type: %u, len: %u.\n",
-			__func__, msg->id.idx, msg->id.val, mcmd->type, mcmd->len);
-		return -EPROTO;
-	}
-
 	cn = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!cn)
 		return -ENOMEM;
@@ -441,6 +435,9 @@
 		w1_netlink_send_error(&node->block->msg, node->m, cmd,
 			node->block->portid, err);
 
+	/* ref taken in w1_search_slave or w1_search_master_id when building
+	 * the block
+	 */
 	if (sl)
 		w1_unref_slave(sl);
 	else
@@ -503,30 +500,42 @@
 
 	msg_len = msg->len;
 	while (msg_len && !err) {
-		struct w1_reg_num id;
-		u16 mlen = m->len;
 
 		dev = NULL;
 		sl = NULL;
 
-		memcpy(&id, m->id.id, sizeof(id));
-#if 0
-		printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n",
-				__func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len);
-#endif
 		if (m->len + sizeof(struct w1_netlink_msg) > msg_len) {
 			err = -E2BIG;
 			break;
 		}
 
+		/* execute on this thread, no need to process later */
+		if (m->type == W1_LIST_MASTERS) {
+			err = w1_process_command_root(msg, m, nsp->portid);
+			goto out_cont;
+		}
+
+		/* All following message types require additional data,
+		 * check here before references are taken.
+		 */
+		if (!m->len) {
+			err = -EPROTO;
+			goto out_cont;
+		}
+
+		/* both search calls take reference counts */
 		if (m->type == W1_MASTER_CMD) {
 			dev = w1_search_master_id(m->id.mst.id);
 		} else if (m->type == W1_SLAVE_CMD) {
-			sl = w1_search_slave(&id);
+			sl = w1_search_slave((struct w1_reg_num *)m->id.id);
 			if (sl)
 				dev = sl->master;
 		} else {
-			err = w1_process_command_root(msg, m, nsp->portid);
+			printk(KERN_NOTICE
+				"%s: msg: %x.%x, wrong type: %u, len: %u.\n",
+				__func__, msg->id.idx, msg->id.val,
+				m->type, m->len);
+			err = -EPROTO;
 			goto out_cont;
 		}
 
@@ -536,8 +545,6 @@
 		}
 
 		err = 0;
-		if (!mlen)
-			goto out_cont;
 
 		atomic_inc(&block->refcnt);
 		node->async.cb = w1_process_cb;
@@ -557,7 +564,8 @@
 		if (err)
 			w1_netlink_send_error(msg, m, NULL, nsp->portid, err);
 		msg_len -= sizeof(struct w1_netlink_msg) + m->len;
-		m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len);
+		m = (struct w1_netlink_msg *)(((u8 *)m) +
+			sizeof(struct w1_netlink_msg) + m->len);
 
 		/*
 		 * Let's allow requests for nonexisting devices.
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index fc6c94c..32f9236 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -198,10 +198,32 @@
 	void (*cb)(void);
 };
 
+static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
+{
+	switch (code) {
+	case SYS_DOWN:
+	case SYS_HALT:
+	case SYS_POWER_OFF:
+		shutting_down = SHUTDOWN_POWEROFF;
+	default:
+		break;
+	}
+	return NOTIFY_DONE;
+}
 static void do_poweroff(void)
 {
-	shutting_down = SHUTDOWN_POWEROFF;
-	orderly_poweroff(false);
+	switch (system_state) {
+	case SYSTEM_BOOTING:
+		orderly_poweroff(true);
+		break;
+	case SYSTEM_RUNNING:
+		orderly_poweroff(false);
+		break;
+	default:
+		/* Don't do it when we are halting/rebooting. */
+		pr_info("Ignoring Xen toolstack shutdown.\n");
+		break;
+	}
 }
 
 static void do_reboot(void)
@@ -307,6 +329,10 @@
 	.callback = shutdown_handler
 };
 
+static struct notifier_block xen_reboot_nb = {
+	.notifier_call = poweroff_nb,
+};
+
 static int setup_shutdown_watcher(void)
 {
 	int err;
@@ -317,6 +343,7 @@
 		return err;
 	}
 
+
 #ifdef CONFIG_MAGIC_SYSRQ
 	err = register_xenbus_watch(&sysrq_watch);
 	if (err) {
@@ -345,6 +372,7 @@
 	if (!xen_domain())
 		return -ENODEV;
 	register_xenstore_notifier(&xenstore_notifier);
+	register_reboot_notifier(&xen_reboot_nb);
 
 	return 0;
 }
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 929dd46..607e414 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -217,7 +217,7 @@
 	if (result == 0) {
 		for (i = 0; i < op->value; i++) {
 			op->msix_entries[i].entry = entries[i].entry;
-			if (entries[i].vector)
+			if (entries[i].vector) {
 				op->msix_entries[i].vector =
 					xen_pirq_from_irq(entries[i].vector);
 				if (unlikely(verbose_request))
@@ -225,6 +225,7 @@
 						"MSI-X[%d]: %d\n",
 						pci_name(dev), i,
 						op->msix_entries[i].vector);
+			}
 		}
 	} else
 		pr_warn_ratelimited("%s: error enabling MSI-X for guest %u: err %d!\n",
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index 3165ce3..51afff9 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -137,6 +137,8 @@
 	/* Publish this device. */
 	if (!err)
 		err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid);
+	else
+		kfree(dev_entry);
 
 out:
 	return err;
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index b6d5fff..ba804f3 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -50,6 +50,7 @@
 #include <xen/xenbus.h>
 #include <xen/xen.h>
 #include "xenbus_comms.h"
+#include "xenbus_probe.h"
 
 struct xs_stored_msg {
 	struct list_head list;
@@ -139,6 +140,29 @@
 	return xsd_errors[i].errnum;
 }
 
+static bool xenbus_ok(void)
+{
+	switch (xen_store_domain_type) {
+	case XS_LOCAL:
+		switch (system_state) {
+		case SYSTEM_POWER_OFF:
+		case SYSTEM_RESTART:
+		case SYSTEM_HALT:
+			return false;
+		default:
+			break;
+		}
+		return true;
+	case XS_PV:
+	case XS_HVM:
+		/* FIXME: Could check that the remote domain is alive,
+		 * but it is normally initial domain. */
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
 static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
 {
 	struct xs_stored_msg *msg;
@@ -148,9 +172,20 @@
 
 	while (list_empty(&xs_state.reply_list)) {
 		spin_unlock(&xs_state.reply_lock);
-		/* XXX FIXME: Avoid synchronous wait for response here. */
-		wait_event(xs_state.reply_waitq,
-			   !list_empty(&xs_state.reply_list));
+		if (xenbus_ok())
+			/* XXX FIXME: Avoid synchronous wait for response here. */
+			wait_event_timeout(xs_state.reply_waitq,
+					   !list_empty(&xs_state.reply_list),
+					   msecs_to_jiffies(500));
+		else {
+			/*
+			 * If we are in the process of being shut-down there is
+			 * no point of trying to contact XenBus - it is either
+			 * killed (xenstored application) or the other domain
+			 * has been killed or is unreachable.
+			 */
+			return ERR_PTR(-EIO);
+		}
 		spin_lock(&xs_state.reply_lock);
 	}
 
@@ -215,6 +250,9 @@
 
 	mutex_unlock(&xs_state.request_mutex);
 
+	if (IS_ERR(ret))
+		return ret;
+
 	if ((msg->type == XS_TRANSACTION_END) ||
 	    ((req_msg.type == XS_TRANSACTION_START) &&
 	     (msg->type == XS_ERROR)))
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 8388f02..0c4d96d 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -273,16 +273,6 @@
 
 --------------------------------------------------------------------------
 
-Driver: ip2 -- Computone IntelliPort Plus serial device
-
-File: intelliport2.bin
-
-Licence: Unknown
-
-Found in hex form in kernel source.
-
---------------------------------------------------------------------------
-
 Driver: CPiA2 -- cameras based on Vision's CPiA2
 
 File: cpia2/stv0672_vp4.bin
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index df9c9141..5be1f99 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -253,6 +253,11 @@
 	cifs_set_oplock_level(cifs_inode, 0);
 	cifs_inode->delete_pending = false;
 	cifs_inode->invalid_mapping = false;
+	clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cifs_inode->flags);
+	clear_bit(CIFS_INODE_PENDING_WRITERS, &cifs_inode->flags);
+	clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cifs_inode->flags);
+	spin_lock_init(&cifs_inode->writers_lock);
+	cifs_inode->writers = 0;
 	cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
 	cifs_inode->server_eof = 0;
 	cifs_inode->uniqueid = 0;
@@ -732,19 +737,26 @@
 				   unsigned long nr_segs, loff_t pos)
 {
 	struct inode *inode = file_inode(iocb->ki_filp);
+	struct cifsInodeInfo *cinode = CIFS_I(inode);
 	ssize_t written;
 	int rc;
 
+	written = cifs_get_writer(cinode);
+	if (written)
+		return written;
+
 	written = generic_file_aio_write(iocb, iov, nr_segs, pos);
 
 	if (CIFS_CACHE_WRITE(CIFS_I(inode)))
-		return written;
+		goto out;
 
 	rc = filemap_fdatawrite(inode->i_mapping);
 	if (rc)
 		cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n",
 			 rc, inode);
 
+out:
+	cifs_put_writer(cinode);
 	return written;
 }
 
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index c0f3718..30f6e92 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -228,6 +228,8 @@
 	/* verify the message */
 	int (*check_message)(char *, unsigned int);
 	bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
+	void (*downgrade_oplock)(struct TCP_Server_Info *,
+					struct cifsInodeInfo *, bool);
 	/* process transaction2 response */
 	bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
 			     char *, int);
@@ -1113,6 +1115,12 @@
 	unsigned int epoch;		/* used to track lease state changes */
 	bool delete_pending;		/* DELETE_ON_CLOSE is set */
 	bool invalid_mapping;		/* pagecache is invalid */
+	unsigned long flags;
+#define CIFS_INODE_PENDING_OPLOCK_BREAK   (0) /* oplock break in progress */
+#define CIFS_INODE_PENDING_WRITERS	  (1) /* Writes in progress */
+#define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2) /* Downgrade oplock to L2 */
+	spinlock_t writers_lock;
+	unsigned int writers;		/* Number of writers on this inode */
 	unsigned long time;		/* jiffies of last update of inode */
 	u64  server_eof;		/* current file size on server -- protected by i_lock */
 	u64  uniqueid;			/* server inode number */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index acc4ee8..ca7980a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -127,6 +127,9 @@
 extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
 				      int offset);
 extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
+extern int cifs_get_writer(struct cifsInodeInfo *cinode);
+extern void cifs_put_writer(struct cifsInodeInfo *cinode);
+extern void cifs_done_oplock_break(struct cifsInodeInfo *cinode);
 extern int cifs_unlock_range(struct cifsFileInfo *cfile,
 			     struct file_lock *flock, const unsigned int xid);
 extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f3264bd..6ce4e09 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -6197,6 +6197,9 @@
 	cifs_dbg(FYI, "ea length %d\n", list_len);
 	if (list_len <= 8) {
 		cifs_dbg(FYI, "empty EA list returned from server\n");
+		/* didn't find the named attribute */
+		if (ea_name)
+			rc = -ENODATA;
 		goto QAllEAsOut;
 	}
 
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 8add255..5ed03e0 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2599,7 +2599,7 @@
 			ssize_t err;
 
 			err = generic_write_sync(file, iocb->ki_pos - rc, rc);
-			if (rc < 0)
+			if (err < 0)
 				rc = err;
 		}
 	} else {
@@ -2621,12 +2621,20 @@
 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
 	ssize_t written;
 
+	written = cifs_get_writer(cinode);
+	if (written)
+		return written;
+
 	if (CIFS_CACHE_WRITE(cinode)) {
 		if (cap_unix(tcon->ses) &&
 		(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
-		    && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
-			return generic_file_aio_write(iocb, iov, nr_segs, pos);
-		return cifs_writev(iocb, iov, nr_segs, pos);
+		  && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
+			written = generic_file_aio_write(
+					iocb, iov, nr_segs, pos);
+			goto out;
+		}
+		written = cifs_writev(iocb, iov, nr_segs, pos);
+		goto out;
 	}
 	/*
 	 * For non-oplocked files in strict cache mode we need to write the data
@@ -2646,6 +2654,8 @@
 			 inode);
 		cinode->oplock = 0;
 	}
+out:
+	cifs_put_writer(cinode);
 	return written;
 }
 
@@ -2872,7 +2882,7 @@
 					    cifs_uncached_readv_complete);
 		if (!rdata) {
 			rc = -ENOMEM;
-			goto error;
+			break;
 		}
 
 		rc = cifs_read_allocate_pages(rdata, npages);
@@ -3621,6 +3631,13 @@
 	return rc;
 }
 
+static int
+cifs_pending_writers_wait(void *unused)
+{
+	schedule();
+	return 0;
+}
+
 void cifs_oplock_break(struct work_struct *work)
 {
 	struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
@@ -3628,8 +3645,15 @@
 	struct inode *inode = cfile->dentry->d_inode;
 	struct cifsInodeInfo *cinode = CIFS_I(inode);
 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+	struct TCP_Server_Info *server = tcon->ses->server;
 	int rc = 0;
 
+	wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
+			cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE);
+
+	server->ops->downgrade_oplock(server, cinode,
+		test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags));
+
 	if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) &&
 						cifs_has_mand_locks(cinode)) {
 		cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n",
@@ -3666,6 +3690,7 @@
 							     cinode);
 		cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
 	}
+	cifs_done_oplock_break(cinode);
 }
 
 /*
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 2f9f379..3b0c62e 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -466,8 +466,22 @@
 				cifs_dbg(FYI, "file id match, oplock break\n");
 				pCifsInode = CIFS_I(netfile->dentry->d_inode);
 
-				cifs_set_oplock_level(pCifsInode,
-					pSMB->OplockLevel ? OPLOCK_READ : 0);
+				set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
+					&pCifsInode->flags);
+
+				/*
+				 * Set flag if the server downgrades the oplock
+				 * to L2 else clear.
+				 */
+				if (pSMB->OplockLevel)
+					set_bit(
+					   CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+					   &pCifsInode->flags);
+				else
+					clear_bit(
+					   CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+					   &pCifsInode->flags);
+
 				queue_work(cifsiod_wq,
 					   &netfile->oplock_break);
 				netfile->oplock_break_cancelled = false;
@@ -551,6 +565,62 @@
 		cinode->oplock = 0;
 }
 
+static int
+cifs_oplock_break_wait(void *unused)
+{
+	schedule();
+	return signal_pending(current) ? -ERESTARTSYS : 0;
+}
+
+/*
+ * We wait for oplock breaks to be processed before we attempt to perform
+ * writes.
+ */
+int cifs_get_writer(struct cifsInodeInfo *cinode)
+{
+	int rc;
+
+start:
+	rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK,
+				   cifs_oplock_break_wait, TASK_KILLABLE);
+	if (rc)
+		return rc;
+
+	spin_lock(&cinode->writers_lock);
+	if (!cinode->writers)
+		set_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+	cinode->writers++;
+	/* Check to see if we have started servicing an oplock break */
+	if (test_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags)) {
+		cinode->writers--;
+		if (cinode->writers == 0) {
+			clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+			wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS);
+		}
+		spin_unlock(&cinode->writers_lock);
+		goto start;
+	}
+	spin_unlock(&cinode->writers_lock);
+	return 0;
+}
+
+void cifs_put_writer(struct cifsInodeInfo *cinode)
+{
+	spin_lock(&cinode->writers_lock);
+	cinode->writers--;
+	if (cinode->writers == 0) {
+		clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+		wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS);
+	}
+	spin_unlock(&cinode->writers_lock);
+}
+
+void cifs_done_oplock_break(struct cifsInodeInfo *cinode)
+{
+	clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags);
+	wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK);
+}
+
 bool
 backup_cred(struct cifs_sb_info *cifs_sb)
 {
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 526fb89..d1fdfa8 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -372,6 +372,16 @@
 	return 0;
 }
 
+static void
+cifs_downgrade_oplock(struct TCP_Server_Info *server,
+			struct cifsInodeInfo *cinode, bool set_level2)
+{
+	if (set_level2)
+		cifs_set_oplock_level(cinode, OPLOCK_READ);
+	else
+		cifs_set_oplock_level(cinode, 0);
+}
+
 static bool
 cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 		  char *buf, int malformed)
@@ -1019,6 +1029,7 @@
 	.clear_stats = cifs_clear_stats,
 	.print_stats = cifs_print_stats,
 	.is_oplock_break = is_valid_oplock_break,
+	.downgrade_oplock = cifs_downgrade_oplock,
 	.check_trans2 = cifs_check_trans2,
 	.need_neg = cifs_need_neg,
 	.negotiate = cifs_negotiate,
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index fb39662..b8021fd 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -575,9 +575,21 @@
 				else
 					cfile->oplock_break_cancelled = false;
 
-				server->ops->set_oplock_level(cinode,
-				  rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0,
-				  0, NULL);
+				set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
+					&cinode->flags);
+
+				/*
+				 * Set flag if the server downgrades the oplock
+				 * to L2 else clear.
+				 */
+				if (rsp->OplockLevel)
+					set_bit(
+					   CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+					   &cinode->flags);
+				else
+					clear_bit(
+					   CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+					   &cinode->flags);
 
 				queue_work(cifsiod_wq, &cfile->oplock_break);
 
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 192f51a..35ddc3e 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -905,6 +905,17 @@
 }
 
 static void
+smb2_downgrade_oplock(struct TCP_Server_Info *server,
+			struct cifsInodeInfo *cinode, bool set_level2)
+{
+	if (set_level2)
+		server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II,
+						0, NULL);
+	else
+		server->ops->set_oplock_level(cinode, 0, 0, NULL);
+}
+
+static void
 smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 		      unsigned int epoch, bool *purge_cache)
 {
@@ -1110,6 +1121,7 @@
 	.clear_stats = smb2_clear_stats,
 	.print_stats = smb2_print_stats,
 	.is_oplock_break = smb2_is_valid_oplock_break,
+	.downgrade_oplock = smb2_downgrade_oplock,
 	.need_neg = smb2_need_neg,
 	.negotiate = smb2_negotiate,
 	.negotiate_wsize = smb2_negotiate_wsize,
@@ -1184,6 +1196,7 @@
 	.clear_stats = smb2_clear_stats,
 	.print_stats = smb2_print_stats,
 	.is_oplock_break = smb2_is_valid_oplock_break,
+	.downgrade_oplock = smb2_downgrade_oplock,
 	.need_neg = smb2_need_neg,
 	.negotiate = smb2_negotiate,
 	.negotiate_wsize = smb2_negotiate_wsize,
@@ -1259,6 +1272,7 @@
 	.print_stats = smb2_print_stats,
 	.dump_share_caps = smb2_dump_share_caps,
 	.is_oplock_break = smb2_is_valid_oplock_break,
+	.downgrade_oplock = smb2_downgrade_oplock,
 	.need_neg = smb2_need_neg,
 	.negotiate = smb2_negotiate,
 	.negotiate_wsize = smb2_negotiate_wsize,
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 8603447..3802f8c 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1352,7 +1352,6 @@
 		     u64 persistent_fid, u64 volatile_fid)
 {
 	int rc;
-	char *res_key = NULL;
 	struct  compress_ioctl fsctl_input;
 	char *ret_data = NULL;
 
@@ -1365,7 +1364,6 @@
 			2 /* in data len */, &ret_data /* out data */, NULL);
 
 	cifs_dbg(FYI, "set compression rc %d\n", rc);
-	kfree(res_key);
 
 	return rc;
 }
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index abb0f1f..9852176 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -48,14 +48,18 @@
 
 static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
 {
+	static DEFINE_MUTEX(iattr_mutex);
+	struct kernfs_iattrs *ret;
 	struct iattr *iattrs;
 
+	mutex_lock(&iattr_mutex);
+
 	if (kn->iattr)
-		return kn->iattr;
+		goto out_unlock;
 
 	kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL);
 	if (!kn->iattr)
-		return NULL;
+		goto out_unlock;
 	iattrs = &kn->iattr->ia_iattr;
 
 	/* assign default attributes */
@@ -65,8 +69,10 @@
 	iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;
 
 	simple_xattrs_init(&kn->iattr->xattrs);
-
-	return kn->iattr;
+out_unlock:
+	ret = kn->iattr;
+	mutex_unlock(&iattr_mutex);
+	return ret;
 }
 
 static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
diff --git a/fs/super.c b/fs/super.c
index e9dc3c3..48377f7 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -800,7 +800,10 @@
 
 static DEFINE_IDA(unnamed_dev_ida);
 static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
-static int unnamed_dev_start = 0; /* don't bother trying below it */
+/* Many userspace utilities consider an FSID of 0 invalid.
+ * Always return at least 1 from get_anon_bdev.
+ */
+static int unnamed_dev_start = 1;
 
 int get_anon_bdev(dev_t *p)
 {
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 1b8b91b..28cc1acd 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -453,95 +453,3 @@
 	kernfs_remove_by_name(kobj->sd, attr->attr.name);
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
-
-struct sysfs_schedule_callback_struct {
-	struct list_head	workq_list;
-	struct kobject		*kobj;
-	void			(*func)(void *);
-	void			*data;
-	struct module		*owner;
-	struct work_struct	work;
-};
-
-static struct workqueue_struct *sysfs_workqueue;
-static DEFINE_MUTEX(sysfs_workq_mutex);
-static LIST_HEAD(sysfs_workq);
-static void sysfs_schedule_callback_work(struct work_struct *work)
-{
-	struct sysfs_schedule_callback_struct *ss = container_of(work,
-			struct sysfs_schedule_callback_struct, work);
-
-	(ss->func)(ss->data);
-	kobject_put(ss->kobj);
-	module_put(ss->owner);
-	mutex_lock(&sysfs_workq_mutex);
-	list_del(&ss->workq_list);
-	mutex_unlock(&sysfs_workq_mutex);
-	kfree(ss);
-}
-
-/**
- * sysfs_schedule_callback - helper to schedule a callback for a kobject
- * @kobj: object we're acting for.
- * @func: callback function to invoke later.
- * @data: argument to pass to @func.
- * @owner: module owning the callback code
- *
- * sysfs attribute methods must not unregister themselves or their parent
- * kobject (which would amount to the same thing).  Attempts to do so will
- * deadlock, since unregistration is mutually exclusive with driver
- * callbacks.
- *
- * Instead methods can call this routine, which will attempt to allocate
- * and schedule a workqueue request to call back @func with @data as its
- * argument in the workqueue's process context.  @kobj will be pinned
- * until @func returns.
- *
- * Returns 0 if the request was submitted, -ENOMEM if storage could not
- * be allocated, -ENODEV if a reference to @owner isn't available,
- * -EAGAIN if a callback has already been scheduled for @kobj.
- */
-int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
-		void *data, struct module *owner)
-{
-	struct sysfs_schedule_callback_struct *ss, *tmp;
-
-	if (!try_module_get(owner))
-		return -ENODEV;
-
-	mutex_lock(&sysfs_workq_mutex);
-	list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
-		if (ss->kobj == kobj) {
-			module_put(owner);
-			mutex_unlock(&sysfs_workq_mutex);
-			return -EAGAIN;
-		}
-	mutex_unlock(&sysfs_workq_mutex);
-
-	if (sysfs_workqueue == NULL) {
-		sysfs_workqueue = create_singlethread_workqueue("sysfsd");
-		if (sysfs_workqueue == NULL) {
-			module_put(owner);
-			return -ENOMEM;
-		}
-	}
-
-	ss = kmalloc(sizeof(*ss), GFP_KERNEL);
-	if (!ss) {
-		module_put(owner);
-		return -ENOMEM;
-	}
-	kobject_get(kobj);
-	ss->kobj = kobj;
-	ss->func = func;
-	ss->data = data;
-	ss->owner = owner;
-	INIT_WORK(&ss->work, sysfs_schedule_callback_work);
-	INIT_LIST_HEAD(&ss->workq_list);
-	mutex_lock(&sysfs_workq_mutex);
-	list_add_tail(&ss->workq_list, &sysfs_workq);
-	mutex_unlock(&sysfs_workq_mutex);
-	queue_work(sysfs_workqueue, &ss->work);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 75df77d..0479c32 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1344,6 +1344,14 @@
 	/*
 	 * If this is O_DIRECT or the mpage code calling tell them how large
 	 * the mapping is, so that we can avoid repeated get_blocks calls.
+	 *
+	 * If the mapping spans EOF, then we have to break the mapping up as the
+	 * mapping for blocks beyond EOF must be marked new so that sub block
+	 * regions can be correctly zeroed. We can't do this for mappings within
+	 * EOF unless the mapping was just allocated or is unwritten, otherwise
+	 * the callers would overwrite existing data with zeros. Hence we have
+	 * to split the mapping into a range up to and including EOF, and a
+	 * second mapping for beyond EOF.
 	 */
 	if (direct || size > (1 << inode->i_blkbits)) {
 		xfs_off_t		mapping_size;
@@ -1354,6 +1362,12 @@
 		ASSERT(mapping_size > 0);
 		if (mapping_size > size)
 			mapping_size = size;
+		if (offset < i_size_read(inode) &&
+		    offset + mapping_size >= i_size_read(inode)) {
+			/* limit mapping to block that spans EOF */
+			mapping_size = roundup_64(i_size_read(inode) - offset,
+						  1 << inode->i_blkbits);
+		}
 		if (mapping_size > LONG_MAX)
 			mapping_size = LONG_MAX;
 
@@ -1566,6 +1580,16 @@
 
 		xfs_vm_kill_delalloc_range(inode, block_offset,
 					   block_offset + bh->b_size);
+
+		/*
+		 * This buffer does not contain data anymore. make sure anyone
+		 * who finds it knows that for certain.
+		 */
+		clear_buffer_delay(bh);
+		clear_buffer_uptodate(bh);
+		clear_buffer_mapped(bh);
+		clear_buffer_new(bh);
+		clear_buffer_dirty(bh);
 	}
 
 }
@@ -1599,12 +1623,21 @@
 	status = __block_write_begin(page, pos, len, xfs_get_blocks);
 	if (unlikely(status)) {
 		struct inode	*inode = mapping->host;
+		size_t		isize = i_size_read(inode);
 
 		xfs_vm_write_failed(inode, page, pos, len);
 		unlock_page(page);
 
-		if (pos + len > i_size_read(inode))
-			truncate_pagecache(inode, i_size_read(inode));
+		/*
+		 * If the write is beyond EOF, we only want to kill blocks
+		 * allocated in this write, not blocks that were previously
+		 * written successfully.
+		 */
+		if (pos + len > isize) {
+			ssize_t start = max_t(ssize_t, pos, isize);
+
+			truncate_pagecache_range(inode, start, pos + len);
+		}
 
 		page_cache_release(page);
 		page = NULL;
@@ -1615,9 +1648,12 @@
 }
 
 /*
- * On failure, we only need to kill delalloc blocks beyond EOF because they
- * will never be written. For blocks within EOF, generic_write_end() zeros them
- * so they are safe to leave alone and be written with all the other valid data.
+ * On failure, we only need to kill delalloc blocks beyond EOF in the range of
+ * this specific write because they will never be written. Previous writes
+ * beyond EOF where block allocation succeeded do not need to be trashed, so
+ * only new blocks from this write should be trashed. For blocks within
+ * EOF, generic_write_end() zeros them so they are safe to leave alone and be
+ * written with all the other valid data.
  */
 STATIC int
 xfs_vm_write_end(
@@ -1640,8 +1676,11 @@
 		loff_t		to = pos + len;
 
 		if (to > isize) {
-			truncate_pagecache(inode, isize);
+			/* only kill blocks in this write beyond EOF */
+			if (pos > isize)
+				isize = pos;
 			xfs_vm_kill_delalloc_range(inode, isize, to);
+			truncate_pagecache_range(inode, isize, to);
 		}
 	}
 	return ret;
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 5b6092e..f0efc7e 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5413,6 +5413,7 @@
 	int				whichfork = XFS_DATA_FORK;
 	int				logflags;
 	xfs_filblks_t			blockcount = 0;
+	int				total_extents;
 
 	if (unlikely(XFS_TEST_ERROR(
 	    (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -5429,7 +5430,6 @@
 	ASSERT(current_ext != NULL);
 
 	ifp = XFS_IFORK_PTR(ip, whichfork);
-
 	if (!(ifp->if_flags & XFS_IFEXTENTS)) {
 		/* Read in all the extents */
 		error = xfs_iread_extents(tp, ip, whichfork);
@@ -5456,7 +5456,6 @@
 
 	/* We are going to change core inode */
 	logflags = XFS_ILOG_CORE;
-
 	if (ifp->if_flags & XFS_IFBROOT) {
 		cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
 		cur->bc_private.b.firstblock = *firstblock;
@@ -5467,8 +5466,14 @@
 		logflags |= XFS_ILOG_DEXT;
 	}
 
-	while (nexts++ < num_exts &&
-	       *current_ext <  XFS_IFORK_NEXTENTS(ip, whichfork)) {
+	/*
+	 * There may be delalloc extents in the data fork before the range we
+	 * are collapsing out, so we cannot
+	 * use the count of real extents here. Instead we have to calculate it
+	 * from the incore fork.
+	 */
+	total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
+	while (nexts++ < num_exts && *current_ext < total_extents) {
 
 		gotp = xfs_iext_get_ext(ifp, *current_ext);
 		xfs_bmbt_get_all(gotp, &got);
@@ -5556,10 +5561,11 @@
 		}
 
 		(*current_ext)++;
+		total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
 	}
 
 	/* Check if we are done */
-	if (*current_ext ==  XFS_IFORK_NEXTENTS(ip, whichfork))
+	if (*current_ext == total_extents)
 		*done = 1;
 
 del_cursor:
@@ -5568,6 +5574,5 @@
 			error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
 
 	xfs_trans_log_inode(tp, ip, logflags);
-
 	return error;
 }
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 01f6a64..296160b 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1418,6 +1418,8 @@
 	xfs_off_t		end_boundary;
 	int			error;
 
+	trace_xfs_zero_file_space(ip);
+
 	granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
 
 	/*
@@ -1432,9 +1434,18 @@
 	ASSERT(end_boundary <= offset + len);
 
 	if (start_boundary < end_boundary - 1) {
-		/* punch out the page cache over the conversion range */
+		/*
+		 * punch out delayed allocation blocks and the page cache over
+		 * the conversion range
+		 */
+		xfs_ilock(ip, XFS_ILOCK_EXCL);
+		error = xfs_bmap_punch_delalloc_range(ip,
+				XFS_B_TO_FSBT(mp, start_boundary),
+				XFS_B_TO_FSB(mp, end_boundary - start_boundary));
+		xfs_iunlock(ip, XFS_ILOCK_EXCL);
 		truncate_pagecache_range(VFS_I(ip), start_boundary,
 					 end_boundary - 1);
+
 		/* convert the blocks */
 		error = xfs_alloc_file_space(ip, start_boundary,
 					end_boundary - start_boundary - 1,
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 107f2fd..cb10a0a 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1372,21 +1372,29 @@
 		xfs_buf_wait_unpin(bp);
 	xfs_buf_hold(bp);
 
-	/* Set the count to 1 initially, this will stop an I/O
+	/*
+	 * Set the count to 1 initially, this will stop an I/O
 	 * completion callout which happens before we have started
 	 * all the I/O from calling xfs_buf_ioend too early.
 	 */
 	atomic_set(&bp->b_io_remaining, 1);
 	_xfs_buf_ioapply(bp);
-	_xfs_buf_ioend(bp, 1);
+	/*
+	 * If _xfs_buf_ioapply failed, we'll get back here with
+	 * only the reference we took above.  _xfs_buf_ioend will
+	 * drop it to zero, so we'd better not queue it for later,
+	 * or we'll free it before it's done.
+	 */
+	_xfs_buf_ioend(bp, bp->b_error ? 0 : 1);
 
 	xfs_buf_rele(bp);
 }
 
 /*
  * Waits for I/O to complete on the buffer supplied.  It returns immediately if
- * no I/O is pending or there is already a pending error on the buffer.  It
- * returns the I/O error code, if any, or 0 if there was no error.
+ * no I/O is pending or there is already a pending error on the buffer, in which
+ * case nothing will ever complete.  It returns the I/O error code, if any, or
+ * 0 if there was no error.
  */
 int
 xfs_buf_iowait(
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 79e96ce..82afdcb 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -679,7 +679,7 @@
 		goto out;
 
 	if (mapping->nrpages) {
-		ret = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
+		ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
 						    pos, -1);
 		if (ret)
 			goto out;
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 5e7a38f..768087b 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1334,7 +1334,8 @@
 xfs_create_tmpfile(
 	struct xfs_inode	*dp,
 	struct dentry		*dentry,
-	umode_t			mode)
+	umode_t			mode,
+	struct xfs_inode	**ipp)
 {
 	struct xfs_mount	*mp = dp->i_mount;
 	struct xfs_inode	*ip = NULL;
@@ -1402,7 +1403,6 @@
 	xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
 
 	ip->i_d.di_nlink--;
-	d_tmpfile(dentry, VFS_I(ip));
 	error = xfs_iunlink(tp, ip);
 	if (error)
 		goto out_trans_abort;
@@ -1415,6 +1415,7 @@
 	xfs_qm_dqrele(gdqp);
 	xfs_qm_dqrele(pdqp);
 
+	*ipp = ip;
 	return 0;
 
  out_trans_abort:
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 396cc1f..f2fcde5 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -334,7 +334,7 @@
 int		xfs_create(struct xfs_inode *dp, struct xfs_name *name,
 			   umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp);
 int		xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry,
-			   umode_t mode);
+			   umode_t mode, struct xfs_inode **ipp);
 int		xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
 			   struct xfs_inode *ip);
 int		xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 89b07e4..ef1ca01 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1053,11 +1053,25 @@
 	struct dentry	*dentry,
 	umode_t		mode)
 {
-	int		error;
+	int			error;
+	struct xfs_inode	*ip;
+	struct inode		*inode;
 
-	error = xfs_create_tmpfile(XFS_I(dir), dentry, mode);
+	error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
+	if (unlikely(error))
+		return -error;
 
-	return -error;
+	inode = VFS_I(ip);
+
+	error = xfs_init_security(inode, dir, &dentry->d_name);
+	if (unlikely(error)) {
+		iput(inode);
+		return -error;
+	}
+
+	d_tmpfile(dentry, inode);
+
+	return 0;
 }
 
 static const struct inode_operations xfs_inode_operations = {
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 8497a00..08624dc 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1181,11 +1181,14 @@
 	/* log I/O is always issued ASYNC */
 	ASSERT(XFS_BUF_ISASYNC(bp));
 	xlog_state_done_syncing(iclog, aborted);
+
 	/*
-	 * do not reference the buffer (bp) here as we could race
-	 * with it being freed after writing the unmount record to the
-	 * log.
+	 * drop the buffer lock now that we are done. Nothing references
+	 * the buffer after this, so an unmount waiting on this lock can now
+	 * tear it down safely. As such, it is unsafe to reference the buffer
+	 * (bp) after the unlock as we could race with it being freed.
 	 */
+	xfs_buf_unlock(bp);
 }
 
 /*
@@ -1368,8 +1371,16 @@
 	bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0);
 	if (!bp)
 		goto out_free_log;
-	bp->b_iodone = xlog_iodone;
+
+	/*
+	 * The iclogbuf buffer locks are held over IO but we are not going to do
+	 * IO yet.  Hence unlock the buffer so that the log IO path can grab it
+	 * when appropriately.
+	 */
 	ASSERT(xfs_buf_islocked(bp));
+	xfs_buf_unlock(bp);
+
+	bp->b_iodone = xlog_iodone;
 	log->l_xbuf = bp;
 
 	spin_lock_init(&log->l_icloglock);
@@ -1398,6 +1409,9 @@
 		if (!bp)
 			goto out_free_iclog;
 
+		ASSERT(xfs_buf_islocked(bp));
+		xfs_buf_unlock(bp);
+
 		bp->b_iodone = xlog_iodone;
 		iclog->ic_bp = bp;
 		iclog->ic_data = bp->b_addr;
@@ -1422,7 +1436,6 @@
 		iclog->ic_callback_tail = &(iclog->ic_callback);
 		iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize;
 
-		ASSERT(xfs_buf_islocked(iclog->ic_bp));
 		init_waitqueue_head(&iclog->ic_force_wait);
 		init_waitqueue_head(&iclog->ic_write_wait);
 
@@ -1631,6 +1644,12 @@
  * we transition the iclogs to IOERROR state *after* flushing all existing
  * iclogs to disk. This is because we don't want anymore new transactions to be
  * started or completed afterwards.
+ *
+ * We lock the iclogbufs here so that we can serialise against IO completion
+ * during unmount. We might be processing a shutdown triggered during unmount,
+ * and that can occur asynchronously to the unmount thread, and hence we need to
+ * ensure that completes before tearing down the iclogbufs. Hence we need to
+ * hold the buffer lock across the log IO to acheive that.
  */
 STATIC int
 xlog_bdstrat(
@@ -1638,6 +1657,7 @@
 {
 	struct xlog_in_core	*iclog = bp->b_fspriv;
 
+	xfs_buf_lock(bp);
 	if (iclog->ic_state & XLOG_STATE_IOERROR) {
 		xfs_buf_ioerror(bp, EIO);
 		xfs_buf_stale(bp);
@@ -1645,7 +1665,8 @@
 		/*
 		 * It would seem logical to return EIO here, but we rely on
 		 * the log state machine to propagate I/O errors instead of
-		 * doing it here.
+		 * doing it here. Similarly, IO completion will unlock the
+		 * buffer, so we don't do it here.
 		 */
 		return 0;
 	}
@@ -1847,14 +1868,28 @@
 	xlog_cil_destroy(log);
 
 	/*
-	 * always need to ensure that the extra buffer does not point to memory
-	 * owned by another log buffer before we free it.
+	 * Cycle all the iclogbuf locks to make sure all log IO completion
+	 * is done before we tear down these buffers.
 	 */
+	iclog = log->l_iclog;
+	for (i = 0; i < log->l_iclog_bufs; i++) {
+		xfs_buf_lock(iclog->ic_bp);
+		xfs_buf_unlock(iclog->ic_bp);
+		iclog = iclog->ic_next;
+	}
+
+	/*
+	 * Always need to ensure that the extra buffer does not point to memory
+	 * owned by another log buffer before we free it. Also, cycle the lock
+	 * first to ensure we've completed IO on it.
+	 */
+	xfs_buf_lock(log->l_xbuf);
+	xfs_buf_unlock(log->l_xbuf);
 	xfs_buf_set_empty(log->l_xbuf, BTOBB(log->l_iclog_size));
 	xfs_buf_free(log->l_xbuf);
 
 	iclog = log->l_iclog;
-	for (i=0; i<log->l_iclog_bufs; i++) {
+	for (i = 0; i < log->l_iclog_bufs; i++) {
 		xfs_buf_free(iclog->ic_bp);
 		next_iclog = iclog->ic_next;
 		kmem_free(iclog);
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a4ae41c..65d8c79 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -603,6 +603,7 @@
 DEFINE_INODE_EVENT(xfs_inactive_symlink);
 DEFINE_INODE_EVENT(xfs_alloc_file_space);
 DEFINE_INODE_EVENT(xfs_free_file_space);
+DEFINE_INODE_EVENT(xfs_zero_file_space);
 DEFINE_INODE_EVENT(xfs_collapse_file_space);
 DEFINE_INODE_EVENT(xfs_readdir);
 #ifdef CONFIG_XFS_POSIX_ACL
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 1ec08c1..a8015a7 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -693,24 +693,35 @@
 #ifndef pte_mknonnuma
 static inline pte_t pte_mknonnuma(pte_t pte)
 {
-	pte = pte_clear_flags(pte, _PAGE_NUMA);
-	return pte_set_flags(pte, _PAGE_PRESENT|_PAGE_ACCESSED);
+	pteval_t val = pte_val(pte);
+
+	val &= ~_PAGE_NUMA;
+	val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+	return __pte(val);
 }
 #endif
 
 #ifndef pmd_mknonnuma
 static inline pmd_t pmd_mknonnuma(pmd_t pmd)
 {
-	pmd = pmd_clear_flags(pmd, _PAGE_NUMA);
-	return pmd_set_flags(pmd, _PAGE_PRESENT|_PAGE_ACCESSED);
+	pmdval_t val = pmd_val(pmd);
+
+	val &= ~_PAGE_NUMA;
+	val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+
+	return __pmd(val);
 }
 #endif
 
 #ifndef pte_mknuma
 static inline pte_t pte_mknuma(pte_t pte)
 {
-	pte = pte_set_flags(pte, _PAGE_NUMA);
-	return pte_clear_flags(pte, _PAGE_PRESENT);
+	pteval_t val = pte_val(pte);
+
+	val &= ~_PAGE_PRESENT;
+	val |= _PAGE_NUMA;
+
+	return __pte(val);
 }
 #endif
 
@@ -729,8 +740,12 @@
 #ifndef pmd_mknuma
 static inline pmd_t pmd_mknuma(pmd_t pmd)
 {
-	pmd = pmd_set_flags(pmd, _PAGE_NUMA);
-	return pmd_clear_flags(pmd, _PAGE_PRESENT);
+	pmdval_t val = pmd_val(pmd);
+
+	val &= ~_PAGE_PRESENT;
+	val |= _PAGE_NUMA;
+
+	return __pmd(val);
 }
 #endif
 
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 0bb34ca..36a5feb 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -125,7 +125,6 @@
 	struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
 };
 
-extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
 extern void drm_helper_disable_unused_functions(struct drm_device *dev);
 extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
 extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
@@ -161,6 +160,11 @@
 }
 
 extern void drm_helper_resume_force_mode(struct drm_device *dev);
+
+/* drm_probe_helper.c */
+extern int drm_helper_probe_single_connector_modes(struct drm_connector
+						   *connector, uint32_t maxX,
+						   uint32_t maxY);
 extern void drm_kms_helper_poll_init(struct drm_device *dev);
 extern void drm_kms_helper_poll_fini(struct drm_device *dev);
 extern bool drm_helper_hpd_irq_event(struct drm_device *dev);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index b4f5891..cfcacec 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -456,6 +456,10 @@
  * transactions. The drm_dp_aux_register_i2c_bus() function registers an
  * I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers
  * should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter.
+ *
+ * Note that the aux helper code assumes that the .transfer() function
+ * only modifies the reply field of the drm_dp_aux_msg structure.  The
+ * retry logic and i2c helpers assume this is the case.
  */
 struct drm_dp_aux {
 	const char *name;
diff --git a/include/linux/device.h b/include/linux/device.h
index 233bbbe..d1d1c05 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -566,12 +566,6 @@
 					const struct bin_attribute *attr);
 extern void device_remove_bin_file(struct device *dev,
 				   const struct bin_attribute *attr);
-extern int device_schedule_callback_owner(struct device *dev,
-		void (*func)(struct device *dev), struct module *owner);
-
-/* This is a macro to avoid include problems with THIS_MODULE */
-#define device_schedule_callback(dev, func)			\
-	device_schedule_callback_owner(dev, func, THIS_MODULE)
 
 /* device resource management */
 typedef void (*dr_release_t)(struct device *dev, void *res);
@@ -932,10 +926,7 @@
 extern struct device *__root_device_register(const char *name,
 					     struct module *owner);
 
-/*
- * This is a macro to avoid include problems with THIS_MODULE,
- * just as per what is done for device_schedule_callback() above.
- */
+/* This is a macro to avoid include problems with THIS_MODULE */
 #define root_device_register(name) \
 	__root_device_register(name, THIS_MODULE)
 
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 0a114d0..212f537 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -154,13 +154,23 @@
  * @reset: Reset (part of) the device, as specified by a bitmask of
  *	flags from &enum ethtool_reset_flags.  Returns a negative
  *	error code or zero.
+ * @get_rxfh_key_size: Get the size of the RX flow hash key.
+ *	Returns zero if not supported for this specific device.
  * @get_rxfh_indir_size: Get the size of the RX flow hash indirection table.
  *	Returns zero if not supported for this specific device.
  * @get_rxfh_indir: Get the contents of the RX flow hash indirection table.
  *	Will not be called if @get_rxfh_indir_size returns zero.
+ * @get_rxfh: Get the contents of the RX flow hash indirection table and hash
+ *	key.
+ *	Will not be called if @get_rxfh_indir_size and @get_rxfh_key_size
+ *	returns zero.
  *	Returns a negative error code or zero.
  * @set_rxfh_indir: Set the contents of the RX flow hash indirection table.
  *	Will not be called if @get_rxfh_indir_size returns zero.
+ * @set_rxfh: Set the contents of the RX flow hash indirection table and
+ *	hash key.
+ *	Will not be called if @get_rxfh_indir_size and @get_rxfh_key_size
+ *	returns zero.
  *	Returns a negative error code or zero.
  * @get_channels: Get number of channels.
  * @set_channels: Set number of channels.  Returns a negative error code or
@@ -232,7 +242,10 @@
 	int	(*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
 	int	(*flash_device)(struct net_device *, struct ethtool_flash *);
 	int	(*reset)(struct net_device *, u32 *);
+	u32	(*get_rxfh_key_size)(struct net_device *);
 	u32	(*get_rxfh_indir_size)(struct net_device *);
+	int	(*get_rxfh)(struct net_device *, u32 *, u8 *);
+	int	(*set_rxfh)(struct net_device *, u32 *, u8 *);
 	int	(*get_rxfh_indir)(struct net_device *, u32 *);
 	int	(*set_rxfh_indir)(struct net_device *, const u32 *);
 	void	(*get_channels)(struct net_device *, struct ethtool_channels *);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 024fd03..759abf7 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -223,6 +223,7 @@
 	BPF_S_ANC_VLAN_TAG,
 	BPF_S_ANC_VLAN_TAG_PRESENT,
 	BPF_S_ANC_PAY_OFFSET,
+	BPF_S_ANC_RANDOM,
 };
 
 #endif /* __LINUX_FILTER_H__ */
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ab7359f..2d7b4f1 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -147,15 +147,17 @@
  * 0 . 13 (Windows Server 2008)
  * 1 . 1  (Windows 7)
  * 2 . 4  (Windows 8)
+ * 3 . 0  (Windows 8 R2)
  */
 
 #define VERSION_WS2008  ((0 << 16) | (13))
 #define VERSION_WIN7    ((1 << 16) | (1))
 #define VERSION_WIN8    ((2 << 16) | (4))
+#define VERSION_WIN8_1    ((3 << 16) | (0))
 
 #define VERSION_INVAL -1
 
-#define VERSION_CURRENT VERSION_WIN8
+#define VERSION_CURRENT VERSION_WIN8_1
 
 /* Make maximum size of pipe payload of 16K */
 #define MAX_PIPE_DATA_PAYLOAD		(sizeof(u8) * 16384)
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 1f9f56e..76d2acb 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -237,7 +237,7 @@
  * The first user that sets this to TRUE will receive all events that
  * have been queued while no one was waiting for events.
  */
-int ipmi_set_gets_events(ipmi_user_t user, int val);
+int ipmi_set_gets_events(ipmi_user_t user, bool val);
 
 /*
  * Called when a new SMI is registered.  This will also be called on
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index 8ea3fe0..bd34924 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -109,12 +109,19 @@
 	   events from the BMC we are attached to. */
 	void (*request_events)(void *send_info);
 
+	/* Called by the upper layer when some user requires that the
+	   interface watch for events, received messages, watchdog
+	   pretimeouts, or not.  Used by the SMI to know if it should
+	   watch for these.  This may be NULL if the SMI does not
+	   implement it. */
+	void (*set_need_watch)(void *send_info, bool enable);
+
 	/* Called when the interface should go into "run to
 	   completion" mode.  If this call sets the value to true, the
 	   interface should make sure that all messages are flushed
 	   out and that none are pending, and any new requests are run
 	   to completion immediately. */
-	void (*set_run_to_completion)(void *send_info, int run_to_completion);
+	void (*set_run_to_completion)(void *send_info, bool run_to_completion);
 
 	/* Called to poll for work to do.  This is so upper layers can
 	   poll for operations during things like crash dumps. */
@@ -125,7 +132,7 @@
 	   setting.  The message handler does the mode handling.  Note
 	   that this is called from interrupt context, so it cannot
 	   block. */
-	void (*set_maintenance_mode)(void *send_info, int enable);
+	void (*set_maintenance_mode)(void *send_info, bool enable);
 
 	/* Tell the handler that we are using it/not using it.  The
 	   message handler get the modules that this handler belongs
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 407bdb6..3406cfb 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -179,6 +179,7 @@
 	MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR	= 1LL <<  9,
 	MLX5_DEV_CAP_FLAG_APM		= 1LL << 17,
 	MLX5_DEV_CAP_FLAG_ATOMIC	= 1LL << 18,
+	MLX5_DEV_CAP_FLAG_BLOCK_MCAST	= 1LL << 23,
 	MLX5_DEV_CAP_FLAG_ON_DMND_PG	= 1LL << 24,
 	MLX5_DEV_CAP_FLAG_CQ_MODER	= 1LL << 29,
 	MLX5_DEV_CAP_FLAG_RESIZE_CQ	= 1LL << 30,
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index f829ad8..9709b30 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -146,6 +146,7 @@
 
 enum {
 	MLX5_QP_LAT_SENSITIVE	= 1 << 28,
+	MLX5_QP_BLOCK_MCAST	= 1 << 30,
 	MLX5_QP_ENABLE_SIG	= 1 << 31,
 };
 
diff --git a/include/linux/mtd/spear_smi.h b/include/linux/mtd/spear_smi.h
index 8ae1726..581603a 100644
--- a/include/linux/mtd/spear_smi.h
+++ b/include/linux/mtd/spear_smi.h
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2010 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7ed3a3a..a803d79 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2633,6 +2633,7 @@
 			 struct netdev_phys_port_id *ppid);
 int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 			struct netdev_queue *txq);
+int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 bool is_skb_forwardable(struct net_device *dev, struct sk_buff *skb);
 
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index aad8eea..5146ce0 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -45,7 +45,8 @@
 	unsigned int	flags;
 	void		(*input)(struct sk_buff *skb);
 	struct mutex	*cb_mutex;
-	void		(*bind)(int group);
+	int		(*bind)(int group);
+	void		(*unbind)(int group);
 	bool		(*compare)(struct net *net, struct sock *sk);
 };
 
diff --git a/include/linux/of.h b/include/linux/of.h
index 919bf21..3bad8d1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -374,6 +374,11 @@
 	return NULL;
 }
 
+static inline struct device_node *of_find_node_by_path(const char *path)
+{
+	return NULL;
+}
+
 static inline struct device_node *of_get_parent(const struct device_node *node)
 {
 	return NULL;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 4d0221f..51d15f6 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -666,6 +666,7 @@
 	return phydev->drv->read_status(phydev);
 }
 
+int genphy_config_init(struct phy_device *phydev);
 int genphy_setup_forced(struct phy_device *phydev);
 int genphy_restart_aneg(struct phy_device *phydev);
 int genphy_config_aneg(struct phy_device *phydev);
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 9e7db9e..48bf152 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -20,13 +20,13 @@
 extern enum reboot_mode reboot_mode;
 
 enum reboot_type {
-	BOOT_TRIPLE = 't',
-	BOOT_KBD = 'k',
-	BOOT_BIOS = 'b',
-	BOOT_ACPI = 'a',
-	BOOT_EFI = 'e',
-	BOOT_CF9 = 'p',
-	BOOT_CF9_COND = 'q',
+	BOOT_TRIPLE	= 't',
+	BOOT_KBD	= 'k',
+	BOOT_BIOS	= 'b',
+	BOOT_ACPI	= 'a',
+	BOOT_EFI	= 'e',
+	BOOT_CF9_FORCE	= 'p',
+	BOOT_CF9_SAFE	= 'q',
 };
 extern enum reboot_type reboot_type;
 
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index 54f91d3..302ab80 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -23,7 +23,7 @@
 void sock_diag_save_cookie(void *sk, __u32 *cookie);
 
 int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
-int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
+int sock_diag_put_filterinfo(struct sock *sk,
 			     struct sk_buff *skb, int attrtype);
 
 #endif
diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h
index aa327a8..b2b1afb 100644
--- a/include/linux/spi/at86rf230.h
+++ b/include/linux/spi/at86rf230.h
@@ -26,20 +26,6 @@
 	int rstn;
 	int slp_tr;
 	int dig2;
-
-	/* Setting the irq_type will configure the driver to request
-	 * the platform irq trigger type according to the given value
-	 * and configure the interrupt polarity of the device to the
-	 * corresponding polarity.
-	 *
-	 * Allowed values are: IRQF_TRIGGER_RISING, IRQF_TRIGGER_FALLING,
-	 *                     IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW
-	 *
-	 * Setting it to 0, the driver does not touch the trigger type
-	 * configuration of the interrupt and sets the interrupt polarity
-	 * of the device to high active (the default value).
-	 */
-	int irq_type;
 };
 
 #endif
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 084354b..5ffaa34 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -179,9 +179,6 @@
 
 #ifdef CONFIG_SYSFS
 
-int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
-			    void *data, struct module *owner);
-
 int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
 void sysfs_remove_dir(struct kobject *kobj);
 int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
@@ -255,12 +252,6 @@
 
 #else /* CONFIG_SYSFS */
 
-static inline int sysfs_schedule_callback(struct kobject *kobj,
-		void (*func)(void *), void *data, struct module *owner)
-{
-	return -ENOSYS;
-}
-
 static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
 {
 	return 0;
diff --git a/include/linux/wait.h b/include/linux/wait.h
index e7d9d9e..bd68819 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -191,11 +191,23 @@
 	(!__builtin_constant_p(state) ||				\
 		state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE)	\
 
+/*
+ * The below macro ___wait_event() has an explicit shadow of the __ret
+ * variable when used from the wait_event_*() macros.
+ *
+ * This is so that both can use the ___wait_cond_timeout() construct
+ * to wrap the condition.
+ *
+ * The type inconsistency of the wait_event_*() __ret variable is also
+ * on purpose; we use long where we can return timeout values and int
+ * otherwise.
+ */
+
 #define ___wait_event(wq, condition, state, exclusive, ret, cmd)	\
 ({									\
 	__label__ __out;						\
 	wait_queue_t __wait;						\
-	long __ret = ret;						\
+	long __ret = ret;	/* explicit shadow */			\
 									\
 	INIT_LIST_HEAD(&__wait.task_list);				\
 	if (exclusive)							\
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index f7d372b..79b530f 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -54,6 +54,7 @@
 #define __6LOWPAN_H__
 
 #include <net/ipv6.h>
+#include <net/net_namespace.h>
 
 #define UIP_802154_SHORTADDR_LEN	2  /* compressed ipv6 address length */
 #define UIP_IPH_LEN			40 /* ipv6 fixed header size */
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 933a9f2..f679877 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -306,11 +306,6 @@
 		      htonl(0xFF000000) | addr->s6_addr32[3]);
 }
 
-static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
-{
-	return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
-}
-
 static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
 {
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 7828ebf..6efce38 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -181,6 +181,11 @@
 void register_switch_driver(struct dsa_switch_driver *type);
 void unregister_switch_driver(struct dsa_switch_driver *type);
 
+static inline void *ds_to_priv(struct dsa_switch *ds)
+{
+	return (void *)(ds + 1);
+}
+
 /*
  * The original DSA tag format and some other tag formats have no
  * ethertype, which means that we need to add a little hack to the
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index d640925..5b40ad2 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -583,6 +583,11 @@
 	return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010);
 }
 
+static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
+{
+	return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
+}
+
 static inline void ipv6_addr_set_v4mapped(const __be32 addr,
 					  struct in6_addr *v4mapped)
 {
@@ -664,6 +669,20 @@
 
 int ip6_dst_hoplimit(struct dst_entry *dst);
 
+static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
+				      struct dst_entry *dst)
+{
+	int hlimit;
+
+	if (ipv6_addr_is_multicast(&fl6->daddr))
+		hlimit = np->mcast_hops;
+	else
+		hlimit = np->hop_limit;
+	if (hlimit < 0)
+		hlimit = ip6_dst_hoplimit(dst);
+	return hlimit;
+}
+
 /*
  *	Header manipulation
  */
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 5f9eb26..361d260 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -373,6 +373,14 @@
 }
 #endif
 
+#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN)
+static inline struct netns_ieee802154_lowpan *
+net_ieee802154_lowpan(struct net *net)
+{
+	return &net->ieee802154_lowpan;
+}
+#endif
+
 /* For callers who don't really care about whether it's IPv4 or IPv6 */
 static inline void rt_genid_bump_all(struct net *net)
 {
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index a2441fb..6da46dc 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -136,7 +136,7 @@
 
 int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
 		      struct nlattr **tb, struct nlattr *rate_tlv,
-		      struct tcf_exts *exts);
+		      struct tcf_exts *exts, bool ovr);
 void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
 void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
 		     struct tcf_exts *src);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index d062f81..624f985 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -199,7 +199,7 @@
 	int			(*change)(struct net *net, struct sk_buff *,
 					struct tcf_proto*, unsigned long,
 					u32 handle, struct nlattr **,
-					unsigned long *);
+					unsigned long *, bool);
 	int			(*delete)(struct tcf_proto*, unsigned long);
 	void			(*walk)(struct tcf_proto*, struct tcf_walker *arg);
 
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index d992ca3..0dfcc92 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1241,6 +1241,7 @@
 	/* SCTP-AUTH: endpoint shared keys */
 	struct list_head endpoint_shared_keys;
 	__u16 active_key_id;
+	__u8  auth_enable;
 };
 
 /* Recover the outter endpoint structure. */
@@ -1269,7 +1270,8 @@
 int sctp_has_association(struct net *net, const union sctp_addr *laddr,
 			 const union sctp_addr *paddr);
 
-int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
+int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
+		     const struct sctp_association *asoc,
 		     sctp_cid_t, sctp_init_chunk_t *peer_init,
 		     struct sctp_chunk *chunk, struct sctp_chunk **err_chunk);
 int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 87d8774..163d2b4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -558,7 +558,6 @@
 bool tcp_schedule_loss_probe(struct sock *sk);
 
 /* tcp_input.c */
-void tcp_cwnd_application_limited(struct sock *sk);
 void tcp_resume_early_retransmit(struct sock *sk);
 void tcp_rearm_rto(struct sock *sk);
 void tcp_reset(struct sock *sk);
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 5deef1a..7bb4084 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -33,7 +33,7 @@
 int vxlan_xmit_skb(struct vxlan_sock *vs,
 		   struct rtable *rt, struct sk_buff *skb,
 		   __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
-		   __be16 src_port, __be16 dst_port, __be32 vni);
+		   __be16 src_port, __be16 dst_port, __be32 vni, bool xnet);
 
 __be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb);
 
diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h
index b042b48..b754821 100644
--- a/include/uapi/drm/tegra_drm.h
+++ b/include/uapi/drm/tegra_drm.h
@@ -120,7 +120,6 @@
 	__u32 num_waitchks;
 	__u32 waitchk_mask;
 	__u32 timeout;
-	__u32 pad;
 	__u64 syncpts;
 	__u64 cmdbufs;
 	__u64 relocs;
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 11917f7..dfa4c86 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -373,6 +373,14 @@
  */
 #define AUDIT_MESSAGE_TEXT_MAX	8560
 
+/* Multicast Netlink socket groups (default up to 32) */
+enum audit_nlgrps {
+	AUDIT_NLGRP_NONE,	/* Group 0 not used */
+	AUDIT_NLGRP_READLOG,	/* "best effort" read only socket */
+	__AUDIT_NLGRP_MAX
+};
+#define AUDIT_NLGRP_MAX                (__AUDIT_NLGRP_MAX - 1)
+
 struct audit_status {
 	__u32		mask;		/* Bit mask for valid entries */
 	__u32		enabled;	/* 1 = enabled, 0 = disabled */
diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
index 154dd6d..12c37a1 100644
--- a/include/uapi/linux/capability.h
+++ b/include/uapi/linux/capability.h
@@ -347,7 +347,12 @@
 
 #define CAP_BLOCK_SUSPEND    36
 
-#define CAP_LAST_CAP         CAP_BLOCK_SUSPEND
+/* Allow reading the audit log via multicast netlink socket */
+
+#define CAP_AUDIT_READ		37
+
+
+#define CAP_LAST_CAP         CAP_AUDIT_READ
 
 #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
 
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index fd161e9..d47d31d 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -847,6 +847,35 @@
 };
 
 /**
+ * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key.
+ * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH
+ * @rss_context: RSS context identifier.
+ * @indir_size: On entry, the array size of the user buffer, which may be zero.
+ *		On return from %ETHTOOL_GRSSH, the array size of the hardware
+ *		indirection table.
+ * @key_size:	On entry, the array size of the user buffer in bytes,
+ *		which may be zero.
+ *		On return from %ETHTOOL_GRSSH, the size of the RSS hash key.
+ * @rsvd:	Reserved for future extensions.
+ * @rss_config: RX ring/queue index for each hash value i.e., indirection table
+ *		of size @indir_size followed by hash key of size @key_size.
+ *
+ * For %ETHTOOL_GRSSH, a @indir_size and key_size of zero means that only the
+ * size should be returned.  For %ETHTOOL_SRSSH, a @indir_size of 0xDEADBEEF
+ * means that indir table setting is not requested and a @indir_size of zero
+ * means the indir table should be reset to default values.  This last feature
+ * is not supported by the original implementations.
+ */
+struct ethtool_rxfh {
+	__u32   cmd;
+	__u32	rss_context;
+	__u32   indir_size;
+	__u32   key_size;
+	__u32	rsvd[2];
+	__u32   rss_config[0];
+};
+
+/**
  * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
  * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
  * @h_u: Flow field values to match (dependent on @flow_type)
@@ -1118,6 +1147,9 @@
 #define ETHTOOL_GEEE		0x00000044 /* Get EEE settings */
 #define ETHTOOL_SEEE		0x00000045 /* Set EEE settings */
 
+#define ETHTOOL_GRSSH		0x00000046 /* Get RX flow hash configuration */
+#define ETHTOOL_SRSSH		0x00000047 /* Set RX flow hash configuration */
+
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
 #define SPARC_ETH_SSET		ETHTOOL_SSET
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 8eb9cca..253b4d4 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -130,7 +130,8 @@
 #define SKF_AD_VLAN_TAG	44
 #define SKF_AD_VLAN_TAG_PRESENT 48
 #define SKF_AD_PAY_OFFSET	52
-#define SKF_AD_MAX	56
+#define SKF_AD_RANDOM	56
+#define SKF_AD_MAX	60
 #define SKF_NET_OFF   (-0x100000)
 #define SKF_LL_OFF    (-0x200000)
 
diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h
index 9beb7c9..78e4a86 100644
--- a/include/uapi/linux/hyperv.h
+++ b/include/uapi/linux/hyperv.h
@@ -305,6 +305,7 @@
 #define HV_ERROR_DEVICE_NOT_CONNECTED	0x8007048F
 #define HV_INVALIDARG			0x80070057
 #define HV_GUID_NOTFOUND		0x80041002
+#define HV_ERROR_ALREADY_EXISTS		0x80070050
 
 #define ADDR_FAMILY_NONE	0x00
 #define ADDR_FAMILY_IPV4	0x01
diff --git a/include/uapi/linux/if_fddi.h b/include/uapi/linux/if_fddi.h
index 0d36909..1086cd9 100644
--- a/include/uapi/linux/if_fddi.h
+++ b/include/uapi/linux/if_fddi.h
@@ -30,74 +30,76 @@
  *  Define max and min legal sizes.  The frame sizes do not include
  *  4 byte FCS/CRC (frame check sequence).
  */
-#define FDDI_K_ALEN			6		/* Octets in one FDDI address */
-#define FDDI_K_8022_HLEN	16		/* Total octets in 802.2 header */
-#define FDDI_K_SNAP_HLEN	21		/* Total octets in 802.2 SNAP header */
-#define FDDI_K_8022_ZLEN	16		/* Min octets in 802.2 frame sans FCS */
-#define FDDI_K_SNAP_ZLEN	21		/* Min octets in 802.2 SNAP frame sans FCS */
+#define FDDI_K_ALEN		6	/* Octets in one FDDI address */
+#define FDDI_K_8022_HLEN	16	/* Total octets in 802.2 header */
+#define FDDI_K_SNAP_HLEN	21	/* Total octets in 802.2 SNAP header */
+#define FDDI_K_8022_ZLEN	16	/* Min octets in 802.2 frame sans
+					   FCS */
+#define FDDI_K_SNAP_ZLEN	21	/* Min octets in 802.2 SNAP frame sans
+					   FCS */
 #define FDDI_K_8022_DLEN	4475	/* Max octets in 802.2 payload */
 #define FDDI_K_SNAP_DLEN	4470	/* Max octets in 802.2 SNAP payload */
-#define FDDI_K_LLC_ZLEN		13		/* Min octets in LLC frame sans FCS */
+#define FDDI_K_LLC_ZLEN		13	/* Min octets in LLC frame sans FCS */
 #define FDDI_K_LLC_LEN		4491	/* Max octets in LLC frame sans FCS */
+#define FDDI_K_OUI_LEN		3	/* Octets in OUI in 802.2 SNAP
+					   header */
 
 /* Define FDDI Frame Control (FC) Byte values */
-#define FDDI_FC_K_VOID					0x00	
-#define FDDI_FC_K_NON_RESTRICTED_TOKEN	0x80	
-#define FDDI_FC_K_RESTRICTED_TOKEN		0xC0	
-#define FDDI_FC_K_SMT_MIN				0x41
-#define FDDI_FC_K_SMT_MAX		   		0x4F
-#define FDDI_FC_K_MAC_MIN				0xC1
-#define FDDI_FC_K_MAC_MAX		  		0xCF	
-#define FDDI_FC_K_ASYNC_LLC_MIN			0x50
-#define FDDI_FC_K_ASYNC_LLC_DEF			0x54
-#define FDDI_FC_K_ASYNC_LLC_MAX			0x5F
-#define FDDI_FC_K_SYNC_LLC_MIN			0xD0
-#define FDDI_FC_K_SYNC_LLC_MAX			0xD7
-#define FDDI_FC_K_IMPLEMENTOR_MIN		0x60
-#define FDDI_FC_K_IMPLEMENTOR_MAX  		0x6F
-#define FDDI_FC_K_RESERVED_MIN			0x70
-#define FDDI_FC_K_RESERVED_MAX			0x7F
+#define FDDI_FC_K_VOID			0x00
+#define FDDI_FC_K_NON_RESTRICTED_TOKEN	0x80
+#define FDDI_FC_K_RESTRICTED_TOKEN	0xC0
+#define FDDI_FC_K_SMT_MIN		0x41
+#define FDDI_FC_K_SMT_MAX		0x4F
+#define FDDI_FC_K_MAC_MIN		0xC1
+#define FDDI_FC_K_MAC_MAX		0xCF
+#define FDDI_FC_K_ASYNC_LLC_MIN		0x50
+#define FDDI_FC_K_ASYNC_LLC_DEF		0x54
+#define FDDI_FC_K_ASYNC_LLC_MAX		0x5F
+#define FDDI_FC_K_SYNC_LLC_MIN		0xD0
+#define FDDI_FC_K_SYNC_LLC_MAX		0xD7
+#define FDDI_FC_K_IMPLEMENTOR_MIN	0x60
+#define FDDI_FC_K_IMPLEMENTOR_MAX	0x6F
+#define FDDI_FC_K_RESERVED_MIN		0x70
+#define FDDI_FC_K_RESERVED_MAX		0x7F
 
 /* Define LLC and SNAP constants */
-#define FDDI_EXTENDED_SAP	0xAA
+#define FDDI_EXTENDED_SAP		0xAA
 #define FDDI_UI_CMD			0x03
 
 /* Define 802.2 Type 1 header */
 struct fddi_8022_1_hdr {
-	__u8	dsap;					/* destination service access point */
-	__u8	ssap;					/* source service access point */
-	__u8	ctrl;					/* control byte #1 */
+	__u8	dsap;			/* destination service access point */
+	__u8	ssap;			/* source service access point */
+	__u8	ctrl;			/* control byte #1 */
 } __attribute__((packed));
 
 /* Define 802.2 Type 2 header */
 struct fddi_8022_2_hdr {
-	__u8	dsap;					/* destination service access point */
-	__u8	ssap;					/* source service access point */
-	__u8	ctrl_1;					/* control byte #1 */
-	__u8	ctrl_2;					/* control byte #2 */
+	__u8	dsap;			/* destination service access point */
+	__u8	ssap;			/* source service access point */
+	__u8	ctrl_1;			/* control byte #1 */
+	__u8	ctrl_2;			/* control byte #2 */
 } __attribute__((packed));
 
 /* Define 802.2 SNAP header */
-#define FDDI_K_OUI_LEN	3
 struct fddi_snap_hdr {
-	__u8	dsap;					/* always 0xAA */
-	__u8	ssap;					/* always 0xAA */
-	__u8	ctrl;					/* always 0x03 */
+	__u8	dsap;			/* always 0xAA */
+	__u8	ssap;			/* always 0xAA */
+	__u8	ctrl;			/* always 0x03 */
 	__u8	oui[FDDI_K_OUI_LEN];	/* organizational universal id */
-	__be16	ethertype;				/* packet type ID field */
+	__be16	ethertype;		/* packet type ID field */
 } __attribute__((packed));
 
 /* Define FDDI LLC frame header */
 struct fddihdr {
-	__u8	fc;						/* frame control */
-	__u8	daddr[FDDI_K_ALEN];		/* destination address */
-	__u8	saddr[FDDI_K_ALEN];		/* source address */
-	union
-		{
-		struct fddi_8022_1_hdr		llc_8022_1;
-		struct fddi_8022_2_hdr		llc_8022_2;
-		struct fddi_snap_hdr		llc_snap;
-		} hdr;
+	__u8	fc;			/* frame control */
+	__u8	daddr[FDDI_K_ALEN];	/* destination address */
+	__u8	saddr[FDDI_K_ALEN];	/* source address */
+	union {
+		struct fddi_8022_1_hdr	llc_8022_1;
+		struct fddi_8022_2_hdr	llc_8022_2;
+		struct fddi_snap_hdr	llc_snap;
+	} hdr;
 } __attribute__((packed));
 
 
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 852373d..6f71b9b 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -38,6 +38,7 @@
 #define _LINUX_TIPC_H_
 
 #include <linux/types.h>
+#include <linux/sockios.h>
 
 /*
  * TIPC addressing primitives
@@ -87,6 +88,7 @@
 
 #define TIPC_CFG_SRV		0	/* configuration service name type */
 #define TIPC_TOP_SRV		1	/* topology service name type */
+#define TIPC_LINK_STATE		2	/* link state name type */
 #define TIPC_RESERVED_TYPES	64	/* lowest user-publishable name type */
 
 /*
@@ -206,4 +208,25 @@
 #define TIPC_NODE_RECVQ_DEPTH	131	/* Default: none (read only) */
 #define TIPC_SOCK_RECVQ_DEPTH	132	/* Default: none (read only) */
 
+/*
+ * Maximum sizes of TIPC bearer-related names (including terminating NULL)
+ * The string formatting for each name element is:
+ * media: media
+ * interface: media:interface name
+ * link: Z.C.N:interface-Z.C.N:interface
+ *
+ */
+
+#define TIPC_MAX_MEDIA_NAME	16
+#define TIPC_MAX_IF_NAME	16
+#define TIPC_MAX_BEARER_NAME	32
+#define TIPC_MAX_LINK_NAME	60
+
+#define SIOCGETLINKNAME		SIOCPROTOPRIVATE
+
+struct tipc_sioc_ln_req {
+	__u32 peer;
+	__u32 bearer_id;
+	char linkname[TIPC_MAX_LINK_NAME];
+};
 #endif
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 6b0bff0..41a76ac 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -39,6 +39,7 @@
 
 #include <linux/types.h>
 #include <linux/string.h>
+#include <linux/tipc.h>
 #include <asm/byteorder.h>
 
 #ifndef __KERNEL__
@@ -155,15 +156,6 @@
 #define TIPC_TLV_PORT_REF	26	/* 32-bit port reference */
 
 /*
- * Maximum sizes of TIPC bearer-related names (including terminating NUL)
- */
-
-#define TIPC_MAX_MEDIA_NAME	16	/* format = media */
-#define TIPC_MAX_IF_NAME	16	/* format = interface */
-#define TIPC_MAX_BEARER_NAME	32	/* format = media:interface */
-#define TIPC_MAX_LINK_NAME	60	/* format = Z.C.N:interface-Z.C.N:interface */
-
-/*
  * Link priority limits (min, default, max, media default)
  */
 
diff --git a/init/Kconfig b/init/Kconfig
index 765018c..9d3585b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1646,6 +1646,18 @@
 
 	  See Documentation/nommu-mmap.txt for more information.
 
+config SYSTEM_TRUSTED_KEYRING
+	bool "Provide system-wide ring of trusted keys"
+	depends on KEYS
+	help
+	  Provide a system keyring to which trusted keys can be added.  Keys in
+	  the keyring are considered to be trusted.  Keys may be added at will
+	  by the kernel from compiled-in data and from hardware key stores, but
+	  userspace may only add extra keys if those keys can be verified by
+	  keys already in the keyring.
+
+	  Keys in this keyring are used by module signature checking.
+
 config PROFILING
 	bool "Profiling support"
 	help
@@ -1681,18 +1693,6 @@
 	default 0 if BASE_FULL
 	default 1 if !BASE_FULL
 
-config SYSTEM_TRUSTED_KEYRING
-	bool "Provide system-wide ring of trusted keys"
-	depends on KEYS
-	help
-	  Provide a system keyring to which trusted keys can be added.  Keys in
-	  the keyring are considered to be trusted.  Keys may be added at will
-	  by the kernel from compiled-in data and from hardware key stores, but
-	  userspace may only add extra keys if those keys can be verified by
-	  keys already in the keyring.
-
-	  Keys in this keyring are used by module signature checking.
-
 menuconfig MODULES
 	bool "Enable loadable module support"
 	option modules
diff --git a/kernel/audit.c b/kernel/audit.c
index 7c28936..33531d7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -424,6 +424,38 @@
 }
 
 /*
+ * kauditd_send_multicast_skb - send the skb to multicast userspace listeners
+ *
+ * This function doesn't consume an skb as might be expected since it has to
+ * copy it anyways.
+ */
+static void kauditd_send_multicast_skb(struct sk_buff *skb)
+{
+	struct sk_buff		*copy;
+	struct audit_net	*aunet = net_generic(&init_net, audit_net_id);
+	struct sock		*sock = aunet->nlsk;
+
+	if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG))
+		return;
+
+	/*
+	 * The seemingly wasteful skb_copy() rather than bumping the refcount
+	 * using skb_get() is necessary because non-standard mods are made to
+	 * the skb by the original kaudit unicast socket send routine.  The
+	 * existing auditd daemon assumes this breakage.  Fixing this would
+	 * require co-ordinating a change in the established protocol between
+	 * the kaudit kernel subsystem and the auditd userspace code.  There is
+	 * no reason for new multicast clients to continue with this
+	 * non-compliance.
+	 */
+	copy = skb_copy(skb, GFP_KERNEL);
+	if (!copy)
+		return;
+
+	nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
+}
+
+/*
  * flush_hold_queue - empty the hold queue if auditd appears
  *
  * If auditd just started, drain the queue of messages already
@@ -1076,10 +1108,22 @@
 	mutex_unlock(&audit_cmd_mutex);
 }
 
+/* Run custom bind function on netlink socket group connect or bind requests. */
+static int audit_bind(int group)
+{
+	if (!capable(CAP_AUDIT_READ))
+		return -EPERM;
+
+	return 0;
+}
+
 static int __net_init audit_net_init(struct net *net)
 {
 	struct netlink_kernel_cfg cfg = {
 		.input	= audit_receive,
+		.bind	= audit_bind,
+		.flags	= NL_CFG_F_NONROOT_RECV,
+		.groups	= AUDIT_NLGRP_MAX,
 	};
 
 	struct audit_net *aunet = net_generic(net, audit_net_id);
@@ -1901,10 +1945,10 @@
  * audit_log_end - end one audit record
  * @ab: the audit_buffer
  *
- * The netlink_* functions cannot be called inside an irq context, so
- * the audit buffer is placed on a queue and a tasklet is scheduled to
- * remove them from the queue outside the irq context.  May be called in
- * any context.
+ * netlink_unicast() cannot be called inside an irq context because it blocks
+ * (last arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed
+ * on a queue and a tasklet is scheduled to remove them from the queue outside
+ * the irq context.  May be called in any context.
  */
 void audit_log_end(struct audit_buffer *ab)
 {
@@ -1914,6 +1958,18 @@
 		audit_log_lost("rate limit exceeded");
 	} else {
 		struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
+
+		kauditd_send_multicast_skb(ab->skb);
+
+		/*
+		 * The original kaudit unicast socket sends up messages with
+		 * nlmsg_len set to the payload length rather than the entire
+		 * message length.  This breaks the standard set by netlink.
+		 * The existing auditd daemon assumes this breakage.  Fixing
+		 * this would require co-ordinating a change in the established
+		 * protocol between the kaudit kernel subsystem and the auditd
+		 * userspace code.
+		 */
 		nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
 
 		if (audit_pid) {
diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
index e1191c9..5cf6731 100644
--- a/kernel/locking/mutex-debug.c
+++ b/kernel/locking/mutex-debug.c
@@ -71,18 +71,17 @@
 
 void debug_mutex_unlock(struct mutex *lock)
 {
-	if (unlikely(!debug_locks))
-		return;
+	if (likely(debug_locks)) {
+		DEBUG_LOCKS_WARN_ON(lock->magic != lock);
 
-	DEBUG_LOCKS_WARN_ON(lock->magic != lock);
+		if (!lock->owner)
+			DEBUG_LOCKS_WARN_ON(!lock->owner);
+		else
+			DEBUG_LOCKS_WARN_ON(lock->owner != current);
 
-	if (!lock->owner)
-		DEBUG_LOCKS_WARN_ON(!lock->owner);
-	else
-		DEBUG_LOCKS_WARN_ON(lock->owner != current);
-
-	DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
-	mutex_clear_owner(lock);
+		DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
+		mutex_clear_owner(lock);
+	}
 
 	/*
 	 * __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 27ef409..b080957 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1021,8 +1021,17 @@
 
 	dl_rq = &rq->dl;
 
-	if (need_pull_dl_task(rq, prev))
+	if (need_pull_dl_task(rq, prev)) {
 		pull_dl_task(rq);
+		/*
+		 * pull_rt_task() can drop (and re-acquire) rq->lock; this
+		 * means a stop task can slip in, in which case we need to
+		 * re-start task selection.
+		 */
+		if (rq->stop && rq->stop->on_rq)
+			return RETRY_TASK;
+	}
+
 	/*
 	 * When prev is DL, we may throttle it in put_prev_task().
 	 * So, we update time before we check for dl_nr_running.
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7e9bd0b..7570dd9 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1497,7 +1497,7 @@
 	/* If the task is part of a group prevent parallel updates to group stats */
 	if (p->numa_group) {
 		group_lock = &p->numa_group->lock;
-		spin_lock(group_lock);
+		spin_lock_irq(group_lock);
 	}
 
 	/* Find the node with the highest number of faults */
@@ -1572,7 +1572,7 @@
 			}
 		}
 
-		spin_unlock(group_lock);
+		spin_unlock_irq(group_lock);
 	}
 
 	/* Preferred node as the node with the most faults */
@@ -1677,7 +1677,8 @@
 	if (!join)
 		return;
 
-	double_lock(&my_grp->lock, &grp->lock);
+	BUG_ON(irqs_disabled());
+	double_lock_irq(&my_grp->lock, &grp->lock);
 
 	for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) {
 		my_grp->faults[i] -= p->numa_faults_memory[i];
@@ -1691,7 +1692,7 @@
 	grp->nr_tasks++;
 
 	spin_unlock(&my_grp->lock);
-	spin_unlock(&grp->lock);
+	spin_unlock_irq(&grp->lock);
 
 	rcu_assign_pointer(p->numa_group, grp);
 
@@ -1710,14 +1711,14 @@
 	void *numa_faults = p->numa_faults_memory;
 
 	if (grp) {
-		spin_lock(&grp->lock);
+		spin_lock_irq(&grp->lock);
 		for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
 			grp->faults[i] -= p->numa_faults_memory[i];
 		grp->total_faults -= p->total_numa_faults;
 
 		list_del(&p->numa_entry);
 		grp->nr_tasks--;
-		spin_unlock(&grp->lock);
+		spin_unlock_irq(&grp->lock);
 		rcu_assign_pointer(p->numa_group, NULL);
 		put_numa_group(grp);
 	}
@@ -6727,7 +6728,8 @@
 out:
 	/* Is there a task of a high priority class? */
 	if (this_rq->nr_running != this_rq->cfs.h_nr_running &&
-	    (this_rq->dl.dl_nr_running ||
+	    ((this_rq->stop && this_rq->stop->on_rq) ||
+	     this_rq->dl.dl_nr_running ||
 	     (this_rq->rt.rt_nr_running && !rt_rq_throttled(&this_rq->rt))))
 		pulled_task = -1;
 
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index d8cdf16..bd2267a 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1362,10 +1362,11 @@
 		pull_rt_task(rq);
 		/*
 		 * pull_rt_task() can drop (and re-acquire) rq->lock; this
-		 * means a dl task can slip in, in which case we need to
-		 * re-start task selection.
+		 * means a dl or stop task can slip in, in which case we need
+		 * to re-start task selection.
 		 */
-		if (unlikely(rq->dl.dl_nr_running))
+		if (unlikely((rq->stop && rq->stop->on_rq) ||
+			     rq->dl.dl_nr_running))
 			return RETRY_TASK;
 	}
 
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c9007f2..456e492 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1385,6 +1385,15 @@
 	spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
 }
 
+static inline void double_lock_irq(spinlock_t *l1, spinlock_t *l2)
+{
+	if (l1 > l2)
+		swap(l1, l2);
+
+	spin_lock_irq(l1);
+	spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
+}
+
 static inline void double_raw_lock(raw_spinlock_t *l1, raw_spinlock_t *l2)
 {
 	if (l1 > l2)
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 0156612..0a0608e 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -276,7 +276,7 @@
 bool tick_check_replacement(struct clock_event_device *curdev,
 			    struct clock_event_device *newdev)
 {
-	if (tick_check_percpu(curdev, newdev, smp_processor_id()))
+	if (!tick_check_percpu(curdev, newdev, smp_processor_id()))
 		return false;
 
 	return tick_check_preferred(curdev, newdev);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 9f8af69..6558b7a 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -84,6 +84,9 @@
 
 		/* Keep the tick_next_period variable up to date */
 		tick_next_period = ktime_add(last_jiffies_update, tick_period);
+	} else {
+		write_sequnlock(&jiffies_lock);
+		return;
 	}
 	write_sequnlock(&jiffies_lock);
 	update_wall_time();
@@ -967,7 +970,7 @@
 	struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
 	ktime_t next;
 
-	if (!tick_nohz_active)
+	if (!tick_nohz_enabled)
 		return;
 
 	local_irq_disable();
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 5b781d2..ffd5635 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -58,12 +58,16 @@
 {
 	int ret;
 
-	/* The top level array uses the "global_ops". */
-	if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL)) {
-		ret = allocate_ftrace_ops(tr);
-		if (ret)
-			return ret;
-	}
+	/*
+	 * The top level array uses the "global_ops", and the files are
+	 * created on boot up.
+	 */
+	if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
+		return 0;
+
+	ret = allocate_ftrace_ops(tr);
+	if (ret)
+		return ret;
 
 	ftrace_create_filter_files(tr->ops, parent);
 
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 930e514..c082a74 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -732,9 +732,15 @@
 
 static void uprobe_buffer_disable(void)
 {
+	int cpu;
+
 	BUG_ON(!mutex_is_locked(&event_mutex));
 
 	if (--uprobe_buffer_refcnt == 0) {
+		for_each_possible_cpu(cpu)
+			free_page((unsigned long)per_cpu_ptr(uprobe_cpu_buffer,
+							     cpu)->buf);
+
 		free_percpu(uprobe_cpu_buffer);
 		uprobe_cpu_buffer = NULL;
 	}
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index e90089f..516203e 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -138,7 +138,11 @@
 
 void touch_softlockup_watchdog(void)
 {
-	__this_cpu_write(watchdog_touch_ts, 0);
+	/*
+	 * Preemption can be enabled.  It doesn't matter which CPU's timestamp
+	 * gets zeroed here, so use the raw_ operation.
+	 */
+	raw_cpu_write(watchdog_touch_ts, 0);
 }
 EXPORT_SYMBOL(touch_softlockup_watchdog);
 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 140b66a..819ac51 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -505,8 +505,7 @@
 	bool "Debug VM red-black trees"
 	depends on DEBUG_VM
 	help
-	  Enable this to turn on more extended checks in the virtual-memory
-	  system that may impact performance.
+	  Enable VM red-black tree debugging information and extra validations.
 
 	  If unsure, say N.
 
diff --git a/mm/filemap.c b/mm/filemap.c
index a82fbe4..5020b28 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2581,7 +2581,6 @@
  * @iocb:	IO state structure (file, offset, etc.)
  * @iov:	vector with data to write
  * @nr_segs:	number of segments in the vector
- * @ppos:	position where to write
  *
  * This function does all the work needed for actually writing data to a
  * file. It does all basic checks, removes SUID from the file, updates
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 64635f5..b4b1feb 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1536,16 +1536,23 @@
 			      enum page_check_address_pmd_flag flag,
 			      spinlock_t **ptl)
 {
+	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 
 	if (address & ~HPAGE_PMD_MASK)
 		return NULL;
 
-	pmd = mm_find_pmd(mm, address);
-	if (!pmd)
+	pgd = pgd_offset(mm, address);
+	if (!pgd_present(*pgd))
 		return NULL;
+	pud = pud_offset(pgd, address);
+	if (!pud_present(*pud))
+		return NULL;
+	pmd = pmd_offset(pud, address);
+
 	*ptl = pmd_lock(mm, pmd);
-	if (pmd_none(*pmd))
+	if (!pmd_present(*pmd))
 		goto unlock;
 	if (pmd_page(*pmd) != page)
 		goto unlock;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index dd30f22..24619292 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1172,6 +1172,7 @@
 	while (nr_pages--) {
 		if (!free_pool_huge_page(h, &node_states[N_MEMORY], 1))
 			break;
+		cond_resched_lock(&hugetlb_lock);
 	}
 }
 
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9b6497e..3f56c8d 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1158,7 +1158,7 @@
 			TTU_UNMAP|TTU_IGNORE_ACCESS,
 			&dummy1, &dummy2, &dummy3, &dummy4, &dummy5, true);
 	list_splice(&clean_pages, page_list);
-	__mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
+	mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
 	return ret;
 }
 
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 6f142f0..8f025af 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -493,10 +493,48 @@
 	}
 }
 
+static int vlan_calculate_locking_subclass(struct net_device *real_dev)
+{
+	int subclass = 0;
+
+	while (is_vlan_dev(real_dev)) {
+		subclass++;
+		real_dev = vlan_dev_priv(real_dev)->real_dev;
+	}
+
+	return subclass;
+}
+
+static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from)
+{
+	int err = 0, subclass;
+
+	subclass = vlan_calculate_locking_subclass(to);
+
+	spin_lock_nested(&to->addr_list_lock, subclass);
+	err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
+	if (!err)
+		__dev_set_rx_mode(to);
+	spin_unlock(&to->addr_list_lock);
+}
+
+static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from)
+{
+	int err = 0, subclass;
+
+	subclass = vlan_calculate_locking_subclass(to);
+
+	spin_lock_nested(&to->addr_list_lock, subclass);
+	err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
+	if (!err)
+		__dev_set_rx_mode(to);
+	spin_unlock(&to->addr_list_lock);
+}
+
 static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
 {
-	dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
-	dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+	vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+	vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
 }
 
 /*
@@ -608,9 +646,7 @@
 
 	SET_NETDEV_DEVTYPE(dev, &vlan_type);
 
-	if (is_vlan_dev(real_dev))
-		subclass = 1;
-
+	subclass = vlan_calculate_locking_subclass(dev);
 	vlan_dev_set_lockdep_class(dev, subclass);
 
 	vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
@@ -670,38 +706,36 @@
 
 static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
+	struct vlan_pcpu_stats *p;
+	u32 rx_errors = 0, tx_dropped = 0;
+	int i;
 
-	if (vlan_dev_priv(dev)->vlan_pcpu_stats) {
-		struct vlan_pcpu_stats *p;
-		u32 rx_errors = 0, tx_dropped = 0;
-		int i;
+	for_each_possible_cpu(i) {
+		u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes;
+		unsigned int start;
 
-		for_each_possible_cpu(i) {
-			u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes;
-			unsigned int start;
+		p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
+		do {
+			start = u64_stats_fetch_begin_irq(&p->syncp);
+			rxpackets	= p->rx_packets;
+			rxbytes		= p->rx_bytes;
+			rxmulticast	= p->rx_multicast;
+			txpackets	= p->tx_packets;
+			txbytes		= p->tx_bytes;
+		} while (u64_stats_fetch_retry_irq(&p->syncp, start));
 
-			p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
-			do {
-				start = u64_stats_fetch_begin_irq(&p->syncp);
-				rxpackets	= p->rx_packets;
-				rxbytes		= p->rx_bytes;
-				rxmulticast	= p->rx_multicast;
-				txpackets	= p->tx_packets;
-				txbytes		= p->tx_bytes;
-			} while (u64_stats_fetch_retry_irq(&p->syncp, start));
-
-			stats->rx_packets	+= rxpackets;
-			stats->rx_bytes		+= rxbytes;
-			stats->multicast	+= rxmulticast;
-			stats->tx_packets	+= txpackets;
-			stats->tx_bytes		+= txbytes;
-			/* rx_errors & tx_dropped are u32 */
-			rx_errors	+= p->rx_errors;
-			tx_dropped	+= p->tx_dropped;
-		}
-		stats->rx_errors  = rx_errors;
-		stats->tx_dropped = tx_dropped;
+		stats->rx_packets	+= rxpackets;
+		stats->rx_bytes		+= rxbytes;
+		stats->multicast	+= rxmulticast;
+		stats->tx_packets	+= txpackets;
+		stats->tx_bytes		+= txbytes;
+		/* rx_errors & tx_dropped are u32 */
+		rx_errors	+= p->rx_errors;
+		tx_dropped	+= p->tx_dropped;
 	}
+	stats->rx_errors  = rx_errors;
+	stats->tx_dropped = tx_dropped;
+
 	return stats;
 }
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 5b3042e..11d70e3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1661,6 +1661,29 @@
 }
 EXPORT_SYMBOL_GPL(is_skb_forwardable);
 
+int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
+{
+	if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
+		if (skb_copy_ubufs(skb, GFP_ATOMIC)) {
+			atomic_long_inc(&dev->rx_dropped);
+			kfree_skb(skb);
+			return NET_RX_DROP;
+		}
+	}
+
+	if (unlikely(!is_skb_forwardable(dev, skb))) {
+		atomic_long_inc(&dev->rx_dropped);
+		kfree_skb(skb);
+		return NET_RX_DROP;
+	}
+
+	skb_scrub_packet(skb, true);
+	skb->protocol = eth_type_trans(skb, dev);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__dev_forward_skb);
+
 /**
  * dev_forward_skb - loopback an skb to another netif
  *
@@ -1681,24 +1704,7 @@
  */
 int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
 {
-	if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
-		if (skb_copy_ubufs(skb, GFP_ATOMIC)) {
-			atomic_long_inc(&dev->rx_dropped);
-			kfree_skb(skb);
-			return NET_RX_DROP;
-		}
-	}
-
-	if (unlikely(!is_skb_forwardable(dev, skb))) {
-		atomic_long_inc(&dev->rx_dropped);
-		kfree_skb(skb);
-		return NET_RX_DROP;
-	}
-
-	skb_scrub_packet(skb, true);
-	skb->protocol = eth_type_trans(skb, dev);
-
-	return netif_rx_internal(skb);
+	return __dev_forward_skb(dev, skb) ?: netif_rx_internal(skb);
 }
 EXPORT_SYMBOL_GPL(dev_forward_skb);
 
@@ -5238,6 +5244,7 @@
 	if (ops->ndo_set_rx_mode)
 		ops->ndo_set_rx_mode(dev);
 }
+EXPORT_SYMBOL(__dev_set_rx_mode);
 
 void dev_set_rx_mode(struct net_device *dev)
 {
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 640ba0e..aa8978ac 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -557,6 +557,25 @@
 	return ret;
 }
 
+static int ethtool_copy_validate_indir(u32 *indir, void __user *useraddr,
+					struct ethtool_rxnfc *rx_rings,
+					u32 size)
+{
+	int ret = 0, i;
+
+	if (copy_from_user(indir, useraddr, size * sizeof(indir[0])))
+		ret = -EFAULT;
+
+	/* Validate ring indices */
+	for (i = 0; i < size; i++) {
+		if (indir[i] >= rx_rings->data) {
+			ret = -EINVAL;
+			break;
+		}
+	}
+	return ret;
+}
+
 static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
 						     void __user *useraddr)
 {
@@ -613,6 +632,7 @@
 	u32 *indir;
 	const struct ethtool_ops *ops = dev->ethtool_ops;
 	int ret;
+	u32 ringidx_offset = offsetof(struct ethtool_rxfh_indir, ring_index[0]);
 
 	if (!ops->get_rxfh_indir_size || !ops->set_rxfh_indir ||
 	    !ops->get_rxnfc)
@@ -643,22 +663,12 @@
 		for (i = 0; i < dev_size; i++)
 			indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
 	} else {
-		if (copy_from_user(indir,
-				  useraddr +
-				  offsetof(struct ethtool_rxfh_indir,
-					   ring_index[0]),
-				  dev_size * sizeof(indir[0]))) {
-			ret = -EFAULT;
+		ret = ethtool_copy_validate_indir(indir,
+						  useraddr + ringidx_offset,
+						  &rx_rings,
+						  dev_size);
+		if (ret)
 			goto out;
-		}
-
-		/* Validate ring indices */
-		for (i = 0; i < dev_size; i++) {
-			if (indir[i] >= rx_rings.data) {
-				ret = -EINVAL;
-				goto out;
-			}
-		}
 	}
 
 	ret = ops->set_rxfh_indir(dev, indir);
@@ -668,6 +678,184 @@
 	return ret;
 }
 
+static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
+					       void __user *useraddr)
+{
+	int ret;
+	const struct ethtool_ops *ops = dev->ethtool_ops;
+	u32 user_indir_size = 0, user_key_size = 0;
+	u32 dev_indir_size = 0, dev_key_size = 0;
+	u32 total_size;
+	u32 indir_offset, indir_bytes;
+	u32 key_offset;
+	u32 *indir = NULL;
+	u8 *hkey = NULL;
+	u8 *rss_config;
+
+	if (!(dev->ethtool_ops->get_rxfh_indir_size ||
+	      dev->ethtool_ops->get_rxfh_key_size) ||
+	      !dev->ethtool_ops->get_rxfh)
+		return -EOPNOTSUPP;
+
+	if (ops->get_rxfh_indir_size)
+		dev_indir_size = ops->get_rxfh_indir_size(dev);
+
+	indir_offset = offsetof(struct ethtool_rxfh, indir_size);
+
+	if (copy_from_user(&user_indir_size,
+			   useraddr + indir_offset,
+			   sizeof(user_indir_size)))
+		return -EFAULT;
+
+	if (copy_to_user(useraddr + indir_offset,
+			 &dev_indir_size, sizeof(dev_indir_size)))
+		return -EFAULT;
+
+	if (ops->get_rxfh_key_size)
+		dev_key_size = ops->get_rxfh_key_size(dev);
+
+	if ((dev_key_size + dev_indir_size) == 0)
+		return -EOPNOTSUPP;
+
+	key_offset = offsetof(struct ethtool_rxfh, key_size);
+
+	if (copy_from_user(&user_key_size,
+			   useraddr + key_offset,
+			   sizeof(user_key_size)))
+		return -EFAULT;
+
+	if (copy_to_user(useraddr + key_offset,
+			 &dev_key_size, sizeof(dev_key_size)))
+		return -EFAULT;
+
+	/* If the user buffer size is 0, this is just a query for the
+	 * device table size and key size.  Otherwise, if the User size is
+	 * not equal to device table size or key size it's an error.
+	 */
+	if (!user_indir_size && !user_key_size)
+		return 0;
+
+	if ((user_indir_size && (user_indir_size != dev_indir_size)) ||
+	    (user_key_size && (user_key_size != dev_key_size)))
+		return -EINVAL;
+
+	indir_bytes = user_indir_size * sizeof(indir[0]);
+	total_size = indir_bytes + user_key_size;
+	rss_config = kzalloc(total_size, GFP_USER);
+	if (!rss_config)
+		return -ENOMEM;
+
+	if (user_indir_size)
+		indir = (u32 *)rss_config;
+
+	if (user_key_size)
+		hkey = rss_config + indir_bytes;
+
+	ret = dev->ethtool_ops->get_rxfh(dev, indir, hkey);
+	if (!ret) {
+		if (copy_to_user(useraddr +
+				 offsetof(struct ethtool_rxfh, rss_config[0]),
+				 rss_config, total_size))
+			ret = -EFAULT;
+	}
+
+	kfree(rss_config);
+
+	return ret;
+}
+
+static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
+					       void __user *useraddr)
+{
+	int ret;
+	const struct ethtool_ops *ops = dev->ethtool_ops;
+	struct ethtool_rxnfc rx_rings;
+	u32 user_indir_size = 0, dev_indir_size = 0, i;
+	u32 user_key_size = 0, dev_key_size = 0;
+	u32 *indir = NULL, indir_bytes = 0;
+	u8 *hkey = NULL;
+	u8 *rss_config;
+	u32 indir_offset, key_offset;
+	u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]);
+
+	if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size) ||
+	    !ops->get_rxnfc || !ops->set_rxfh)
+		return -EOPNOTSUPP;
+
+	if (ops->get_rxfh_indir_size)
+		dev_indir_size = ops->get_rxfh_indir_size(dev);
+
+	indir_offset = offsetof(struct ethtool_rxfh, indir_size);
+	if (copy_from_user(&user_indir_size,
+			   useraddr + indir_offset,
+			   sizeof(user_indir_size)))
+		return -EFAULT;
+
+	if (ops->get_rxfh_key_size)
+		dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev);
+
+	if ((dev_key_size + dev_indir_size) == 0)
+		return -EOPNOTSUPP;
+
+	key_offset = offsetof(struct ethtool_rxfh, key_size);
+	if (copy_from_user(&user_key_size,
+			   useraddr + key_offset,
+			   sizeof(user_key_size)))
+		return -EFAULT;
+
+	/* If either indir or hash key is valid, proceed further.
+	 */
+	if ((user_indir_size && ((user_indir_size != 0xDEADBEEF) &&
+				 user_indir_size != dev_indir_size)) ||
+	    (user_key_size && (user_key_size != dev_key_size)))
+		return -EINVAL;
+
+	if (user_indir_size != 0xDEADBEEF)
+		indir_bytes = dev_indir_size * sizeof(indir[0]);
+
+	rss_config = kzalloc(indir_bytes + user_key_size, GFP_USER);
+	if (!rss_config)
+		return -ENOMEM;
+
+	rx_rings.cmd = ETHTOOL_GRXRINGS;
+	ret = ops->get_rxnfc(dev, &rx_rings, NULL);
+	if (ret)
+		goto out;
+
+	/* user_indir_size == 0 means reset the indir table to default.
+	 * user_indir_size == 0xDEADBEEF means indir setting is not requested.
+	 */
+	if (user_indir_size && user_indir_size != 0xDEADBEEF) {
+		indir = (u32 *)rss_config;
+		ret = ethtool_copy_validate_indir(indir,
+						  useraddr + rss_cfg_offset,
+						  &rx_rings,
+						  user_indir_size);
+		if (ret)
+			goto out;
+	} else if (user_indir_size == 0) {
+		indir = (u32 *)rss_config;
+		for (i = 0; i < dev_indir_size; i++)
+			indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
+	}
+
+	if (user_key_size) {
+		hkey = rss_config + indir_bytes;
+		if (copy_from_user(hkey,
+				   useraddr + rss_cfg_offset + indir_bytes,
+				   user_key_size)) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+
+	ret = ops->set_rxfh(dev, indir, hkey);
+
+out:
+	kfree(rss_config);
+	return ret;
+}
+
 static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_regs regs;
@@ -1491,6 +1679,7 @@
 	case ETHTOOL_GRXCLSRULE:
 	case ETHTOOL_GRXCLSRLALL:
 	case ETHTOOL_GRXFHINDIR:
+	case ETHTOOL_GRSSH:
 	case ETHTOOL_GFEATURES:
 	case ETHTOOL_GCHANNELS:
 	case ETHTOOL_GET_TS_INFO:
@@ -1628,6 +1817,12 @@
 	case ETHTOOL_SRXFHINDIR:
 		rc = ethtool_set_rxfh_indir(dev, useraddr);
 		break;
+	case ETHTOOL_GRSSH:
+		rc = ethtool_get_rxfh(dev, useraddr);
+		break;
+	case ETHTOOL_SRSSH:
+		rc = ethtool_set_rxfh(dev, useraddr);
+		break;
 	case ETHTOOL_GFEATURES:
 		rc = ethtool_get_features(dev, useraddr);
 		break;
diff --git a/net/core/filter.c b/net/core/filter.c
index cd58614..7c4db3d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -122,6 +122,13 @@
 	return 0;
 }
 
+/* Register mappings for user programs. */
+#define A_REG		0
+#define X_REG		7
+#define TMP_REG		8
+#define ARG2_REG	2
+#define ARG3_REG	3
+
 /**
  *	__sk_run_filter - run a filter on a given context
  *	@ctx: buffer to run the filter on
@@ -242,6 +249,8 @@
 
 	regs[FP_REG]  = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)];
 	regs[ARG1_REG] = (u64) (unsigned long) ctx;
+	regs[A_REG] = 0;
+	regs[X_REG] = 0;
 
 select_insn:
 	goto *jumptable[insn->code];
@@ -643,12 +652,11 @@
 	return raw_smp_processor_id();
 }
 
-/* Register mappings for user programs. */
-#define A_REG		0
-#define X_REG		7
-#define TMP_REG		8
-#define ARG2_REG	2
-#define ARG3_REG	3
+/* note that this only generates 32-bit random numbers */
+static u64 __get_random_u32(u64 ctx, u64 A, u64 X, u64 r4, u64 r5)
+{
+	return (u64)prandom_u32();
+}
 
 static bool convert_bpf_extensions(struct sock_filter *fp,
 				   struct sock_filter_int **insnp)
@@ -779,6 +787,7 @@
 	case SKF_AD_OFF + SKF_AD_NLATTR:
 	case SKF_AD_OFF + SKF_AD_NLATTR_NEST:
 	case SKF_AD_OFF + SKF_AD_CPU:
+	case SKF_AD_OFF + SKF_AD_RANDOM:
 		/* arg1 = ctx */
 		insn->code = BPF_ALU64 | BPF_MOV | BPF_X;
 		insn->a_reg = ARG1_REG;
@@ -812,6 +821,9 @@
 		case SKF_AD_OFF + SKF_AD_CPU:
 			insn->imm = __get_raw_cpu_id - __bpf_call_base;
 			break;
+		case SKF_AD_OFF + SKF_AD_RANDOM:
+			insn->imm = __get_random_u32 - __bpf_call_base;
+			break;
 		}
 		break;
 
@@ -1362,6 +1374,7 @@
 			ANCILLARY(VLAN_TAG);
 			ANCILLARY(VLAN_TAG_PRESENT);
 			ANCILLARY(PAY_OFFSET);
+			ANCILLARY(RANDOM);
 			}
 
 			/* ancillary operation unknown or unsupported */
@@ -1746,6 +1759,7 @@
 		[BPF_S_ANC_VLAN_TAG]	= BPF_LD|BPF_B|BPF_ABS,
 		[BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS,
 		[BPF_S_ANC_PAY_OFFSET]	= BPF_LD|BPF_B|BPF_ABS,
+		[BPF_S_ANC_RANDOM]	= BPF_LD|BPF_B|BPF_ABS,
 		[BPF_S_LD_W_LEN]	= BPF_LD|BPF_W|BPF_LEN,
 		[BPF_S_LD_W_IND]	= BPF_LD|BPF_W|BPF_IND,
 		[BPF_S_LD_H_IND]	= BPF_LD|BPF_H|BPF_IND,
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 81d3a9a..05e949d 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -273,7 +273,7 @@
 {
 	const struct pernet_operations *ops;
 	struct net *net, *tmp;
-	LIST_HEAD(net_kill_list);
+	struct list_head net_kill_list;
 	LIST_HEAD(net_exit_list);
 
 	/* Atomically snapshot the list of namespaces to cleanup */
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index d7af188..9deb6ab 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -49,7 +49,7 @@
 }
 EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
 
-int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
+int sock_diag_put_filterinfo(struct sock *sk,
 			     struct sk_buff *skb, int attrtype)
 {
 	struct sock_fprog_kern *fprog;
@@ -58,7 +58,7 @@
 	unsigned int flen;
 	int err = 0;
 
-	if (!ns_capable(user_ns, CAP_NET_ADMIN)) {
+	if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
 		nla_reserve(skb, attrtype, 0);
 		return 0;
 	}
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c
index ef2d543..6f1428c 100644
--- a/net/ieee802154/reassembly.c
+++ b/net/ieee802154/reassembly.c
@@ -36,7 +36,7 @@
 	u8 d_offset;
 };
 
-struct lowpan_frag_info *lowpan_cb(struct sk_buff *skb)
+static struct lowpan_frag_info *lowpan_cb(struct sk_buff *skb)
 {
 	return (struct lowpan_frag_info *)skb->cb;
 }
@@ -120,6 +120,8 @@
 	struct inet_frag_queue *q;
 	struct lowpan_create_arg arg;
 	unsigned int hash;
+	struct netns_ieee802154_lowpan *ieee802154_lowpan =
+		net_ieee802154_lowpan(net);
 
 	arg.tag = frag_info->d_tag;
 	arg.d_size = frag_info->d_size;
@@ -129,7 +131,7 @@
 	read_lock(&lowpan_frags.lock);
 	hash = lowpan_hash_frag(frag_info->d_tag, frag_info->d_size, src, dst);
 
-	q = inet_frag_find(&net->ieee802154_lowpan.frags,
+	q = inet_frag_find(&ieee802154_lowpan->frags,
 			   &lowpan_frags, &arg, hash);
 	if (IS_ERR_OR_NULL(q)) {
 		inet_frag_maybe_warn_overflow(q, pr_fmt());
@@ -357,6 +359,8 @@
 	struct net *net = dev_net(skb->dev);
 	struct lowpan_frag_info *frag_info = lowpan_cb(skb);
 	struct ieee802154_addr source, dest;
+	struct netns_ieee802154_lowpan *ieee802154_lowpan =
+		net_ieee802154_lowpan(net);
 	int err;
 
 	source = mac_cb(skb)->source;
@@ -366,10 +370,10 @@
 	if (err < 0)
 		goto err;
 
-	if (frag_info->d_size > net->ieee802154_lowpan.max_dsize)
+	if (frag_info->d_size > ieee802154_lowpan->max_dsize)
 		goto err;
 
-	inet_frag_evictor(&net->ieee802154_lowpan.frags, &lowpan_frags, false);
+	inet_frag_evictor(&ieee802154_lowpan->frags, &lowpan_frags, false);
 
 	fq = fq_find(net, frag_info, &source, &dest);
 	if (fq != NULL) {
@@ -436,6 +440,8 @@
 {
 	struct ctl_table *table;
 	struct ctl_table_header *hdr;
+	struct netns_ieee802154_lowpan *ieee802154_lowpan =
+		net_ieee802154_lowpan(net);
 
 	table = lowpan_frags_ns_ctl_table;
 	if (!net_eq(net, &init_net)) {
@@ -444,10 +450,10 @@
 		if (table == NULL)
 			goto err_alloc;
 
-		table[0].data = &net->ieee802154_lowpan.frags.high_thresh;
-		table[1].data = &net->ieee802154_lowpan.frags.low_thresh;
-		table[2].data = &net->ieee802154_lowpan.frags.timeout;
-		table[3].data = &net->ieee802154_lowpan.max_dsize;
+		table[0].data = &ieee802154_lowpan->frags.high_thresh;
+		table[1].data = &ieee802154_lowpan->frags.low_thresh;
+		table[2].data = &ieee802154_lowpan->frags.timeout;
+		table[3].data = &ieee802154_lowpan->max_dsize;
 
 		/* Don't export sysctls to unprivileged users */
 		if (net->user_ns != &init_user_ns)
@@ -458,7 +464,7 @@
 	if (hdr == NULL)
 		goto err_reg;
 
-	net->ieee802154_lowpan.sysctl.frags_hdr = hdr;
+	ieee802154_lowpan->sysctl.frags_hdr = hdr;
 	return 0;
 
 err_reg:
@@ -471,9 +477,11 @@
 static void __net_exit lowpan_frags_ns_sysctl_unregister(struct net *net)
 {
 	struct ctl_table *table;
+	struct netns_ieee802154_lowpan *ieee802154_lowpan =
+		net_ieee802154_lowpan(net);
 
-	table = net->ieee802154_lowpan.sysctl.frags_hdr->ctl_table_arg;
-	unregister_net_sysctl_table(net->ieee802154_lowpan.sysctl.frags_hdr);
+	table = ieee802154_lowpan->sysctl.frags_hdr->ctl_table_arg;
+	unregister_net_sysctl_table(ieee802154_lowpan->sysctl.frags_hdr);
 	if (!net_eq(net, &init_net))
 		kfree(table);
 }
@@ -514,20 +522,26 @@
 
 static int __net_init lowpan_frags_init_net(struct net *net)
 {
-	net->ieee802154_lowpan.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
-	net->ieee802154_lowpan.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
-	net->ieee802154_lowpan.frags.timeout = IPV6_FRAG_TIMEOUT;
-	net->ieee802154_lowpan.max_dsize = 0xFFFF;
+	struct netns_ieee802154_lowpan *ieee802154_lowpan =
+		net_ieee802154_lowpan(net);
 
-	inet_frags_init_net(&net->ieee802154_lowpan.frags);
+	ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
+	ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
+	ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
+	ieee802154_lowpan->max_dsize = 0xFFFF;
+
+	inet_frags_init_net(&ieee802154_lowpan->frags);
 
 	return lowpan_frags_ns_sysctl_register(net);
 }
 
 static void __net_exit lowpan_frags_exit_net(struct net *net)
 {
+	struct netns_ieee802154_lowpan *ieee802154_lowpan =
+		net_ieee802154_lowpan(net);
+
 	lowpan_frags_ns_sysctl_unregister(net);
-	inet_frags_exit_net(&net->ieee802154_lowpan.frags, &lowpan_frags);
+	inet_frags_exit_net(&ieee802154_lowpan->frags, &lowpan_frags);
 }
 
 static struct pernet_operations lowpan_frags_ops = {
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 48f4244..c98cf14 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -120,7 +120,7 @@
 static void inetpeer_gc_worker(struct work_struct *work)
 {
 	struct inet_peer *p, *n, *c;
-	LIST_HEAD(list);
+	struct list_head list;
 
 	spin_lock_bh(&gc_lock);
 	list_replace_init(&gc_list, &list);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 94213c8..c5a557a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -410,7 +410,7 @@
 		struct flowi4 fl4;
 		struct rtable *rt;
 
-		rt = ip_route_output_gre(dev_net(dev), &fl4,
+		rt = ip_route_output_gre(t->net, &fl4,
 					 t->parms.iph.daddr,
 					 t->parms.iph.saddr,
 					 t->parms.o_key,
@@ -434,7 +434,7 @@
 
 	if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
 		struct in_device *in_dev;
-		in_dev = inetdev_by_index(dev_net(dev), t->mlink);
+		in_dev = inetdev_by_index(t->net, t->mlink);
 		if (in_dev)
 			ip_mc_dec_group(in_dev, t->parms.iph.daddr);
 	}
@@ -478,7 +478,7 @@
 	dev->needed_headroom	= LL_MAX_HEADER + sizeof(struct iphdr) + 4;
 	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr) - 4;
 
-	dev->features		|= NETIF_F_NETNS_LOCAL | GRE_FEATURES;
+	dev->features		|= GRE_FEATURES;
 	dev->hw_features	|= GRE_FEATURES;
 
 	if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index f4ab72e..5e7aece 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -364,7 +364,7 @@
 			}
 			if (optptr[2] <= optlen) {
 				unsigned char *timeptr = NULL;
-				if (optptr[2]+3 > optptr[1]) {
+				if (optptr[2]+3 > optlen) {
 					pp_ptr = optptr + 2;
 					goto error;
 				}
@@ -376,7 +376,7 @@
 					optptr[2] += 4;
 					break;
 				case IPOPT_TS_TSANDADDR:
-					if (optptr[2]+7 > optptr[1]) {
+					if (optptr[2]+7 > optlen) {
 						pp_ptr = optptr + 2;
 						goto error;
 					}
@@ -390,7 +390,7 @@
 					optptr[2] += 8;
 					break;
 				case IPOPT_TS_PRESPEC:
-					if (optptr[2]+7 > optptr[1]) {
+					if (optptr[2]+7 > optlen) {
 						pp_ptr = optptr + 2;
 						goto error;
 					}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4bd6d52..eb1dde3 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2916,6 +2916,14 @@
 	case TCP_USER_TIMEOUT:
 		val = jiffies_to_msecs(icsk->icsk_user_timeout);
 		break;
+
+	case TCP_FASTOPEN:
+		if (icsk->icsk_accept_queue.fastopenq != NULL)
+			val = icsk->icsk_accept_queue.fastopenq->max_qlen;
+		else
+			val = 0;
+		break;
+
 	case TCP_TIMESTAMP:
 		val = tcp_time_stamp + tp->tsoffset;
 		break;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d6b46eb..6efed13 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4703,28 +4703,6 @@
 	return -1;
 }
 
-/* RFC2861, slow part. Adjust cwnd, after it was not full during one rto.
- * As additional protections, we do not touch cwnd in retransmission phases,
- * and if application hit its sndbuf limit recently.
- */
-void tcp_cwnd_application_limited(struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
-	    sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
-		/* Limited by application or receiver window. */
-		u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk));
-		u32 win_used = max(tp->snd_cwnd_used, init_win);
-		if (win_used < tp->snd_cwnd) {
-			tp->snd_ssthresh = tcp_current_ssthresh(sk);
-			tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1;
-		}
-		tp->snd_cwnd_used = 0;
-	}
-	tp->snd_cwnd_stamp = tcp_time_stamp;
-}
-
 static bool tcp_should_expand_sndbuf(const struct sock *sk)
 {
 	const struct tcp_sock *tp = tcp_sk(sk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 025e250..20847de 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -878,15 +878,8 @@
 	BUG_ON(!skb || !tcp_skb_pcount(skb));
 
 	if (clone_it) {
-		const struct sk_buff *fclone = skb + 1;
-
 		skb_mstamp_get(&skb->skb_mstamp);
 
-		if (unlikely(skb->fclone == SKB_FCLONE_ORIG &&
-			     fclone->fclone == SKB_FCLONE_CLONE))
-			NET_INC_STATS(sock_net(sk),
-				      LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES);
-
 		if (unlikely(skb_cloned(skb)))
 			skb = pskb_copy(skb, gfp_mask);
 		else
@@ -1387,6 +1380,28 @@
 	return mss_now;
 }
 
+/* RFC2861, slow part. Adjust cwnd, after it was not full during one rto.
+ * As additional protections, we do not touch cwnd in retransmission phases,
+ * and if application hit its sndbuf limit recently.
+ */
+static void tcp_cwnd_application_limited(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+
+	if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
+	    sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
+		/* Limited by application or receiver window. */
+		u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk));
+		u32 win_used = max(tp->snd_cwnd_used, init_win);
+		if (win_used < tp->snd_cwnd) {
+			tp->snd_ssthresh = tcp_current_ssthresh(sk);
+			tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1;
+		}
+		tp->snd_cwnd_used = 0;
+	}
+	tp->snd_cwnd_stamp = tcp_time_stamp;
+}
+
 /* Congestion window validation. (RFC2861) */
 static void tcp_cwnd_validate(struct sock *sk)
 {
@@ -2039,6 +2054,25 @@
 	return true;
 }
 
+/* Thanks to skb fast clones, we can detect if a prior transmit of
+ * a packet is still in a qdisc or driver queue.
+ * In this case, there is very little point doing a retransmit !
+ * Note: This is called from BH context only.
+ */
+static bool skb_still_in_host_queue(const struct sock *sk,
+				    const struct sk_buff *skb)
+{
+	const struct sk_buff *fclone = skb + 1;
+
+	if (unlikely(skb->fclone == SKB_FCLONE_ORIG &&
+		     fclone->fclone == SKB_FCLONE_CLONE)) {
+		NET_INC_STATS_BH(sock_net(sk),
+				 LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES);
+		return true;
+	}
+	return false;
+}
+
 /* When probe timeout (PTO) fires, send a new segment if one exists, else
  * retransmit the last segment.
  */
@@ -2064,6 +2098,9 @@
 	if (WARN_ON(!skb))
 		goto rearm_timer;
 
+	if (skb_still_in_host_queue(sk, skb))
+		goto rearm_timer;
+
 	pcount = tcp_skb_pcount(skb);
 	if (WARN_ON(!pcount))
 		goto rearm_timer;
@@ -2385,6 +2422,9 @@
 	    min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
 		return -EAGAIN;
 
+	if (skb_still_in_host_queue(sk, skb))
+		return -EBUSY;
+
 	if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
 		if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
 			BUG();
@@ -2478,7 +2518,7 @@
 		 * see tcp_input.c tcp_sacktag_write_queue().
 		 */
 		TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt;
-	} else {
+	} else if (err != -EBUSY) {
 		NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL);
 	}
 	return err;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c7fa08..fc203db 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2504,8 +2504,8 @@
 	return PTR_ERR(ifp);
 }
 
-static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx,
-			  unsigned int plen)
+static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
+			  const struct in6_addr *pfx, unsigned int plen)
 {
 	struct inet6_ifaddr *ifp;
 	struct inet6_dev *idev;
@@ -2528,7 +2528,12 @@
 			in6_ifa_hold(ifp);
 			read_unlock_bh(&idev->lock);
 
+			if (!(ifp->flags & IFA_F_TEMPORARY) &&
+			    (ifa_flags & IFA_F_MANAGETEMPADDR))
+				manage_tempaddrs(idev, ifp, 0, 0, false,
+						 jiffies);
 			ipv6_del_addr(ifp);
+			addrconf_verify_rtnl();
 			return 0;
 		}
 	}
@@ -2568,7 +2573,7 @@
 		return -EFAULT;
 
 	rtnl_lock();
-	err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr,
+	err = inet6_addr_del(net, ireq.ifr6_ifindex, 0, &ireq.ifr6_addr,
 			     ireq.ifr6_prefixlen);
 	rtnl_unlock();
 	return err;
@@ -3743,6 +3748,7 @@
 	struct ifaddrmsg *ifm;
 	struct nlattr *tb[IFA_MAX+1];
 	struct in6_addr *pfx, *peer_pfx;
+	u32 ifa_flags;
 	int err;
 
 	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
@@ -3754,7 +3760,13 @@
 	if (pfx == NULL)
 		return -EINVAL;
 
-	return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
+	ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
+
+	/* We ignore other flags so far. */
+	ifa_flags &= IFA_F_MANAGETEMPADDR;
+
+	return inet6_addr_del(net, ifm->ifa_index, ifa_flags, pfx,
+			      ifm->ifa_prefixlen);
 }
 
 static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 7b32652..3b0905b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -493,12 +493,7 @@
 	if (IS_ERR(dst))
 		goto out;
 
-	if (ipv6_addr_is_multicast(&fl6.daddr))
-		hlimit = np->mcast_hops;
-	else
-		hlimit = np->hop_limit;
-	if (hlimit < 0)
-		hlimit = ip6_dst_hoplimit(dst);
+	hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
 	msg.skb = skb;
 	msg.offset = skb_network_offset(skb);
@@ -593,12 +588,7 @@
 	if (IS_ERR(dst))
 		goto out;
 
-	if (ipv6_addr_is_multicast(&fl6.daddr))
-		hlimit = np->mcast_hops;
-	else
-		hlimit = np->hop_limit;
-	if (hlimit < 0)
-		hlimit = ip6_dst_hoplimit(dst);
+	hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
 	idev = __in6_dev_get(skb->dev);
 
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 0961b5e..4052694 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -26,7 +26,6 @@
 #include <net/sock.h>
 
 #include <net/ipv6.h>
-#include <net/addrconf.h>
 #include <net/rawv6.h>
 #include <net/transp_v6.h>
 
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 9d92146..75277b7 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -72,6 +72,7 @@
 };
 
 static struct rtnl_link_ops ip6gre_link_ops __read_mostly;
+static struct rtnl_link_ops ip6gre_tap_ops __read_mostly;
 static int ip6gre_tunnel_init(struct net_device *dev);
 static void ip6gre_tunnel_setup(struct net_device *dev);
 static void ip6gre_tunnel_link(struct ip6gre_net *ign, struct ip6_tnl *t);
@@ -353,10 +354,10 @@
 
 static void ip6gre_tunnel_uninit(struct net_device *dev)
 {
-	struct net *net = dev_net(dev);
-	struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
+	struct ip6_tnl *t = netdev_priv(dev);
+	struct ip6gre_net *ign = net_generic(t->net, ip6gre_net_id);
 
-	ip6gre_tunnel_unlink(ign, netdev_priv(dev));
+	ip6gre_tunnel_unlink(ign, t);
 	dev_put(dev);
 }
 
@@ -611,8 +612,8 @@
 			 int encap_limit,
 			 __u32 *pmtu)
 {
-	struct net *net = dev_net(dev);
 	struct ip6_tnl *tunnel = netdev_priv(dev);
+	struct net *net = tunnel->net;
 	struct net_device *tdev;    /* Device to other host */
 	struct ipv6hdr  *ipv6h;     /* Our new IP header */
 	unsigned int max_headroom = 0; /* The extra header space needed */
@@ -979,7 +980,7 @@
 		int strict = (ipv6_addr_type(&p->raddr) &
 			      (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
 
-		struct rt6_info *rt = rt6_lookup(dev_net(dev),
+		struct rt6_info *rt = rt6_lookup(t->net,
 						 &p->raddr, &p->laddr,
 						 p->link, strict);
 
@@ -1063,13 +1064,12 @@
 	int err = 0;
 	struct ip6_tnl_parm2 p;
 	struct __ip6_tnl_parm p1;
-	struct ip6_tnl *t;
-	struct net *net = dev_net(dev);
+	struct ip6_tnl *t = netdev_priv(dev);
+	struct net *net = t->net;
 	struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
 
 	switch (cmd) {
 	case SIOCGETTUNNEL:
-		t = NULL;
 		if (dev == ign->fb_tunnel_dev) {
 			if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
 				err = -EFAULT;
@@ -1077,9 +1077,9 @@
 			}
 			ip6gre_tnl_parm_from_user(&p1, &p);
 			t = ip6gre_tunnel_locate(net, &p1, 0);
+			if (t == NULL)
+				t = netdev_priv(dev);
 		}
-		if (t == NULL)
-			t = netdev_priv(dev);
 		memset(&p, 0, sizeof(p));
 		ip6gre_tnl_parm_to_user(&p, &t->parms);
 		if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
@@ -1242,7 +1242,6 @@
 	dev->flags |= IFF_NOARP;
 	dev->iflink = 0;
 	dev->addr_len = sizeof(struct in6_addr);
-	dev->features |= NETIF_F_NETNS_LOCAL;
 	dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 }
 
@@ -1297,11 +1296,17 @@
 	.flags       = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
-static void ip6gre_destroy_tunnels(struct ip6gre_net *ign,
-	struct list_head *head)
+static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
 {
+	struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
+	struct net_device *dev, *aux;
 	int prio;
 
+	for_each_netdev_safe(net, dev, aux)
+		if (dev->rtnl_link_ops == &ip6gre_link_ops ||
+		    dev->rtnl_link_ops == &ip6gre_tap_ops)
+			unregister_netdevice_queue(dev, head);
+
 	for (prio = 0; prio < 4; prio++) {
 		int h;
 		for (h = 0; h < HASH_SIZE; h++) {
@@ -1310,7 +1315,12 @@
 			t = rtnl_dereference(ign->tunnels[prio][h]);
 
 			while (t != NULL) {
-				unregister_netdevice_queue(t->dev, head);
+				/* If dev is in the same netns, it has already
+				 * been added to the list by the previous loop.
+				 */
+				if (!net_eq(dev_net(t->dev), net))
+					unregister_netdevice_queue(t->dev,
+								   head);
 				t = rtnl_dereference(t->next);
 			}
 		}
@@ -1329,6 +1339,11 @@
 		goto err_alloc_dev;
 	}
 	dev_net_set(ign->fb_tunnel_dev, net);
+	/* FB netdevice is special: we have one, and only one per netns.
+	 * Allowing to move it to another netns is clearly unsafe.
+	 */
+	ign->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
+
 
 	ip6gre_fb_tunnel_init(ign->fb_tunnel_dev);
 	ign->fb_tunnel_dev->rtnl_link_ops = &ip6gre_link_ops;
@@ -1349,12 +1364,10 @@
 
 static void __net_exit ip6gre_exit_net(struct net *net)
 {
-	struct ip6gre_net *ign;
 	LIST_HEAD(list);
 
-	ign = net_generic(net, ip6gre_net_id);
 	rtnl_lock();
-	ip6gre_destroy_tunnels(ign, &list);
+	ip6gre_destroy_tunnels(net, &list);
 	unregister_netdevice_many(&list);
 	rtnl_unlock();
 }
@@ -1531,15 +1544,14 @@
 static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
 			    struct nlattr *data[])
 {
-	struct ip6_tnl *t, *nt;
-	struct net *net = dev_net(dev);
+	struct ip6_tnl *t, *nt = netdev_priv(dev);
+	struct net *net = nt->net;
 	struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
 	struct __ip6_tnl_parm p;
 
 	if (dev == ign->fb_tunnel_dev)
 		return -EINVAL;
 
-	nt = netdev_priv(dev);
 	ip6gre_netlink_parms(data, &p);
 
 	t = ip6gre_tunnel_locate(net, &p, 0);
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index bda7429..a2a1d80 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -168,12 +168,7 @@
 	pfh.wcheck = 0;
 	pfh.family = AF_INET6;
 
-	if (ipv6_addr_is_multicast(&fl6.daddr))
-		hlimit = np->mcast_hops;
-	else
-		hlimit = np->hop_limit;
-	if (hlimit < 0)
-		hlimit = ip6_dst_hoplimit(dst);
+	hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
 	lock_sock(sk);
 	err = ip6_append_data(sk, ping_getfrag, &pfh, len,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 1f29996..dddfb5f 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -873,14 +873,8 @@
 		err = PTR_ERR(dst);
 		goto out;
 	}
-	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl6.daddr))
-			hlimit = np->mcast_hops;
-		else
-			hlimit = np->hop_limit;
-		if (hlimit < 0)
-			hlimit = ip6_dst_hoplimit(dst);
-	}
+	if (hlimit < 0)
+		hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
 	if (tclass < 0)
 		tclass = np->tclass;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 1e586d9..d8d6ca0 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1232,14 +1232,8 @@
 		goto out;
 	}
 
-	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl6.daddr))
-			hlimit = np->mcast_hops;
-		else
-			hlimit = np->hop_limit;
-		if (hlimit < 0)
-			hlimit = ip6_dst_hoplimit(dst);
-	}
+	if (hlimit < 0)
+		hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
 	if (tclass < 0)
 		tclass = np->tclass;
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 7704ea9..e472d44 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -605,14 +605,8 @@
 		goto out;
 	}
 
-	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl6.daddr))
-			hlimit = np->mcast_hops;
-		else
-			hlimit = np->hop_limit;
-		if (hlimit < 0)
-			hlimit = ip6_dst_hoplimit(dst);
-	}
+	if (hlimit < 0)
+		hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
 	if (tclass < 0)
 		tclass = np->tclass;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index e8138da..6e42dcf 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -400,19 +400,17 @@
 }
 
 #ifdef CONFIG_MODULES
-static void nfnetlink_bind(int group)
+static int nfnetlink_bind(int group)
 {
 	const struct nfnetlink_subsystem *ss;
 	int type = nfnl_group2type[group];
 
 	rcu_read_lock();
 	ss = nfnetlink_get_subsys(type);
-	if (!ss) {
-		rcu_read_unlock();
-		request_module("nfnetlink-subsys-%d", type);
-		return;
-	}
 	rcu_read_unlock();
+	if (!ss)
+		request_module("nfnetlink-subsys-%d", type);
+	return 0;
 }
 #endif
 
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 894cda0..92f4b69 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1206,7 +1206,8 @@
 	struct module *module = NULL;
 	struct mutex *cb_mutex;
 	struct netlink_sock *nlk;
-	void (*bind)(int group);
+	int (*bind)(int group);
+	void (*unbind)(int group);
 	int err = 0;
 
 	sock->state = SS_UNCONNECTED;
@@ -1232,6 +1233,7 @@
 		err = -EPROTONOSUPPORT;
 	cb_mutex = nl_table[protocol].cb_mutex;
 	bind = nl_table[protocol].bind;
+	unbind = nl_table[protocol].unbind;
 	netlink_unlock_table();
 
 	if (err < 0)
@@ -1248,6 +1250,7 @@
 	nlk = nlk_sk(sock->sk);
 	nlk->module = module;
 	nlk->netlink_bind = bind;
+	nlk->netlink_unbind = unbind;
 out:
 	return err;
 
@@ -1301,6 +1304,7 @@
 			kfree_rcu(old, rcu);
 			nl_table[sk->sk_protocol].module = NULL;
 			nl_table[sk->sk_protocol].bind = NULL;
+			nl_table[sk->sk_protocol].unbind = NULL;
 			nl_table[sk->sk_protocol].flags = 0;
 			nl_table[sk->sk_protocol].registered = 0;
 		}
@@ -1411,6 +1415,19 @@
 	return err;
 }
 
+static void netlink_unbind(int group, long unsigned int groups,
+			   struct netlink_sock *nlk)
+{
+	int undo;
+
+	if (!nlk->netlink_unbind)
+		return;
+
+	for (undo = 0; undo < group; undo++)
+		if (test_bit(group, &groups))
+			nlk->netlink_unbind(undo);
+}
+
 static int netlink_bind(struct socket *sock, struct sockaddr *addr,
 			int addr_len)
 {
@@ -1419,6 +1436,7 @@
 	struct netlink_sock *nlk = nlk_sk(sk);
 	struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
 	int err;
+	long unsigned int groups = nladdr->nl_groups;
 
 	if (addr_len < sizeof(struct sockaddr_nl))
 		return -EINVAL;
@@ -1427,7 +1445,7 @@
 		return -EINVAL;
 
 	/* Only superuser is allowed to listen multicasts */
-	if (nladdr->nl_groups) {
+	if (groups) {
 		if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
 			return -EPERM;
 		err = netlink_realloc_groups(sk);
@@ -1435,37 +1453,45 @@
 			return err;
 	}
 
-	if (nlk->portid) {
+	if (nlk->portid)
 		if (nladdr->nl_pid != nlk->portid)
 			return -EINVAL;
-	} else {
+
+	if (nlk->netlink_bind && groups) {
+		int group;
+
+		for (group = 0; group < nlk->ngroups; group++) {
+			if (!test_bit(group, &groups))
+				continue;
+			err = nlk->netlink_bind(group);
+			if (!err)
+				continue;
+			netlink_unbind(group, groups, nlk);
+			return err;
+		}
+	}
+
+	if (!nlk->portid) {
 		err = nladdr->nl_pid ?
 			netlink_insert(sk, net, nladdr->nl_pid) :
 			netlink_autobind(sock);
-		if (err)
+		if (err) {
+			netlink_unbind(nlk->ngroups - 1, groups, nlk);
 			return err;
+		}
 	}
 
-	if (!nladdr->nl_groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
+	if (!groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
 		return 0;
 
 	netlink_table_grab();
 	netlink_update_subscriptions(sk, nlk->subscriptions +
-					 hweight32(nladdr->nl_groups) -
+					 hweight32(groups) -
 					 hweight32(nlk->groups[0]));
-	nlk->groups[0] = (nlk->groups[0] & ~0xffffffffUL) | nladdr->nl_groups;
+	nlk->groups[0] = (nlk->groups[0] & ~0xffffffffUL) | groups;
 	netlink_update_listeners(sk);
 	netlink_table_ungrab();
 
-	if (nlk->netlink_bind && nlk->groups[0]) {
-		int i;
-
-		for (i = 0; i < nlk->ngroups; i++) {
-			if (test_bit(i, nlk->groups))
-				nlk->netlink_bind(i);
-		}
-	}
-
 	return 0;
 }
 
@@ -2103,13 +2129,17 @@
 			return err;
 		if (!val || val - 1 >= nlk->ngroups)
 			return -EINVAL;
+		if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
+			err = nlk->netlink_bind(val);
+			if (err)
+				return err;
+		}
 		netlink_table_grab();
 		netlink_update_socket_mc(nlk, val,
 					 optname == NETLINK_ADD_MEMBERSHIP);
 		netlink_table_ungrab();
-
-		if (nlk->netlink_bind)
-			nlk->netlink_bind(val);
+		if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
+			nlk->netlink_unbind(val);
 
 		err = 0;
 		break;
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index ed13a79..0b59d44 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -38,7 +38,8 @@
 	struct mutex		*cb_mutex;
 	struct mutex		cb_def_mutex;
 	void			(*netlink_rcv)(struct sk_buff *skb);
-	void			(*netlink_bind)(int group);
+	int			(*netlink_bind)(int group);
+	void			(*netlink_unbind)(int group);
 	struct module		*module;
 #ifdef CONFIG_NETLINK_MMAP
 	struct mutex		pg_vec_lock;
@@ -74,7 +75,8 @@
 	unsigned int		groups;
 	struct mutex		*cb_mutex;
 	struct module		*module;
-	void			(*bind)(int group);
+	int			(*bind)(int group);
+	void			(*unbind)(int group);
 	bool			(*compare)(struct net *net, struct sock *sock);
 	int			registered;
 };
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index e797a50..21cceb3 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -180,7 +180,8 @@
 			     OVS_CB(skb)->tun_key->ipv4_tos,
 			     OVS_CB(skb)->tun_key->ipv4_ttl, df,
 			     src_port, dst_port,
-			     htonl(be64_to_cpu(OVS_CB(skb)->tun_key->tun_id) << 8));
+			     htonl(be64_to_cpu(OVS_CB(skb)->tun_key->tun_id) << 8),
+			     false);
 	if (err < 0)
 		ip_rt_put(rt);
 error:
diff --git a/net/packet/diag.c b/net/packet/diag.c
index 533ce4f..435ff99 100644
--- a/net/packet/diag.c
+++ b/net/packet/diag.c
@@ -172,7 +172,7 @@
 		goto out_nlmsg_trim;
 
 	if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
-	    sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER))
+	    sock_diag_put_filterinfo(sk, skb, PACKET_DIAG_FILTER))
 		goto out_nlmsg_trim;
 
 	return nlmsg_end(skb, nlh);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 29a30a1..a481bbe 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -317,7 +317,8 @@
 		}
 	}
 
-	err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh);
+	err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
+			      n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE : TCA_ACT_REPLACE);
 	if (err == 0) {
 		if (tp_created) {
 			spin_lock_bh(root_lock);
@@ -504,7 +505,7 @@
 EXPORT_SYMBOL(tcf_exts_destroy);
 
 int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
-		  struct nlattr *rate_tlv, struct tcf_exts *exts)
+		  struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	{
@@ -513,7 +514,7 @@
 		INIT_LIST_HEAD(&exts->actions);
 		if (exts->police && tb[exts->police]) {
 			act = tcf_action_init_1(net, tb[exts->police], rate_tlv,
-						"police", TCA_ACT_NOREPLACE,
+						"police", ovr,
 						TCA_ACT_BIND);
 			if (IS_ERR(act))
 				return PTR_ERR(act);
@@ -523,7 +524,7 @@
 		} else if (exts->action && tb[exts->action]) {
 			int err;
 			err = tcf_action_init(net, tb[exts->action], rate_tlv,
-					      NULL, TCA_ACT_NOREPLACE,
+					      NULL, ovr,
 					      TCA_ACT_BIND, &exts->actions);
 			if (err)
 				return err;
@@ -543,14 +544,12 @@
 		     struct tcf_exts *src)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	if (!list_empty(&src->actions)) {
-		LIST_HEAD(tmp);
-		tcf_tree_lock(tp);
-		list_splice_init(&dst->actions, &tmp);
-		list_splice(&src->actions, &dst->actions);
-		tcf_tree_unlock(tp);
-		tcf_action_destroy(&tmp, TCA_ACT_UNBIND);
-	}
+	LIST_HEAD(tmp);
+	tcf_tree_lock(tp);
+	list_splice_init(&dst->actions, &tmp);
+	list_splice(&src->actions, &dst->actions);
+	tcf_tree_unlock(tp);
+	tcf_action_destroy(&tmp, TCA_ACT_UNBIND);
 #endif
 }
 EXPORT_SYMBOL(tcf_exts_change);
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index e98ca99..0ae1813 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -130,14 +130,14 @@
 static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 			   struct basic_filter *f, unsigned long base,
 			   struct nlattr **tb,
-			   struct nlattr *est)
+			   struct nlattr *est, bool ovr)
 {
 	int err;
 	struct tcf_exts e;
 	struct tcf_ematch_tree t;
 
 	tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e);
+	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		return err;
 
@@ -161,7 +161,7 @@
 
 static int basic_change(struct net *net, struct sk_buff *in_skb,
 			struct tcf_proto *tp, unsigned long base, u32 handle,
-			struct nlattr **tca, unsigned long *arg)
+			struct nlattr **tca, unsigned long *arg, bool ovr)
 {
 	int err;
 	struct basic_head *head = tp->root;
@@ -179,7 +179,7 @@
 	if (f != NULL) {
 		if (handle && f->handle != handle)
 			return -EINVAL;
-		return basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE]);
+		return basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr);
 	}
 
 	err = -ENOBUFS;
@@ -206,7 +206,7 @@
 		f->handle = head->hgenerator;
 	}
 
-	err = basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE]);
+	err = basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 8e3cf49..1618696 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -156,7 +156,7 @@
 static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
 				   struct cls_bpf_prog *prog,
 				   unsigned long base, struct nlattr **tb,
-				   struct nlattr *est)
+				   struct nlattr *est, bool ovr)
 {
 	struct sock_filter *bpf_ops, *bpf_old;
 	struct tcf_exts exts;
@@ -170,7 +170,7 @@
 		return -EINVAL;
 
 	tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
-	ret = tcf_exts_validate(net, tp, tb, est, &exts);
+	ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
 	if (ret < 0)
 		return ret;
 
@@ -242,7 +242,7 @@
 static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
 			  struct tcf_proto *tp, unsigned long base,
 			  u32 handle, struct nlattr **tca,
-			  unsigned long *arg)
+			  unsigned long *arg, bool ovr)
 {
 	struct cls_bpf_head *head = tp->root;
 	struct cls_bpf_prog *prog = (struct cls_bpf_prog *) *arg;
@@ -260,7 +260,7 @@
 		if (handle && prog->handle != handle)
 			return -EINVAL;
 		return cls_bpf_modify_existing(net, tp, prog, base, tb,
-					       tca[TCA_RATE]);
+					       tca[TCA_RATE], ovr);
 	}
 
 	prog = kzalloc(sizeof(*prog), GFP_KERNEL);
@@ -277,7 +277,7 @@
 		goto errout;
 	}
 
-	ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE]);
+	ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE], ovr);
 	if (ret < 0)
 		goto errout;
 
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 8e2158a..cacf01b 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -83,7 +83,7 @@
 static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 			     struct tcf_proto *tp, unsigned long base,
 			     u32 handle, struct nlattr **tca,
-			     unsigned long *arg)
+			     unsigned long *arg, bool ovr)
 {
 	struct nlattr *tb[TCA_CGROUP_MAX + 1];
 	struct cls_cgroup_head *head = tp->root;
@@ -119,7 +119,7 @@
 		return err;
 
 	tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
 		return err;
 
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 257029c..35be16f 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -349,7 +349,7 @@
 static int flow_change(struct net *net, struct sk_buff *in_skb,
 		       struct tcf_proto *tp, unsigned long base,
 		       u32 handle, struct nlattr **tca,
-		       unsigned long *arg)
+		       unsigned long *arg, bool ovr)
 {
 	struct flow_head *head = tp->root;
 	struct flow_filter *f;
@@ -393,7 +393,7 @@
 	}
 
 	tcf_exts_init(&e, TCA_FLOW_ACT, TCA_FLOW_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
 		return err;
 
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 63a3ce7..861b03c 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -169,7 +169,7 @@
 
 static int
 fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
-	struct nlattr **tb, struct nlattr **tca, unsigned long base)
+	struct nlattr **tb, struct nlattr **tca, unsigned long base, bool ovr)
 {
 	struct fw_head *head = tp->root;
 	struct tcf_exts e;
@@ -177,7 +177,7 @@
 	int err;
 
 	tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
 		return err;
 
@@ -218,7 +218,7 @@
 		     struct tcf_proto *tp, unsigned long base,
 		     u32 handle,
 		     struct nlattr **tca,
-		     unsigned long *arg)
+		     unsigned long *arg, bool ovr)
 {
 	struct fw_head *head = tp->root;
 	struct fw_filter *f = (struct fw_filter *) *arg;
@@ -236,7 +236,7 @@
 	if (f != NULL) {
 		if (f->id != handle && handle)
 			return -EINVAL;
-		return fw_change_attrs(net, tp, f, tb, tca, base);
+		return fw_change_attrs(net, tp, f, tb, tca, base, ovr);
 	}
 
 	if (!handle)
@@ -264,7 +264,7 @@
 	tcf_exts_init(&f->exts, TCA_FW_ACT, TCA_FW_POLICE);
 	f->id = handle;
 
-	err = fw_change_attrs(net, tp, f, tb, tca, base);
+	err = fw_change_attrs(net, tp, f, tb, tca, base, ovr);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 1ad3068..dd9fc25 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -333,7 +333,8 @@
 static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 			    unsigned long base, struct route4_filter *f,
 			    u32 handle, struct route4_head *head,
-			    struct nlattr **tb, struct nlattr *est, int new)
+			    struct nlattr **tb, struct nlattr *est, int new,
+			    bool ovr)
 {
 	int err;
 	u32 id = 0, to = 0, nhandle = 0x8000;
@@ -343,7 +344,7 @@
 	struct tcf_exts e;
 
 	tcf_exts_init(&e, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e);
+	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		return err;
 
@@ -428,7 +429,7 @@
 		       struct tcf_proto *tp, unsigned long base,
 		       u32 handle,
 		       struct nlattr **tca,
-		       unsigned long *arg)
+		       unsigned long *arg, bool ovr)
 {
 	struct route4_head *head = tp->root;
 	struct route4_filter *f, *f1, **fp;
@@ -455,7 +456,7 @@
 			old_handle = f->handle;
 
 		err = route4_set_parms(net, tp, base, f, handle, head, tb,
-			tca[TCA_RATE], 0);
+			tca[TCA_RATE], 0, ovr);
 		if (err < 0)
 			return err;
 
@@ -479,7 +480,7 @@
 
 	tcf_exts_init(&f->exts, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
 	err = route4_set_parms(net, tp, base, f, handle, head, tb,
-		tca[TCA_RATE], 1);
+		tca[TCA_RATE], 1, ovr);
 	if (err < 0)
 		goto errout;
 
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 19f8e5d..1020e23 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -415,7 +415,7 @@
 		       struct tcf_proto *tp, unsigned long base,
 		       u32 handle,
 		       struct nlattr **tca,
-		       unsigned long *arg)
+		       unsigned long *arg, bool ovr)
 {
 	struct rsvp_head *data = tp->root;
 	struct rsvp_filter *f, **fp;
@@ -436,7 +436,7 @@
 		return err;
 
 	tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
 		return err;
 
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index eed8404..d11d0a4 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -192,7 +192,7 @@
 tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 		  u32 handle, struct tcindex_data *p,
 		  struct tcindex_filter_result *r, struct nlattr **tb,
-		 struct nlattr *est)
+		  struct nlattr *est, bool ovr)
 {
 	int err, balloc = 0;
 	struct tcindex_filter_result new_filter_result, *old_r = r;
@@ -202,7 +202,7 @@
 	struct tcf_exts e;
 
 	tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e);
+	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		return err;
 
@@ -331,7 +331,7 @@
 static int
 tcindex_change(struct net *net, struct sk_buff *in_skb,
 	       struct tcf_proto *tp, unsigned long base, u32 handle,
-	       struct nlattr **tca, unsigned long *arg)
+	       struct nlattr **tca, unsigned long *arg, bool ovr)
 {
 	struct nlattr *opt = tca[TCA_OPTIONS];
 	struct nlattr *tb[TCA_TCINDEX_MAX + 1];
@@ -351,7 +351,7 @@
 		return err;
 
 	return tcindex_set_parms(net, tp, base, handle, p, r, tb,
-				 tca[TCA_RATE]);
+				 tca[TCA_RATE], ovr);
 }
 
 
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 84c28da..c39b583 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -486,13 +486,13 @@
 static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 			 unsigned long base, struct tc_u_hnode *ht,
 			 struct tc_u_knode *n, struct nlattr **tb,
-			 struct nlattr *est)
+			 struct nlattr *est, bool ovr)
 {
 	int err;
 	struct tcf_exts e;
 
 	tcf_exts_init(&e, TCA_U32_ACT, TCA_U32_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e);
+	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		return err;
 
@@ -545,7 +545,7 @@
 static int u32_change(struct net *net, struct sk_buff *in_skb,
 		      struct tcf_proto *tp, unsigned long base, u32 handle,
 		      struct nlattr **tca,
-		      unsigned long *arg)
+		      unsigned long *arg, bool ovr)
 {
 	struct tc_u_common *tp_c = tp->data;
 	struct tc_u_hnode *ht;
@@ -569,7 +569,7 @@
 			return -EINVAL;
 
 		return u32_set_parms(net, tp, base, n->ht_up, n, tb,
-				     tca[TCA_RATE]);
+				     tca[TCA_RATE], ovr);
 	}
 
 	if (tb[TCA_U32_DIVISOR]) {
@@ -656,7 +656,7 @@
 	}
 #endif
 
-	err = u32_set_parms(net, tp, base, ht, n, tb, tca[TCA_RATE]);
+	err = u32_set_parms(net, tp, base, ht, n, tb, tca[TCA_RATE], ovr);
 	if (err == 0) {
 		struct tc_u_knode **ins;
 		for (ins = &ht->ht[TC_U32_HASH(handle)]; *ins; ins = &(*ins)->next)
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 683c7d1..0e85291 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -386,14 +386,13 @@
  */
 int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
 {
-	struct net *net = sock_net(asoc->base.sk);
 	struct sctp_auth_bytes	*secret;
 	struct sctp_shared_key *ep_key;
 
 	/* If we don't support AUTH, or peer is not capable
 	 * we don't need to do anything.
 	 */
-	if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
+	if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
 		return 0;
 
 	/* If the key_id is non-zero and we couldn't find an
@@ -440,16 +439,16 @@
  */
 int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
 {
-	struct net *net = sock_net(ep->base.sk);
 	struct crypto_hash *tfm = NULL;
 	__u16   id;
 
-	/* if the transforms are already allocted, we are done */
-	if (!net->sctp.auth_enable) {
+	/* If AUTH extension is disabled, we are done */
+	if (!ep->auth_enable) {
 		ep->auth_hmacs = NULL;
 		return 0;
 	}
 
+	/* If the transforms are already allocated, we are done */
 	if (ep->auth_hmacs)
 		return 0;
 
@@ -665,12 +664,10 @@
 /* Check if peer requested that this chunk is authenticated */
 int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
 {
-	struct net  *net;
 	if (!asoc)
 		return 0;
 
-	net = sock_net(asoc->base.sk);
-	if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
+	if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
 		return 0;
 
 	return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
@@ -679,12 +676,10 @@
 /* Check if we requested that peer authenticate this chunk. */
 int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
 {
-	struct net *net;
 	if (!asoc)
 		return 0;
 
-	net = sock_net(asoc->base.sk);
-	if (!net->sctp.auth_enable)
+	if (!asoc->ep->auth_enable)
 		return 0;
 
 	return __sctp_auth_cid(chunk,
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 8e5fdea..3d9f429 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -68,7 +68,8 @@
 	if (!ep->digest)
 		return NULL;
 
-	if (net->sctp.auth_enable) {
+	ep->auth_enable = net->sctp.auth_enable;
+	if (ep->auth_enable) {
 		/* Allocate space for HMACS and CHUNKS authentication
 		 * variables.  There are arrays that we encode directly
 		 * into parameters to make the rest of the operations easier.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 3a1767e..fee5552 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -219,6 +219,7 @@
 			     gfp_t gfp, int vparam_len)
 {
 	struct net *net = sock_net(asoc->base.sk);
+	struct sctp_endpoint *ep = asoc->ep;
 	sctp_inithdr_t init;
 	union sctp_params addrs;
 	size_t chunksize;
@@ -278,7 +279,7 @@
 	chunksize += vparam_len;
 
 	/* Account for AUTH related parameters */
-	if (net->sctp.auth_enable) {
+	if (ep->auth_enable) {
 		/* Add random parameter length*/
 		chunksize += sizeof(asoc->c.auth_random);
 
@@ -363,7 +364,7 @@
 	}
 
 	/* Add SCTP-AUTH chunks to the parameter list */
-	if (net->sctp.auth_enable) {
+	if (ep->auth_enable) {
 		sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),
 				 asoc->c.auth_random);
 		if (auth_hmacs)
@@ -2010,7 +2011,7 @@
 			/* if the peer reports AUTH, assume that he
 			 * supports AUTH.
 			 */
-			if (net->sctp.auth_enable)
+			if (asoc->ep->auth_enable)
 				asoc->peer.auth_capable = 1;
 			break;
 		case SCTP_CID_ASCONF:
@@ -2102,6 +2103,7 @@
  * 	SCTP_IERROR_NO_ERROR - continue with the chunk
  */
 static sctp_ierror_t sctp_verify_param(struct net *net,
+					const struct sctp_endpoint *ep,
 					const struct sctp_association *asoc,
 					union sctp_params param,
 					sctp_cid_t cid,
@@ -2152,7 +2154,7 @@
 		goto fallthrough;
 
 	case SCTP_PARAM_RANDOM:
-		if (!net->sctp.auth_enable)
+		if (!ep->auth_enable)
 			goto fallthrough;
 
 		/* SCTP-AUTH: Secion 6.1
@@ -2169,7 +2171,7 @@
 		break;
 
 	case SCTP_PARAM_CHUNKS:
-		if (!net->sctp.auth_enable)
+		if (!ep->auth_enable)
 			goto fallthrough;
 
 		/* SCTP-AUTH: Section 3.2
@@ -2185,7 +2187,7 @@
 		break;
 
 	case SCTP_PARAM_HMAC_ALGO:
-		if (!net->sctp.auth_enable)
+		if (!ep->auth_enable)
 			goto fallthrough;
 
 		hmacs = (struct sctp_hmac_algo_param *)param.p;
@@ -2220,10 +2222,9 @@
 }
 
 /* Verify the INIT packet before we process it.  */
-int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
-		     sctp_cid_t cid,
-		     sctp_init_chunk_t *peer_init,
-		     struct sctp_chunk *chunk,
+int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
+		     const struct sctp_association *asoc, sctp_cid_t cid,
+		     sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,
 		     struct sctp_chunk **errp)
 {
 	union sctp_params param;
@@ -2264,8 +2265,8 @@
 
 	/* Verify all the variable length parameters */
 	sctp_walk_params(param, peer_init, init_hdr.params) {
-
-		result = sctp_verify_param(net, asoc, param, cid, chunk, errp);
+		result = sctp_verify_param(net, ep, asoc, param, cid,
+					   chunk, errp);
 		switch (result) {
 		case SCTP_IERROR_ABORT:
 		case SCTP_IERROR_NOMEM:
@@ -2497,6 +2498,7 @@
 	struct sctp_af *af;
 	union sctp_addr_param *addr_param;
 	struct sctp_transport *t;
+	struct sctp_endpoint *ep = asoc->ep;
 
 	/* We maintain all INIT parameters in network byte order all the
 	 * time.  This allows us to not worry about whether the parameters
@@ -2636,7 +2638,7 @@
 		goto fall_through;
 
 	case SCTP_PARAM_RANDOM:
-		if (!net->sctp.auth_enable)
+		if (!ep->auth_enable)
 			goto fall_through;
 
 		/* Save peer's random parameter */
@@ -2649,7 +2651,7 @@
 		break;
 
 	case SCTP_PARAM_HMAC_ALGO:
-		if (!net->sctp.auth_enable)
+		if (!ep->auth_enable)
 			goto fall_through;
 
 		/* Save peer's HMAC list */
@@ -2665,7 +2667,7 @@
 		break;
 
 	case SCTP_PARAM_CHUNKS:
-		if (!net->sctp.auth_enable)
+		if (!ep->auth_enable)
 			goto fall_through;
 
 		asoc->peer.peer_chunks = kmemdup(param.p,
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index ae9fbeb..5170a1f 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -357,7 +357,7 @@
 
 	/* Verify the INIT chunk before processing it. */
 	err_chunk = NULL;
-	if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+	if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
 			      (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
 			      &err_chunk)) {
 		/* This chunk contains fatal error. It is to be discarded.
@@ -524,7 +524,7 @@
 
 	/* Verify the INIT chunk before processing it. */
 	err_chunk = NULL;
-	if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+	if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
 			      (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
 			      &err_chunk)) {
 
@@ -1430,7 +1430,7 @@
 
 	/* Verify the INIT chunk before processing it. */
 	err_chunk = NULL;
-	if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+	if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
 			      (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
 			      &err_chunk)) {
 		/* This chunk contains fatal error. It is to be discarded.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff20e2d..e37b2cb 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -71,6 +71,7 @@
 #include <net/route.h>
 #include <net/ipv6.h>
 #include <net/inet_common.h>
+#include <net/busy_poll.h>
 
 #include <linux/socket.h> /* for sa_family_t */
 #include <linux/export.h>
@@ -3321,10 +3322,10 @@
 				      char __user *optval,
 				      unsigned int optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_authchunk val;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (optlen != sizeof(struct sctp_authchunk))
@@ -3341,7 +3342,7 @@
 	}
 
 	/* add this chunk id to the endpoint */
-	return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk);
+	return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk);
 }
 
 /*
@@ -3354,12 +3355,12 @@
 				      char __user *optval,
 				      unsigned int optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_hmacalgo *hmacs;
 	u32 idents;
 	int err;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (optlen < sizeof(struct sctp_hmacalgo))
@@ -3376,7 +3377,7 @@
 		goto out;
 	}
 
-	err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs);
+	err = sctp_auth_ep_set_hmacs(ep, hmacs);
 out:
 	kfree(hmacs);
 	return err;
@@ -3392,12 +3393,12 @@
 				    char __user *optval,
 				    unsigned int optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_authkey *authkey;
 	struct sctp_association *asoc;
 	int ret;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (optlen <= sizeof(struct sctp_authkey))
@@ -3418,7 +3419,7 @@
 		goto out;
 	}
 
-	ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey);
+	ret = sctp_auth_set_key(ep, asoc, authkey);
 out:
 	kzfree(authkey);
 	return ret;
@@ -3434,11 +3435,11 @@
 				      char __user *optval,
 				      unsigned int optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_authkeyid val;
 	struct sctp_association *asoc;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (optlen != sizeof(struct sctp_authkeyid))
@@ -3450,8 +3451,7 @@
 	if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
 		return -EINVAL;
 
-	return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc,
-					val.scact_keynumber);
+	return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber);
 }
 
 /*
@@ -3463,11 +3463,11 @@
 				   char __user *optval,
 				   unsigned int optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_authkeyid val;
 	struct sctp_association *asoc;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (optlen != sizeof(struct sctp_authkeyid))
@@ -3479,8 +3479,7 @@
 	if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
 		return -EINVAL;
 
-	return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc,
-				    val.scact_keynumber);
+	return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber);
 
 }
 
@@ -5387,16 +5386,16 @@
 static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
 				    char __user *optval, int __user *optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_hmacalgo  __user *p = (void __user *)optval;
 	struct sctp_hmac_algo_param *hmacs;
 	__u16 data_len = 0;
 	u32 num_idents;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
-	hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
+	hmacs = ep->auth_hmacs_list;
 	data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
 
 	if (len < sizeof(struct sctp_hmacalgo) + data_len)
@@ -5417,11 +5416,11 @@
 static int sctp_getsockopt_active_key(struct sock *sk, int len,
 				    char __user *optval, int __user *optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_authkeyid val;
 	struct sctp_association *asoc;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (len < sizeof(struct sctp_authkeyid))
@@ -5436,7 +5435,7 @@
 	if (asoc)
 		val.scact_keynumber = asoc->active_key_id;
 	else
-		val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
+		val.scact_keynumber = ep->active_key_id;
 
 	len = sizeof(struct sctp_authkeyid);
 	if (put_user(len, optlen))
@@ -5450,7 +5449,7 @@
 static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
 				    char __user *optval, int __user *optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_authchunks __user *p = (void __user *)optval;
 	struct sctp_authchunks val;
 	struct sctp_association *asoc;
@@ -5458,7 +5457,7 @@
 	u32    num_chunks = 0;
 	char __user *to;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (len < sizeof(struct sctp_authchunks))
@@ -5495,7 +5494,7 @@
 static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
 				    char __user *optval, int __user *optlen)
 {
-	struct net *net = sock_net(sk);
+	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
 	struct sctp_authchunks __user *p = (void __user *)optval;
 	struct sctp_authchunks val;
 	struct sctp_association *asoc;
@@ -5503,7 +5502,7 @@
 	u32    num_chunks = 0;
 	char __user *to;
 
-	if (!net->sctp.auth_enable)
+	if (!ep->auth_enable)
 		return -EACCES;
 
 	if (len < sizeof(struct sctp_authchunks))
@@ -5520,7 +5519,7 @@
 	if (asoc)
 		ch = (struct sctp_chunks_param *)asoc->c.auth_chunks;
 	else
-		ch = sctp_sk(sk)->ep->auth_chunk_list;
+		ch = ep->auth_chunk_list;
 
 	if (!ch)
 		goto num;
@@ -6559,6 +6558,10 @@
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
 
+		if (sk_can_busy_loop(sk) &&
+		    sk_busy_loop(sk, noblock))
+			continue;
+
 		/* User doesn't want to wait.  */
 		error = -EAGAIN;
 		if (!timeo)
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 35c8923..c82fdc1 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -64,6 +64,9 @@
 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
 				void __user *buffer, size_t *lenp,
 				loff_t *ppos);
+static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
+			     void __user *buffer, size_t *lenp,
+			     loff_t *ppos);
 
 static struct ctl_table sctp_table[] = {
 	{
@@ -266,7 +269,7 @@
 		.data		= &init_net.sctp.auth_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_sctp_do_auth,
 	},
 	{
 		.procname	= "addr_scope_policy",
@@ -400,6 +403,37 @@
 	return ret;
 }
 
+static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
+			     void __user *buffer, size_t *lenp,
+			     loff_t *ppos)
+{
+	struct net *net = current->nsproxy->net_ns;
+	struct ctl_table tbl;
+	int new_value, ret;
+
+	memset(&tbl, 0, sizeof(struct ctl_table));
+	tbl.maxlen = sizeof(unsigned int);
+
+	if (write)
+		tbl.data = &new_value;
+	else
+		tbl.data = &net->sctp.auth_enable;
+
+	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
+
+	if (write) {
+		struct sock *sk = net->sctp.ctl_sock;
+
+		net->sctp.auth_enable = new_value;
+		/* Update the value in the control socket */
+		lock_sock(sk);
+		sctp_sk(sk)->ep->auth_enable = new_value;
+		release_sock(sk);
+	}
+
+	return ret;
+}
+
 int sctp_sysctl_net_register(struct net *net)
 {
 	struct ctl_table *table = sctp_net_table;
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 7144eb6..d49dc2ed 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -38,6 +38,7 @@
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
+#include <net/busy_poll.h>
 #include <net/sctp/structs.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
@@ -204,6 +205,9 @@
 	if (sock_flag(sk, SOCK_DEAD) || (sk->sk_shutdown & RCV_SHUTDOWN))
 		goto out_free;
 
+	if (!sctp_ulpevent_is_notification(event))
+		sk_mark_napi_id(sk, skb);
+
 	/* Check if the user wishes to receive this event.  */
 	if (!sctp_ulpevent_is_enabled(event, &sctp_sk(sk)->subscribe))
 		goto out_free;
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 95ab5ef..119a59b 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -112,6 +112,8 @@
 static void tipc_nmap_diff(struct tipc_node_map *nm_a,
 			   struct tipc_node_map *nm_b,
 			   struct tipc_node_map *nm_diff);
+static void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node);
+static void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
 
 static u32 bcbuf_acks(struct sk_buff *buf)
 {
@@ -273,7 +275,7 @@
 /**
  * tipc_bclink_update_link_state - update broadcast link state
  *
- * tipc_net_lock and node lock set
+ * RCU and node lock set
  */
 void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
 {
@@ -321,7 +323,7 @@
 				 : n_ptr->bclink.last_sent);
 
 		spin_lock_bh(&bc_lock);
-		tipc_bearer_send(&bcbearer->bearer, buf, NULL);
+		tipc_bearer_send(MAX_BEARERS, buf, NULL);
 		bcl->stats.sent_nacks++;
 		spin_unlock_bh(&bc_lock);
 		kfree_skb(buf);
@@ -335,8 +337,6 @@
  *
  * Delay any upcoming NACK by this node if another node has already
  * requested the first message this node is going to ask for.
- *
- * Only tipc_net_lock set.
  */
 static void bclink_peek_nack(struct tipc_msg *msg)
 {
@@ -408,7 +408,7 @@
 /**
  * tipc_bclink_rcv - receive a broadcast packet, and deliver upwards
  *
- * tipc_net_lock is read_locked, no other locks set
+ * RCU is locked, no other locks set
  */
 void tipc_bclink_rcv(struct sk_buff *buf)
 {
@@ -627,13 +627,13 @@
 
 		if (bp_index == 0) {
 			/* Use original buffer for first bearer */
-			tipc_bearer_send(b, buf, &b->bcast_addr);
+			tipc_bearer_send(b->identity, buf, &b->bcast_addr);
 		} else {
 			/* Avoid concurrent buffer access */
 			tbuf = pskb_copy(buf, GFP_ATOMIC);
 			if (!tbuf)
 				break;
-			tipc_bearer_send(b, tbuf, &b->bcast_addr);
+			tipc_bearer_send(b->identity, tbuf, &b->bcast_addr);
 			kfree_skb(tbuf); /* Bearer keeps a clone */
 		}
 
@@ -655,20 +655,27 @@
 /**
  * tipc_bcbearer_sort - create sets of bearer pairs used by broadcast bearer
  */
-void tipc_bcbearer_sort(void)
+void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action)
 {
 	struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp;
 	struct tipc_bcbearer_pair *bp_curr;
+	struct tipc_bearer *b;
 	int b_index;
 	int pri;
 
 	spin_lock_bh(&bc_lock);
 
+	if (action)
+		tipc_nmap_add(nm_ptr, node);
+	else
+		tipc_nmap_remove(nm_ptr, node);
+
 	/* Group bearers by priority (can assume max of two per priority) */
 	memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
 
+	rcu_read_lock();
 	for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
-		struct tipc_bearer *b = bearer_list[b_index];
+		b = rcu_dereference_rtnl(bearer_list[b_index]);
 		if (!b || !b->nodes.count)
 			continue;
 
@@ -677,6 +684,7 @@
 		else
 			bp_temp[b->priority].secondary = b;
 	}
+	rcu_read_unlock();
 
 	/* Create array of bearer pairs for broadcasting */
 	bp_curr = bcbearer->bpairs;
@@ -783,8 +791,8 @@
 	bcl->owner = &bclink->node;
 	bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
 	tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
-	bcl->b_ptr = &bcbearer->bearer;
-	bearer_list[BCBEARER] = &bcbearer->bearer;
+	bcl->bearer_id = MAX_BEARERS;
+	rcu_assign_pointer(bearer_list[MAX_BEARERS], &bcbearer->bearer);
 	bcl->state = WORKING_WORKING;
 	strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
 }
@@ -795,16 +803,15 @@
 	tipc_link_purge_queues(bcl);
 	spin_unlock_bh(&bc_lock);
 
-	bearer_list[BCBEARER] = NULL;
+	RCU_INIT_POINTER(bearer_list[BCBEARER], NULL);
 	memset(bclink, 0, sizeof(*bclink));
 	memset(bcbearer, 0, sizeof(*bcbearer));
 }
 
-
 /**
  * tipc_nmap_add - add a node to a node map
  */
-void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
+static void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
 {
 	int n = tipc_node(node);
 	int w = n / WSIZE;
@@ -819,7 +826,7 @@
 /**
  * tipc_nmap_remove - remove a node from a node map
  */
-void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
+static void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
 {
 	int n = tipc_node(node);
 	int w = n / WSIZE;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index a80ef54..7c1ef1b 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -69,9 +69,6 @@
 
 extern const char tipc_bclink_name[];
 
-void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node);
-void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
-
 /**
  * tipc_nmap_equal - test for equality of node maps
  */
@@ -98,6 +95,6 @@
 int  tipc_bclink_stats(char *stats_buf, const u32 buf_size);
 int  tipc_bclink_reset_stats(void);
 int  tipc_bclink_set_queue_limits(u32 limit);
-void tipc_bcbearer_sort(void);
+void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
 
 #endif
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 3fef7eb..f3259d4 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -49,7 +49,7 @@
 	NULL
 };
 
-struct tipc_bearer *bearer_list[MAX_BEARERS + 1];
+struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
 
 static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);
 
@@ -178,7 +178,7 @@
 	u32 i;
 
 	for (i = 0; i < MAX_BEARERS; i++) {
-		b_ptr = bearer_list[i];
+		b_ptr = rtnl_dereference(bearer_list[i]);
 		if (b_ptr && (!strcmp(b_ptr->name, name)))
 			return b_ptr;
 	}
@@ -198,10 +198,9 @@
 	if (!buf)
 		return NULL;
 
-	read_lock_bh(&tipc_net_lock);
 	for (i = 0; media_info_array[i] != NULL; i++) {
 		for (j = 0; j < MAX_BEARERS; j++) {
-			b = bearer_list[j];
+			b = rtnl_dereference(bearer_list[j]);
 			if (!b)
 				continue;
 			if (b->media == media_info_array[i]) {
@@ -211,22 +210,33 @@
 			}
 		}
 	}
-	read_unlock_bh(&tipc_net_lock);
 	return buf;
 }
 
-void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
+void tipc_bearer_add_dest(u32 bearer_id, u32 dest)
 {
-	tipc_nmap_add(&b_ptr->nodes, dest);
-	tipc_bcbearer_sort();
-	tipc_disc_add_dest(b_ptr->link_req);
+	struct tipc_bearer *b_ptr;
+
+	rcu_read_lock();
+	b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]);
+	if (b_ptr) {
+		tipc_bcbearer_sort(&b_ptr->nodes, dest, true);
+		tipc_disc_add_dest(b_ptr->link_req);
+	}
+	rcu_read_unlock();
 }
 
-void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
+void tipc_bearer_remove_dest(u32 bearer_id, u32 dest)
 {
-	tipc_nmap_remove(&b_ptr->nodes, dest);
-	tipc_bcbearer_sort();
-	tipc_disc_remove_dest(b_ptr->link_req);
+	struct tipc_bearer *b_ptr;
+
+	rcu_read_lock();
+	b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]);
+	if (b_ptr) {
+		tipc_bcbearer_sort(&b_ptr->nodes, dest, false);
+		tipc_disc_remove_dest(b_ptr->link_req);
+	}
+	rcu_read_unlock();
 }
 
 /**
@@ -271,13 +281,11 @@
 		return -EINVAL;
 	}
 
-	write_lock_bh(&tipc_net_lock);
-
 	m_ptr = tipc_media_find(b_names.media_name);
 	if (!m_ptr) {
 		pr_warn("Bearer <%s> rejected, media <%s> not registered\n",
 			name, b_names.media_name);
-		goto exit;
+		return -EINVAL;
 	}
 
 	if (priority == TIPC_MEDIA_LINK_PRI)
@@ -287,7 +295,7 @@
 	bearer_id = MAX_BEARERS;
 	with_this_prio = 1;
 	for (i = MAX_BEARERS; i-- != 0; ) {
-		b_ptr = bearer_list[i];
+		b_ptr = rtnl_dereference(bearer_list[i]);
 		if (!b_ptr) {
 			bearer_id = i;
 			continue;
@@ -295,14 +303,14 @@
 		if (!strcmp(name, b_ptr->name)) {
 			pr_warn("Bearer <%s> rejected, already enabled\n",
 				name);
-			goto exit;
+			return -EINVAL;
 		}
 		if ((b_ptr->priority == priority) &&
 		    (++with_this_prio > 2)) {
 			if (priority-- == 0) {
 				pr_warn("Bearer <%s> rejected, duplicate priority\n",
 					name);
-				goto exit;
+				return -EINVAL;
 			}
 			pr_warn("Bearer <%s> priority adjustment required %u->%u\n",
 				name, priority + 1, priority);
@@ -312,21 +320,20 @@
 	if (bearer_id >= MAX_BEARERS) {
 		pr_warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
 			name, MAX_BEARERS);
-		goto exit;
+		return -EINVAL;
 	}
 
 	b_ptr = kzalloc(sizeof(*b_ptr), GFP_ATOMIC);
-	if (!b_ptr) {
-		res = -ENOMEM;
-		goto exit;
-	}
+	if (!b_ptr)
+		return -ENOMEM;
+
 	strcpy(b_ptr->name, name);
 	b_ptr->media = m_ptr;
 	res = m_ptr->enable_media(b_ptr);
 	if (res) {
 		pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
 			name, -res);
-		goto exit;
+		return -EINVAL;
 	}
 
 	b_ptr->identity = bearer_id;
@@ -341,16 +348,14 @@
 		bearer_disable(b_ptr, false);
 		pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
 			name);
-		goto exit;
+		return -EINVAL;
 	}
 
-	bearer_list[bearer_id] = b_ptr;
+	rcu_assign_pointer(bearer_list[bearer_id], b_ptr);
 
 	pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
 		name,
 		tipc_addr_string_fill(addr_string, disc_domain), priority);
-exit:
-	write_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
@@ -359,19 +364,16 @@
  */
 static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
 {
-	read_lock_bh(&tipc_net_lock);
 	pr_info("Resetting bearer <%s>\n", b_ptr->name);
-	tipc_disc_delete(b_ptr->link_req);
 	tipc_link_reset_list(b_ptr->identity);
-	tipc_disc_create(b_ptr, &b_ptr->bcast_addr);
-	read_unlock_bh(&tipc_net_lock);
+	tipc_disc_reset(b_ptr);
 	return 0;
 }
 
 /**
  * bearer_disable
  *
- * Note: This routine assumes caller holds tipc_net_lock.
+ * Note: This routine assumes caller holds RTNL lock.
  */
 static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
 {
@@ -385,12 +387,12 @@
 		tipc_disc_delete(b_ptr->link_req);
 
 	for (i = 0; i < MAX_BEARERS; i++) {
-		if (b_ptr == bearer_list[i]) {
-			bearer_list[i] = NULL;
+		if (b_ptr == rtnl_dereference(bearer_list[i])) {
+			RCU_INIT_POINTER(bearer_list[i], NULL);
 			break;
 		}
 	}
-	kfree(b_ptr);
+	kfree_rcu(b_ptr, rcu);
 }
 
 int tipc_disable_bearer(const char *name)
@@ -398,7 +400,6 @@
 	struct tipc_bearer *b_ptr;
 	int res;
 
-	write_lock_bh(&tipc_net_lock);
 	b_ptr = tipc_bearer_find(name);
 	if (b_ptr == NULL) {
 		pr_warn("Attempt to disable unknown bearer <%s>\n", name);
@@ -407,7 +408,6 @@
 		bearer_disable(b_ptr, false);
 		res = 0;
 	}
-	write_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
@@ -444,7 +444,7 @@
 		return -ENODEV;
 
 	/* Associate TIPC bearer with Ethernet bearer */
-	b->media_ptr = dev;
+	rcu_assign_pointer(b->media_ptr, dev);
 	memset(b->bcast_addr.value, 0, sizeof(b->bcast_addr.value));
 	memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len);
 	b->bcast_addr.media_id = b->media->type_id;
@@ -463,8 +463,12 @@
  */
 void tipc_disable_l2_media(struct tipc_bearer *b)
 {
-	struct net_device *dev = (struct net_device *)b->media_ptr;
+	struct net_device *dev;
+
+	dev = (struct net_device *)rtnl_dereference(b->media_ptr);
+	RCU_INIT_POINTER(b->media_ptr, NULL);
 	RCU_INIT_POINTER(dev->tipc_ptr, NULL);
+	synchronize_net();
 	dev_put(dev);
 }
 
@@ -478,8 +482,12 @@
 		     struct tipc_media_addr *dest)
 {
 	struct sk_buff *clone;
+	struct net_device *dev;
 	int delta;
-	struct net_device *dev = (struct net_device *)b->media_ptr;
+
+	dev = (struct net_device *)rcu_dereference_rtnl(b->media_ptr);
+	if (!dev)
+		return 0;
 
 	clone = skb_clone(buf, GFP_ATOMIC);
 	if (!clone)
@@ -507,10 +515,16 @@
  * The media send routine must not alter the buffer being passed in
  * as it may be needed for later retransmission!
  */
-void tipc_bearer_send(struct tipc_bearer *b, struct sk_buff *buf,
+void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf,
 		      struct tipc_media_addr *dest)
 {
-	b->media->send_msg(buf, b, dest);
+	struct tipc_bearer *b_ptr;
+
+	rcu_read_lock();
+	b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]);
+	if (likely(b_ptr))
+		b_ptr->media->send_msg(buf, b_ptr, dest);
+	rcu_read_unlock();
 }
 
 /**
@@ -535,7 +549,7 @@
 	}
 
 	rcu_read_lock();
-	b_ptr = rcu_dereference(dev->tipc_ptr);
+	b_ptr = rcu_dereference_rtnl(dev->tipc_ptr);
 	if (likely(b_ptr)) {
 		if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
 			buf->next = NULL;
@@ -568,12 +582,9 @@
 	if (!net_eq(dev_net(dev), &init_net))
 		return NOTIFY_DONE;
 
-	rcu_read_lock();
-	b_ptr = rcu_dereference(dev->tipc_ptr);
-	if (!b_ptr) {
-		rcu_read_unlock();
+	b_ptr = rtnl_dereference(dev->tipc_ptr);
+	if (!b_ptr)
 		return NOTIFY_DONE;
-	}
 
 	b_ptr->mtu = dev->mtu;
 
@@ -592,11 +603,9 @@
 		break;
 	case NETDEV_UNREGISTER:
 	case NETDEV_CHANGENAME:
-		tipc_disable_bearer(b_ptr->name);
+		bearer_disable(b_ptr, false);
 		break;
 	}
-	rcu_read_unlock();
-
 	return NOTIFY_OK;
 }
 
@@ -633,7 +642,7 @@
 	u32 i;
 
 	for (i = 0; i < MAX_BEARERS; i++) {
-		b_ptr = bearer_list[i];
+		b_ptr = rtnl_dereference(bearer_list[i]);
 		if (b_ptr) {
 			bearer_disable(b_ptr, true);
 			bearer_list[i] = NULL;
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index ba48145..a983b30 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -113,6 +113,7 @@
  * @name: bearer name (format = media:interface)
  * @media: ptr to media structure associated with bearer
  * @bcast_addr: media address used in broadcasting
+ * @rcu: rcu struct for tipc_bearer
  * @priority: default link priority for bearer
  * @window: default window size for bearer
  * @tolerance: default link tolerance for bearer
@@ -127,12 +128,13 @@
  * care of initializing all other fields.
  */
 struct tipc_bearer {
-	void *media_ptr;			/* initalized by media */
+	void __rcu *media_ptr;			/* initalized by media */
 	u32 mtu;				/* initalized by media */
 	struct tipc_media_addr addr;		/* initalized by media */
 	char name[TIPC_MAX_BEARER_NAME];
 	struct tipc_media *media;
 	struct tipc_media_addr bcast_addr;
+	struct rcu_head rcu;
 	u32 priority;
 	u32 window;
 	u32 tolerance;
@@ -150,7 +152,7 @@
 
 struct tipc_link;
 
-extern struct tipc_bearer *bearer_list[];
+extern struct tipc_bearer __rcu *bearer_list[];
 
 /*
  * TIPC routines available to supported media types
@@ -181,14 +183,14 @@
 		     struct tipc_media_addr *dest);
 
 struct sk_buff *tipc_bearer_get_names(void);
-void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest);
-void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest);
+void tipc_bearer_add_dest(u32 bearer_id, u32 dest);
+void tipc_bearer_remove_dest(u32 bearer_id, u32 dest);
 struct tipc_bearer *tipc_bearer_find(const char *name);
 struct tipc_media *tipc_media_find(const char *name);
 int tipc_bearer_setup(void);
 void tipc_bearer_cleanup(void);
 void tipc_bearer_stop(void);
-void tipc_bearer_send(struct tipc_bearer *b, struct sk_buff *buf,
+void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf,
 		      struct tipc_media_addr *dest);
 
 #endif	/* _TIPC_BEARER_H */
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 4b981c0..251f5a2 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -42,8 +42,6 @@
 
 #define REPLY_TRUNCATED "<truncated>\n"
 
-static DEFINE_MUTEX(config_mutex);
-
 static const void *req_tlv_area;	/* request message TLV area */
 static int req_tlv_space;		/* request message TLV area size */
 static int rep_headroom;		/* reply message headroom to use */
@@ -223,7 +221,7 @@
 {
 	struct sk_buff *rep_tlv_buf;
 
-	mutex_lock(&config_mutex);
+	rtnl_lock();
 
 	/* Save request and reply details in a well-known location */
 	req_tlv_area = request_area;
@@ -337,6 +335,6 @@
 
 	/* Return reply buffer */
 exit:
-	mutex_unlock(&config_mutex);
+	rtnl_unlock();
 	return rep_tlv_buf;
 }
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 8985bbc..36cbf15 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -56,7 +56,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-
+#include <linux/rtnetlink.h>
 
 #define TIPC_MOD_VER "2.0.0"
 
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 542fe34..bd35c4a 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -46,8 +46,9 @@
 
 /**
  * struct tipc_link_req - information about an ongoing link setup request
- * @bearer: bearer issuing requests
+ * @bearer_id: identity of bearer issuing requests
  * @dest: destination address for request messages
+ * @domain: network domain to which links can be established
  * @num_nodes: number of nodes currently discovered (i.e. with an active link)
  * @lock: spinlock for controlling access to requests
  * @buf: request message to be (repeatedly) sent
@@ -55,8 +56,9 @@
  * @timer_intv: current interval between requests (in ms)
  */
 struct tipc_link_req {
-	struct tipc_bearer *bearer;
+	u32 bearer_id;
 	struct tipc_media_addr dest;
+	u32 domain;
 	int num_nodes;
 	spinlock_t lock;
 	struct sk_buff *buf;
@@ -69,22 +71,19 @@
  * @type: message type (request or response)
  * @b_ptr: ptr to bearer issuing message
  */
-static struct sk_buff *tipc_disc_init_msg(u32 type, struct tipc_bearer *b_ptr)
+static void tipc_disc_init_msg(struct sk_buff *buf, u32 type,
+			       struct tipc_bearer *b_ptr)
 {
-	struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE);
 	struct tipc_msg *msg;
 	u32 dest_domain = b_ptr->domain;
 
-	if (buf) {
-		msg = buf_msg(buf);
-		tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
-		msg_set_non_seq(msg, 1);
-		msg_set_node_sig(msg, tipc_random);
-		msg_set_dest_domain(msg, dest_domain);
-		msg_set_bc_netid(msg, tipc_net_id);
-		b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg));
-	}
-	return buf;
+	msg = buf_msg(buf);
+	tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
+	msg_set_non_seq(msg, 1);
+	msg_set_node_sig(msg, tipc_random);
+	msg_set_dest_domain(msg, dest_domain);
+	msg_set_bc_netid(msg, tipc_net_id);
+	b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg));
 }
 
 /**
@@ -239,9 +238,10 @@
 	link_fully_up = link_working_working(link);
 
 	if ((type == DSC_REQ_MSG) && !link_fully_up) {
-		rbuf = tipc_disc_init_msg(DSC_RESP_MSG, b_ptr);
+		rbuf = tipc_buf_acquire(INT_H_SIZE);
 		if (rbuf) {
-			tipc_bearer_send(b_ptr, rbuf, &media_addr);
+			tipc_disc_init_msg(rbuf, DSC_RESP_MSG, b_ptr);
+			tipc_bearer_send(b_ptr->identity, rbuf, &media_addr);
 			kfree_skb(rbuf);
 		}
 	}
@@ -303,7 +303,7 @@
 	spin_lock_bh(&req->lock);
 
 	/* Stop searching if only desired node has been found */
-	if (tipc_node(req->bearer->domain) && req->num_nodes) {
+	if (tipc_node(req->domain) && req->num_nodes) {
 		req->timer_intv = TIPC_LINK_REQ_INACTIVE;
 		goto exit;
 	}
@@ -315,7 +315,7 @@
 	 * hold at fast polling rate if don't have any associated nodes,
 	 * otherwise hold at slow polling rate
 	 */
-	tipc_bearer_send(req->bearer, req->buf, &req->dest);
+	tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
 
 
 	req->timer_intv *= 2;
@@ -347,21 +347,23 @@
 	if (!req)
 		return -ENOMEM;
 
-	req->buf = tipc_disc_init_msg(DSC_REQ_MSG, b_ptr);
+	req->buf = tipc_buf_acquire(INT_H_SIZE);
 	if (!req->buf) {
 		kfree(req);
-		return -ENOMSG;
+		return -ENOMEM;
 	}
 
+	tipc_disc_init_msg(req->buf, DSC_REQ_MSG, b_ptr);
 	memcpy(&req->dest, dest, sizeof(*dest));
-	req->bearer = b_ptr;
+	req->bearer_id = b_ptr->identity;
+	req->domain = b_ptr->domain;
 	req->num_nodes = 0;
 	req->timer_intv = TIPC_LINK_REQ_INIT;
 	spin_lock_init(&req->lock);
 	k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
 	k_start_timer(&req->timer, req->timer_intv);
 	b_ptr->link_req = req;
-	tipc_bearer_send(req->bearer, req->buf, &req->dest);
+	tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
 	return 0;
 }
 
@@ -376,3 +378,23 @@
 	kfree_skb(req->buf);
 	kfree(req);
 }
+
+/**
+ * tipc_disc_reset - reset object to send periodic link setup requests
+ * @b_ptr: ptr to bearer issuing requests
+ * @dest_domain: network domain to which links can be established
+ */
+void tipc_disc_reset(struct tipc_bearer *b_ptr)
+{
+	struct tipc_link_req *req = b_ptr->link_req;
+
+	spin_lock_bh(&req->lock);
+	tipc_disc_init_msg(req->buf, DSC_REQ_MSG, b_ptr);
+	req->bearer_id = b_ptr->identity;
+	req->domain = b_ptr->domain;
+	req->num_nodes = 0;
+	req->timer_intv = TIPC_LINK_REQ_INIT;
+	k_start_timer(&req->timer, req->timer_intv);
+	tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
+	spin_unlock_bh(&req->lock);
+}
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index 07f3472..515b573 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -41,6 +41,7 @@
 
 int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest);
 void tipc_disc_delete(struct tipc_link_req *req);
+void tipc_disc_reset(struct tipc_bearer *b_ptr);
 void tipc_disc_add_dest(struct tipc_link_req *req);
 void tipc_disc_remove_dest(struct tipc_link_req *req);
 void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *b_ptr);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index c5190ab..c723ee9 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -101,9 +101,18 @@
 
 static void link_init_max_pkt(struct tipc_link *l_ptr)
 {
+	struct tipc_bearer *b_ptr;
 	u32 max_pkt;
 
-	max_pkt = (l_ptr->b_ptr->mtu & ~3);
+	rcu_read_lock();
+	b_ptr = rcu_dereference_rtnl(bearer_list[l_ptr->bearer_id]);
+	if (!b_ptr) {
+		rcu_read_unlock();
+		return;
+	}
+	max_pkt = (b_ptr->mtu & ~3);
+	rcu_read_unlock();
+
 	if (max_pkt > MAX_MSG_SIZE)
 		max_pkt = MAX_MSG_SIZE;
 
@@ -248,7 +257,7 @@
 	l_ptr->owner = n_ptr;
 	l_ptr->checkpoint = 1;
 	l_ptr->peer_session = INVALID_SESSION;
-	l_ptr->b_ptr = b_ptr;
+	l_ptr->bearer_id = b_ptr->identity;
 	link_set_supervision_props(l_ptr, b_ptr->tolerance);
 	l_ptr->state = RESET_UNKNOWN;
 
@@ -263,6 +272,7 @@
 	l_ptr->priority = b_ptr->priority;
 	tipc_link_set_queue_limits(l_ptr, b_ptr->window);
 
+	l_ptr->net_plane = b_ptr->net_plane;
 	link_init_max_pkt(l_ptr);
 
 	l_ptr->next_out_no = 1;
@@ -426,7 +436,7 @@
 		return;
 
 	tipc_node_link_down(l_ptr->owner, l_ptr);
-	tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
+	tipc_bearer_remove_dest(l_ptr->bearer_id, l_ptr->addr);
 
 	if (was_active_link && tipc_node_active_links(l_ptr->owner)) {
 		l_ptr->reset_checkpoint = checkpoint;
@@ -477,7 +487,7 @@
 {
 	l_ptr->next_in_no = l_ptr->stats.recv_info = 1;
 	tipc_node_link_up(l_ptr->owner, l_ptr);
-	tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
+	tipc_bearer_add_dest(l_ptr->bearer_id, l_ptr->addr);
 }
 
 /**
@@ -777,7 +787,7 @@
 	if (likely(!link_congested(l_ptr))) {
 		link_add_to_outqueue(l_ptr, buf, msg);
 
-		tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+		tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
 		l_ptr->unacked_window = 0;
 		return dsz;
 	}
@@ -825,7 +835,6 @@
 	struct tipc_node *n_ptr;
 	int res = -ELINKCONG;
 
-	read_lock_bh(&tipc_net_lock);
 	n_ptr = tipc_node_find(dest);
 	if (n_ptr) {
 		tipc_node_lock(n_ptr);
@@ -838,7 +847,6 @@
 	} else {
 		kfree_skb(buf);
 	}
-	read_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
@@ -902,7 +910,6 @@
 	if (list_empty(message_list))
 		return;
 
-	read_lock_bh(&tipc_net_lock);
 	n_ptr = tipc_node_find(dest);
 	if (n_ptr) {
 		tipc_node_lock(n_ptr);
@@ -917,7 +924,6 @@
 		}
 		tipc_node_unlock(n_ptr);
 	}
-	read_unlock_bh(&tipc_net_lock);
 
 	/* discard the messages if they couldn't be sent */
 	list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) {
@@ -941,7 +947,7 @@
 	if (likely(!link_congested(l_ptr))) {
 		if (likely(msg_size(msg) <= l_ptr->max_pkt)) {
 			link_add_to_outqueue(l_ptr, buf, msg);
-			tipc_bearer_send(l_ptr->b_ptr, buf,
+			tipc_bearer_send(l_ptr->bearer_id, buf,
 					 &l_ptr->media_addr);
 			l_ptr->unacked_window = 0;
 			return res;
@@ -979,7 +985,6 @@
 	if (unlikely(res < 0))
 		return res;
 
-	read_lock_bh(&tipc_net_lock);
 	node = tipc_node_find(destaddr);
 	if (likely(node)) {
 		tipc_node_lock(node);
@@ -990,7 +995,6 @@
 							  &sender->max_pkt);
 exit:
 				tipc_node_unlock(node);
-				read_unlock_bh(&tipc_net_lock);
 				return res;
 			}
 
@@ -1007,7 +1011,6 @@
 			 */
 			sender->max_pkt = l_ptr->max_pkt;
 			tipc_node_unlock(node);
-			read_unlock_bh(&tipc_net_lock);
 
 
 			if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
@@ -1018,7 +1021,6 @@
 		}
 		tipc_node_unlock(node);
 	}
-	read_unlock_bh(&tipc_net_lock);
 
 	/* Couldn't find a link to the destination node */
 	kfree_skb(buf);
@@ -1204,7 +1206,7 @@
 	if (r_q_size && buf) {
 		msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
 		msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
-		tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+		tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
 		l_ptr->retransm_queue_head = mod(++r_q_head);
 		l_ptr->retransm_queue_size = --r_q_size;
 		l_ptr->stats.retransmitted++;
@@ -1216,7 +1218,7 @@
 	if (buf) {
 		msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
 		msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
-		tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+		tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
 		l_ptr->unacked_window = 0;
 		kfree_skb(buf);
 		l_ptr->proto_msg_queue = NULL;
@@ -1233,7 +1235,8 @@
 		if (mod(next - first) < l_ptr->queue_limit[0]) {
 			msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
 			msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
-			tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+			tipc_bearer_send(l_ptr->bearer_id, buf,
+					 &l_ptr->media_addr);
 			if (msg_user(msg) == MSG_BUNDLER)
 				msg_set_type(msg, CLOSED_MSG);
 			l_ptr->next_out = buf->next;
@@ -1262,12 +1265,9 @@
 	char addr_string[16];
 	u32 i;
 
-	read_lock_bh(&tipc_net_lock);
 	n_ptr = tipc_node_find((u32)addr);
-	if (!n_ptr) {
-		read_unlock_bh(&tipc_net_lock);
+	if (!n_ptr)
 		return;	/* node no longer exists */
-	}
 
 	tipc_node_lock(n_ptr);
 
@@ -1282,7 +1282,6 @@
 	}
 
 	tipc_node_unlock(n_ptr);
-	read_unlock_bh(&tipc_net_lock);
 }
 
 static void link_retransmit_failure(struct tipc_link *l_ptr,
@@ -1352,7 +1351,7 @@
 		msg = buf_msg(buf);
 		msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
 		msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
-		tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+		tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
 		buf = buf->next;
 		retransmits--;
 		l_ptr->stats.retransmitted++;
@@ -1440,14 +1439,13 @@
 /**
  * tipc_rcv - process TIPC packets/messages arriving from off-node
  * @head: pointer to message buffer chain
- * @tb_ptr: pointer to bearer message arrived on
+ * @b_ptr: pointer to bearer message arrived on
  *
  * Invoked with no locks held.  Bearer pointer must point to a valid bearer
  * structure (i.e. cannot be NULL), but bearer can be inactive.
  */
 void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 {
-	read_lock_bh(&tipc_net_lock);
 	while (head) {
 		struct tipc_node *n_ptr;
 		struct tipc_link *l_ptr;
@@ -1635,7 +1633,6 @@
 discard:
 		kfree_skb(buf);
 	}
-	read_unlock_bh(&tipc_net_lock);
 }
 
 /**
@@ -1752,7 +1749,7 @@
 
 	/* Create protocol message with "out-of-sequence" sequence number */
 	msg_set_type(msg, msg_typ);
-	msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
+	msg_set_net_plane(msg, l_ptr->net_plane);
 	msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
 	msg_set_last_bcast(msg, tipc_bclink_get_last_sent());
 
@@ -1818,7 +1815,7 @@
 	skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
 	buf->priority = TC_PRIO_CONTROL;
 
-	tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+	tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
 	l_ptr->unacked_window = 0;
 	kfree_skb(buf);
 }
@@ -1843,9 +1840,9 @@
 	/* record unnumbered packet arrival (force mismatch on next timeout) */
 	l_ptr->checkpoint--;
 
-	if (l_ptr->b_ptr->net_plane != msg_net_plane(msg))
+	if (l_ptr->net_plane != msg_net_plane(msg))
 		if (tipc_own_addr > msg_prevnode(msg))
-			l_ptr->b_ptr->net_plane = msg_net_plane(msg);
+			l_ptr->net_plane = msg_net_plane(msg);
 
 	switch (msg_type(msg)) {
 
@@ -2397,8 +2394,6 @@
 /* tipc_link_find_owner - locate owner node of link by link's name
  * @name: pointer to link name string
  * @bearer_id: pointer to index in 'node->links' array where the link was found.
- * Caller must hold 'tipc_net_lock' to ensure node and bearer are not deleted;
- * this also prevents link deletion.
  *
  * Returns pointer to node owning the link, or 0 if no matching link is found.
  */
@@ -2460,7 +2455,7 @@
  * @new_value: new value of link, bearer, or media setting
  * @cmd: which link, bearer, or media attribute to set (TIPC_CMD_SET_LINK_*)
  *
- * Caller must hold 'tipc_net_lock' to ensure link/bearer/media is not deleted.
+ * Caller must hold RTNL lock to ensure link/bearer/media is not deleted.
  *
  * Returns 0 if value updated and negative value on error.
  */
@@ -2566,9 +2561,7 @@
 						   " (cannot change setting on broadcast link)");
 	}
 
-	read_lock_bh(&tipc_net_lock);
 	res = link_cmd_set_value(args->name, new_value, cmd);
-	read_unlock_bh(&tipc_net_lock);
 	if (res)
 		return tipc_cfg_reply_error_string("cannot change link setting");
 
@@ -2602,22 +2595,18 @@
 			return tipc_cfg_reply_error_string("link not found");
 		return tipc_cfg_reply_none();
 	}
-	read_lock_bh(&tipc_net_lock);
 	node = tipc_link_find_owner(link_name, &bearer_id);
-	if (!node) {
-		read_unlock_bh(&tipc_net_lock);
+	if (!node)
 		return tipc_cfg_reply_error_string("link not found");
-	}
+
 	tipc_node_lock(node);
 	l_ptr = node->links[bearer_id];
 	if (!l_ptr) {
 		tipc_node_unlock(node);
-		read_unlock_bh(&tipc_net_lock);
 		return tipc_cfg_reply_error_string("link not found");
 	}
 	link_reset_statistics(l_ptr);
 	tipc_node_unlock(node);
-	read_unlock_bh(&tipc_net_lock);
 	return tipc_cfg_reply_none();
 }
 
@@ -2650,18 +2639,15 @@
 	if (!strcmp(name, tipc_bclink_name))
 		return tipc_bclink_stats(buf, buf_size);
 
-	read_lock_bh(&tipc_net_lock);
 	node = tipc_link_find_owner(name, &bearer_id);
-	if (!node) {
-		read_unlock_bh(&tipc_net_lock);
+	if (!node)
 		return 0;
-	}
+
 	tipc_node_lock(node);
 
 	l = node->links[bearer_id];
 	if (!l) {
 		tipc_node_unlock(node);
-		read_unlock_bh(&tipc_net_lock);
 		return 0;
 	}
 
@@ -2727,7 +2713,6 @@
 			     (s->accu_queue_sz / s->queue_sz_counts) : 0);
 
 	tipc_node_unlock(node);
-	read_unlock_bh(&tipc_net_lock);
 	return ret;
 }
 
@@ -2778,7 +2763,6 @@
 	if (dest == tipc_own_addr)
 		return MAX_MSG_SIZE;
 
-	read_lock_bh(&tipc_net_lock);
 	n_ptr = tipc_node_find(dest);
 	if (n_ptr) {
 		tipc_node_lock(n_ptr);
@@ -2787,13 +2771,18 @@
 			res = l_ptr->max_pkt;
 		tipc_node_unlock(n_ptr);
 	}
-	read_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
 static void link_print(struct tipc_link *l_ptr, const char *str)
 {
-	pr_info("%s Link %x<%s>:", str, l_ptr->addr, l_ptr->b_ptr->name);
+	struct tipc_bearer *b_ptr;
+
+	rcu_read_lock();
+	b_ptr = rcu_dereference_rtnl(bearer_list[l_ptr->bearer_id]);
+	if (b_ptr)
+		pr_info("%s Link %x<%s>:", str, l_ptr->addr, b_ptr->name);
+	rcu_read_unlock();
 
 	if (link_working_unknown(l_ptr))
 		pr_cont(":WU\n");
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 8c0b49b..4b556c1 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -107,7 +107,7 @@
  * @checkpoint: reference point for triggering link continuity checking
  * @peer_session: link session # being used by peer end of link
  * @peer_bearer_id: bearer id used by link's peer endpoint
- * @b_ptr: pointer to bearer used by link
+ * @bearer_id: local bearer id used by link
  * @tolerance: minimum link continuity loss needed to reset link [in ms]
  * @continuity_interval: link continuity testing interval [in ms]
  * @abort_limit: # of unacknowledged continuity probes needed to reset link
@@ -116,6 +116,7 @@
  * @proto_msg: template for control messages generated by link
  * @pmsg: convenience pointer to "proto_msg" field
  * @priority: current link priority
+ * @net_plane: current link network plane ('A' through 'H')
  * @queue_limit: outbound message queue congestion thresholds (indexed by user)
  * @exp_msg_count: # of tunnelled messages expected during link changeover
  * @reset_checkpoint: seq # of last acknowledged message at time of link reset
@@ -155,7 +156,7 @@
 	u32 checkpoint;
 	u32 peer_session;
 	u32 peer_bearer_id;
-	struct tipc_bearer *b_ptr;
+	u32 bearer_id;
 	u32 tolerance;
 	u32 continuity_interval;
 	u32 abort_limit;
@@ -167,6 +168,7 @@
 	} proto_msg;
 	struct tipc_msg *pmsg;
 	u32 priority;
+	char net_plane;
 	u32 queue_limit[15];	/* queue_limit[0]==window limit */
 
 	/* Changeover */
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index aff8041..974a73f 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -127,7 +127,7 @@
 	return buf;
 }
 
-static void named_cluster_distribute(struct sk_buff *buf)
+void named_cluster_distribute(struct sk_buff *buf)
 {
 	struct sk_buff *buf_copy;
 	struct tipc_node *n_ptr;
@@ -156,7 +156,7 @@
 /**
  * tipc_named_publish - tell other nodes about a new publication by this node
  */
-void tipc_named_publish(struct publication *publ)
+struct sk_buff *tipc_named_publish(struct publication *publ)
 {
 	struct sk_buff *buf;
 	struct distr_item *item;
@@ -165,23 +165,23 @@
 	publ_lists[publ->scope]->size++;
 
 	if (publ->scope == TIPC_NODE_SCOPE)
-		return;
+		return NULL;
 
 	buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0);
 	if (!buf) {
 		pr_warn("Publication distribution failure\n");
-		return;
+		return NULL;
 	}
 
 	item = (struct distr_item *)msg_data(buf_msg(buf));
 	publ_to_item(item, publ);
-	named_cluster_distribute(buf);
+	return buf;
 }
 
 /**
  * tipc_named_withdraw - tell other nodes about a withdrawn publication by this node
  */
-void tipc_named_withdraw(struct publication *publ)
+struct sk_buff *tipc_named_withdraw(struct publication *publ)
 {
 	struct sk_buff *buf;
 	struct distr_item *item;
@@ -190,17 +190,17 @@
 	publ_lists[publ->scope]->size--;
 
 	if (publ->scope == TIPC_NODE_SCOPE)
-		return;
+		return NULL;
 
 	buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0);
 	if (!buf) {
 		pr_warn("Withdrawal distribution failure\n");
-		return;
+		return NULL;
 	}
 
 	item = (struct distr_item *)msg_data(buf_msg(buf));
 	publ_to_item(item, publ);
-	named_cluster_distribute(buf);
+	return buf;
 }
 
 /*
@@ -248,7 +248,6 @@
 	u32 max_item_buf = 0;
 
 	/* compute maximum amount of publication data to send per message */
-	read_lock_bh(&tipc_net_lock);
 	n_ptr = tipc_node_find(node);
 	if (n_ptr) {
 		tipc_node_lock(n_ptr);
@@ -258,7 +257,6 @@
 				ITEM_SIZE) * ITEM_SIZE;
 		tipc_node_unlock(n_ptr);
 	}
-	read_unlock_bh(&tipc_net_lock);
 	if (!max_item_buf)
 		return;
 
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index 9b312cc..47ff829 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -39,8 +39,9 @@
 
 #include "name_table.h"
 
-void tipc_named_publish(struct publication *publ);
-void tipc_named_withdraw(struct publication *publ);
+struct sk_buff *tipc_named_publish(struct publication *publ);
+struct sk_buff *tipc_named_withdraw(struct publication *publ);
+void named_cluster_distribute(struct sk_buff *buf);
 void tipc_named_node_up(unsigned long node);
 void tipc_named_rcv(struct sk_buff *buf);
 void tipc_named_reinit(void);
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 042e8e3..9d7d37d 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -664,6 +664,7 @@
 					 u32 scope, u32 port_ref, u32 key)
 {
 	struct publication *publ;
+	struct sk_buff *buf = NULL;
 
 	if (table.local_publ_count >= TIPC_MAX_PUBLICATIONS) {
 		pr_warn("Publication failed, local publication limit reached (%u)\n",
@@ -676,9 +677,12 @@
 				   tipc_own_addr, port_ref, key);
 	if (likely(publ)) {
 		table.local_publ_count++;
-		tipc_named_publish(publ);
+		buf = tipc_named_publish(publ);
 	}
 	write_unlock_bh(&tipc_nametbl_lock);
+
+	if (buf)
+		named_cluster_distribute(buf);
 	return publ;
 }
 
@@ -688,15 +692,19 @@
 int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
 {
 	struct publication *publ;
+	struct sk_buff *buf;
 
 	write_lock_bh(&tipc_nametbl_lock);
 	publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
 	if (likely(publ)) {
 		table.local_publ_count--;
-		tipc_named_withdraw(publ);
+		buf = tipc_named_withdraw(publ);
 		write_unlock_bh(&tipc_nametbl_lock);
 		list_del_init(&publ->pport_list);
 		kfree(publ);
+
+		if (buf)
+			named_cluster_distribute(buf);
 		return 1;
 	}
 	write_unlock_bh(&tipc_nametbl_lock);
@@ -961,6 +969,7 @@
 	list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) {
 		tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node,
 					 publ->ref, publ->key);
+		kfree(publ);
 	}
 }
 
@@ -982,7 +991,6 @@
 		hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) {
 			tipc_purge_publications(seq);
 		}
-		continue;
 	}
 	kfree(table.types);
 	table.types = NULL;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 4c564eb..75bb390 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -45,39 +45,34 @@
 /*
  * The TIPC locking policy is designed to ensure a very fine locking
  * granularity, permitting complete parallel access to individual
- * port and node/link instances. The code consists of three major
+ * port and node/link instances. The code consists of four major
  * locking domains, each protected with their own disjunct set of locks.
  *
- * 1: The routing hierarchy.
- *    Comprises the structures 'zone', 'cluster', 'node', 'link'
- *    and 'bearer'. The whole hierarchy is protected by a big
- *    read/write lock, tipc_net_lock, to enssure that nothing is added
- *    or removed while code is accessing any of these structures.
- *    This layer must not be called from the two others while they
- *    hold any of their own locks.
- *    Neither must it itself do any upcalls to the other two before
- *    it has released tipc_net_lock and other protective locks.
+ * 1: The bearer level.
+ *    RTNL lock is used to serialize the process of configuring bearer
+ *    on update side, and RCU lock is applied on read side to make
+ *    bearer instance valid on both paths of message transmission and
+ *    reception.
  *
- *   Within the tipc_net_lock domain there are two sub-domains;'node' and
- *   'bearer', where local write operations are permitted,
- *   provided that those are protected by individual spin_locks
- *   per instance. Code holding tipc_net_lock(read) and a node spin_lock
- *   is permitted to poke around in both the node itself and its
- *   subordinate links. I.e, it can update link counters and queues,
- *   change link state, send protocol messages, and alter the
- *   "active_links" array in the node; but it can _not_ remove a link
- *   or a node from the overall structure.
- *   Correspondingly, individual bearers may change status within a
- *   tipc_net_lock(read), protected by an individual spin_lock ber bearer
- *   instance, but it needs tipc_net_lock(write) to remove/add any bearers.
+ * 2: The node and link level.
+ *    All node instances are saved into two tipc_node_list and node_htable
+ *    lists. The two lists are protected by node_list_lock on write side,
+ *    and they are guarded with RCU lock on read side. Especially node
+ *    instance is destroyed only when TIPC module is removed, and we can
+ *    confirm that there has no any user who is accessing the node at the
+ *    moment. Therefore, Except for iterating the two lists within RCU
+ *    protection, it's no needed to hold RCU that we access node instance
+ *    in other places.
  *
+ *    In addition, all members in node structure including link instances
+ *    are protected by node spin lock.
  *
- *  2: The transport level of the protocol.
- *     This consists of the structures port, (and its user level
- *     representations, such as user_port and tipc_sock), reference and
- *     tipc_user (port.c, reg.c, socket.c).
+ * 3: The transport level of the protocol.
+ *    This consists of the structures port, (and its user level
+ *    representations, such as user_port and tipc_sock), reference and
+ *    tipc_user (port.c, reg.c, socket.c).
  *
- *     This layer has four different locks:
+ *    This layer has four different locks:
  *     - The tipc_port spin_lock. This is protecting each port instance
  *       from parallel data access and removal. Since we can not place
  *       this lock in the port itself, it has been placed in the
@@ -96,7 +91,7 @@
  *       There are two such lists; 'port_list', which is used for management,
  *       and 'wait_list', which is used to queue ports during congestion.
  *
- *  3: The name table (name_table.c, name_distr.c, subscription.c)
+ *  4: The name table (name_table.c, name_distr.c, subscription.c)
  *     - There is one big read/write-lock (tipc_nametbl_lock) protecting the
  *       overall name table structure. Nothing must be added/removed to
  *       this structure without holding write access to it.
@@ -108,8 +103,6 @@
  *     - A local spin_lock protecting the queue of subscriber events.
 */
 
-DEFINE_RWLOCK(tipc_net_lock);
-
 static void net_route_named_msg(struct sk_buff *buf)
 {
 	struct tipc_msg *msg = buf_msg(buf);
@@ -175,15 +168,13 @@
 {
 	char addr_string[16];
 
-	write_lock_bh(&tipc_net_lock);
 	tipc_own_addr = addr;
 	tipc_named_reinit();
 	tipc_port_reinit();
 	tipc_bclink_init();
-	write_unlock_bh(&tipc_net_lock);
-
 	tipc_nametbl_publish(TIPC_CFG_SRV, tipc_own_addr, tipc_own_addr,
 			     TIPC_ZONE_SCOPE, 0, tipc_own_addr);
+
 	pr_info("Started in network mode\n");
 	pr_info("Own node address %s, network identity %u\n",
 		tipc_addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
@@ -195,11 +186,11 @@
 		return;
 
 	tipc_nametbl_withdraw(TIPC_CFG_SRV, tipc_own_addr, 0, tipc_own_addr);
-	write_lock_bh(&tipc_net_lock);
+	rtnl_lock();
 	tipc_bearer_stop();
 	tipc_bclink_stop();
 	tipc_node_stop();
-	write_unlock_bh(&tipc_net_lock);
+	rtnl_unlock();
 
 	pr_info("Left network mode\n");
 }
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 079daad..f781cae 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -37,8 +37,6 @@
 #ifndef _TIPC_NET_H
 #define _TIPC_NET_H
 
-extern rwlock_t tipc_net_lock;
-
 void tipc_net_route_msg(struct sk_buff *buf);
 
 void tipc_net_start(u32 addr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 1d3a499..6d6543e 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -144,11 +144,13 @@
 void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
 {
 	struct tipc_link **active = &n_ptr->active_links[0];
+	u32 addr = n_ptr->addr;
 
 	n_ptr->working_links++;
-
+	tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, TIPC_NODE_SCOPE,
+			     l_ptr->bearer_id, addr);
 	pr_info("Established link <%s> on network plane %c\n",
-		l_ptr->name, l_ptr->b_ptr->net_plane);
+		l_ptr->name, l_ptr->net_plane);
 
 	if (!active[0]) {
 		active[0] = active[1] = l_ptr;
@@ -203,16 +205,18 @@
 void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
 {
 	struct tipc_link **active;
+	u32 addr = n_ptr->addr;
 
 	n_ptr->working_links--;
+	tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, l_ptr->bearer_id, addr);
 
 	if (!tipc_link_is_active(l_ptr)) {
 		pr_info("Lost standby link <%s> on network plane %c\n",
-			l_ptr->name, l_ptr->b_ptr->net_plane);
+			l_ptr->name, l_ptr->net_plane);
 		return;
 	}
 	pr_info("Lost link <%s> on network plane %c\n",
-		l_ptr->name, l_ptr->b_ptr->net_plane);
+		l_ptr->name, l_ptr->net_plane);
 
 	active = &n_ptr->active_links[0];
 	if (active[0] == l_ptr)
@@ -239,7 +243,7 @@
 
 void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
 {
-	n_ptr->links[l_ptr->b_ptr->identity] = l_ptr;
+	n_ptr->links[l_ptr->bearer_id] = l_ptr;
 	spin_lock_bh(&node_list_lock);
 	tipc_num_links++;
 	spin_unlock_bh(&node_list_lock);
@@ -273,14 +277,12 @@
 {
 	struct tipc_node *n_ptr;
 
-	read_lock_bh(&tipc_net_lock);
 	n_ptr = tipc_node_find(node_addr);
 	if (n_ptr) {
 		tipc_node_lock(n_ptr);
 		n_ptr->block_setup &= ~WAIT_NAMES_GONE;
 		tipc_node_unlock(n_ptr);
 	}
-	read_unlock_bh(&tipc_net_lock);
 }
 
 static void node_lost_contact(struct tipc_node *n_ptr)
@@ -436,3 +438,30 @@
 	rcu_read_unlock();
 	return buf;
 }
+
+/**
+ * tipc_node_get_linkname - get the name of a link
+ *
+ * @bearer_id: id of the bearer
+ * @node: peer node address
+ * @linkname: link name output buffer
+ *
+ * Returns 0 on success
+ */
+int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
+{
+	struct tipc_link *link;
+	struct tipc_node *node = tipc_node_find(addr);
+
+	if ((bearer_id >= MAX_BEARERS) || !node)
+		return -EINVAL;
+	tipc_node_lock(node);
+	link = node->links[bearer_id];
+	if (link) {
+		strncpy(linkname, link->name, len);
+		tipc_node_unlock(node);
+		return 0;
+	}
+	tipc_node_unlock(node);
+	return -EINVAL;
+}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 7cbb8ce..411b191 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -118,6 +118,7 @@
 int tipc_node_is_up(struct tipc_node *n_ptr);
 struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
 struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
+int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
 
 static inline void tipc_node_lock(struct tipc_node *n_ptr)
 {
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 3c02569..3f9912f 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -36,6 +36,7 @@
 
 #include "core.h"
 #include "port.h"
+#include "node.h"
 
 #include <linux/export.h>
 
@@ -1905,6 +1906,28 @@
 	return put_user(sizeof(value), ol);
 }
 
+int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg)
+{
+	struct tipc_sioc_ln_req lnr;
+	void __user *argp = (void __user *)arg;
+
+	switch (cmd) {
+	case SIOCGETLINKNAME:
+		if (copy_from_user(&lnr, argp, sizeof(lnr)))
+			return -EFAULT;
+		if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer,
+					    lnr.linkname, TIPC_MAX_LINK_NAME)) {
+			if (copy_to_user(argp, &lnr, sizeof(lnr)))
+				return -EFAULT;
+			return 0;
+		}
+		return -EADDRNOTAVAIL;
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
 /* Protocol switches for the various types of TIPC sockets */
 
 static const struct proto_ops msg_ops = {
@@ -1917,7 +1940,7 @@
 	.accept		= sock_no_accept,
 	.getname	= tipc_getname,
 	.poll		= tipc_poll,
-	.ioctl		= sock_no_ioctl,
+	.ioctl		= tipc_ioctl,
 	.listen		= sock_no_listen,
 	.shutdown	= tipc_shutdown,
 	.setsockopt	= tipc_setsockopt,
@@ -1938,7 +1961,7 @@
 	.accept		= tipc_accept,
 	.getname	= tipc_getname,
 	.poll		= tipc_poll,
-	.ioctl		= sock_no_ioctl,
+	.ioctl		= tipc_ioctl,
 	.listen		= tipc_listen,
 	.shutdown	= tipc_shutdown,
 	.setsockopt	= tipc_setsockopt,
@@ -1959,7 +1982,7 @@
 	.accept		= tipc_accept,
 	.getname	= tipc_getname,
 	.poll		= tipc_poll,
-	.ioctl		= sock_no_ioctl,
+	.ioctl		= tipc_ioctl,
 	.listen		= tipc_listen,
 	.shutdown	= tipc_shutdown,
 	.setsockopt	= tipc_setsockopt,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 14d04e6..be491a7 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -147,7 +147,7 @@
 	{ "peer", { "recv", NULL } },
 	{ "capability2",
 	  { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend",
-	    NULL } },
+	    "audit_read", NULL } },
 	{ "kernel_service", { "use_as_override", "create_files_as", NULL } },
 	{ "tun_socket",
 	  { COMMON_SOCK_PERMS, "attach_queue", NULL } },
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 1c16830..6faaac6 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -520,7 +520,7 @@
 			snd_es18xx_mixer_write(chip, 0x78, 0x93);
 #ifdef AVOID_POPS
 		/* Avoid pops */
-                udelay(100000);
+		mdelay(100);
 		if (chip->caps & ES18XX_PCM2)
 			/* Restore Audio 2 volume */
 			snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol);
@@ -537,7 +537,7 @@
                 /* Stop DMA */
                 snd_es18xx_mixer_write(chip, 0x78, 0x00);
 #ifdef AVOID_POPS
-                udelay(25000);
+		mdelay(25);
 		if (chip->caps & ES18XX_PCM2)
 			/* Set Audio 2 volume to 0 */
 			snd_es18xx_mixer_write(chip, 0x7C, 0);
@@ -596,7 +596,7 @@
 	snd_es18xx_write(chip, 0xA5, count >> 8);
 
 #ifdef AVOID_POPS
-	udelay(100000);
+	mdelay(100);
 #endif
 
         /* Set format */
@@ -691,7 +691,7 @@
                 snd_es18xx_write(chip, 0xB8, 0x05);
 #ifdef AVOID_POPS
 		/* Avoid pops */
-                udelay(100000);
+		mdelay(100);
                 /* Enable Audio 1 */
                 snd_es18xx_dsp_command(chip, 0xD1);
 #endif
@@ -705,7 +705,7 @@
                 snd_es18xx_write(chip, 0xB8, 0x00);
 #ifdef AVOID_POPS
 		/* Avoid pops */
-                udelay(25000);
+		mdelay(25);
                 /* Disable Audio 1 */
                 snd_es18xx_dsp_command(chip, 0xD3);
 #endif
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 14ae979..c643dfc 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4621,6 +4621,7 @@
 	SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
+	SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -4912,6 +4913,7 @@
 		spec->codec_variant = ALC269_TYPE_ALC285;
 		break;
 	case 0x10ec0286:
+	case 0x10ec0288:
 		spec->codec_variant = ALC269_TYPE_ALC286;
 		break;
 	case 0x10ec0255:
@@ -5539,6 +5541,8 @@
 	SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
 	SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE),
+	SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+	SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
 	SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
 	SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
@@ -5781,6 +5785,7 @@
 	{ .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
 	{ .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
 	{ .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
+	{ .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
 	{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
 	{ .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
 	{ .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index 4ecc4fd..fba1c75 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -82,8 +82,10 @@
 
 	if (!access(target_fname, F_OK)) {
 		syslog(LOG_INFO, "File: %s exists", target_fname);
-		if (!smsg->copy_flags & OVER_WRITE)
+		if (!(smsg->copy_flags & OVER_WRITE)) {
+			error = HV_ERROR_ALREADY_EXISTS;
 			goto done;
+		}
 	}
 
 	target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744);
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index 07b0b75..cb09d3f 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -1,13 +1,8 @@
-# liblockdep version
-LL_VERSION = 0
-LL_PATCHLEVEL = 0
-LL_EXTRAVERSION = 1
-
 # file format version
 FILE_VERSION = 1
 
 MAKEFLAGS += --no-print-directory
-
+LIBLOCKDEP_VERSION=$(shell make -sC ../../.. kernelversion)
 
 # Makefiles suck: This macro sets a default value of $(2) for the
 # variable named by $(1), unless the variable has been set by
@@ -98,7 +93,7 @@
 libdir_SQ = $(subst ','\'',$(libdir))
 bindir_SQ = $(subst ','\'',$(bindir))
 
-LIB_FILE = liblockdep.a liblockdep.so
+LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION)
 BIN_FILE = lockdep
 
 CONFIG_INCLUDES =
@@ -110,8 +105,6 @@
 
 export Q VERBOSE
 
-LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION)
-
 INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include $(CONFIG_INCLUDES)
 
 # Set compile option CFLAGS if not set elsewhere
@@ -146,7 +139,7 @@
 
 do_compile_shared_library =			\
 	($(print_shared_lib_compile)		\
-	$(CC) --shared $^ -o $@ -lpthread -ldl)
+	$(CC) --shared $^ -o $@ -lpthread -ldl -Wl,-soname='"$@"';$(shell ln -s $@ liblockdep.so))
 
 do_build_static_lib =				\
 	($(print_static_lib_build)		\
@@ -177,7 +170,7 @@
 
 all_cmd: $(CMD_TARGETS)
 
-liblockdep.so: $(PEVENT_LIB_OBJS)
+liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS)
 	$(Q)$(do_compile_shared_library)
 
 liblockdep.a: $(PEVENT_LIB_OBJS)
diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h
index d0f5d6e..c1552c2 100644
--- a/tools/lib/lockdep/uinclude/linux/lockdep.h
+++ b/tools/lib/lockdep/uinclude/linux/lockdep.h
@@ -10,6 +10,9 @@
 
 #define MAX_LOCK_DEPTH 2000UL
 
+#define asmlinkage
+#define __visible
+
 #include "../../../include/linux/lockdep.h"
 
 struct task_struct {
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 1587ea39..baec7d8 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -50,6 +50,18 @@
 			warning(fmt, ##__VA_ARGS__);	\
 	} while (0)
 
+#define do_warning_event(event, fmt, ...)			\
+	do {							\
+		if (!show_warning)				\
+			continue;				\
+								\
+		if (event)					\
+			warning("[%s:%s] " fmt, event->system,	\
+				event->name, ##__VA_ARGS__);	\
+		else						\
+			warning(fmt, ##__VA_ARGS__);		\
+	} while (0)
+
 static void init_input_buf(const char *buf, unsigned long long size)
 {
 	input_buf = buf;
@@ -1355,7 +1367,7 @@
 		}
 
 		if (!field->type) {
-			do_warning("%s: no type found", __func__);
+			do_warning_event(event, "%s: no type found", __func__);
 			goto fail;
 		}
 		field->name = last_token;
@@ -1402,7 +1414,7 @@
 				free_token(token);
 				type = read_token(&token);
 				if (type == EVENT_NONE) {
-					do_warning("failed to find token");
+					do_warning_event(event, "failed to find token");
 					goto fail;
 				}
 			}
@@ -1636,7 +1648,7 @@
 	right = alloc_arg();
 
 	if (!arg || !left || !right) {
-		do_warning("%s: not enough memory!", __func__);
+		do_warning_event(event, "%s: not enough memory!", __func__);
 		/* arg will be freed at out_free */
 		free_arg(left);
 		free_arg(right);
@@ -1686,7 +1698,7 @@
 
 	arg = alloc_arg();
 	if (!arg) {
-		do_warning("%s: not enough memory!", __func__);
+		do_warning_event(event, "%s: not enough memory!", __func__);
 		/* '*tok' is set to top->op.op.  No need to free. */
 		*tok = NULL;
 		return EVENT_ERROR;
@@ -1792,7 +1804,7 @@
 	if (arg->type == PRINT_OP && !arg->op.left) {
 		/* handle single op */
 		if (token[1]) {
-			do_warning("bad op token %s", token);
+			do_warning_event(event, "bad op token %s", token);
 			goto out_free;
 		}
 		switch (token[0]) {
@@ -1802,7 +1814,7 @@
 		case '-':
 			break;
 		default:
-			do_warning("bad op token %s", token);
+			do_warning_event(event, "bad op token %s", token);
 			goto out_free;
 
 		}
@@ -1888,7 +1900,7 @@
 			char *new_atom;
 
 			if (left->type != PRINT_ATOM) {
-				do_warning("bad pointer type");
+				do_warning_event(event, "bad pointer type");
 				goto out_free;
 			}
 			new_atom = realloc(left->atom.atom,
@@ -1930,7 +1942,7 @@
 		type = process_array(event, arg, tok);
 
 	} else {
-		do_warning("unknown op '%s'", token);
+		do_warning_event(event, "unknown op '%s'", token);
 		event->flags |= EVENT_FL_FAILED;
 		/* the arg is now the left side */
 		goto out_free;
@@ -1951,7 +1963,7 @@
 	return type;
 
 out_warn_free:
-	do_warning("%s: not enough memory!", __func__);
+	do_warning_event(event, "%s: not enough memory!", __func__);
 out_free:
 	free_token(token);
 	*tok = NULL;
@@ -2385,7 +2397,7 @@
 
 	field = alloc_arg();
 	if (!field) {
-		do_warning("%s: not enough memory!", __func__);
+		do_warning_event(event, "%s: not enough memory!", __func__);
 		goto out_free;
 	}
 
@@ -2438,7 +2450,7 @@
 
 	field = alloc_arg();
 	if (!field) {
-		do_warning("%s: not enough memory!", __func__);
+		do_warning_event(event, "%s: not enough memory!", __func__);
 		goto out_free;
 	}
 
@@ -2477,7 +2489,7 @@
 
 	field = alloc_arg();
 	if (!field) {
-		do_warning("%s: not enough memory!", __func__);
+		do_warning_event(event, "%s: not enough memory!", __func__);
 		goto out_free;
 	}
 
@@ -2492,7 +2504,7 @@
 
 	field = alloc_arg();
 	if (!field) {
-		do_warning("%s: not enough memory!", __func__);
+		do_warning_event(event, "%s: not enough memory!", __func__);
 		*tok = NULL;
 		return EVENT_ERROR;
 	}
@@ -2555,7 +2567,7 @@
 	free_token(token);
 	arg = alloc_arg();
 	if (!arg) {
-		do_warning("%s: not enough memory!", __func__);
+		do_warning_event(event, "%s: not enough memory!", __func__);
 		*tok = NULL;
 		return EVENT_ERROR;
 	}
@@ -2614,13 +2626,14 @@
 
 		/* prevous must be an atom */
 		if (arg->type != PRINT_ATOM) {
-			do_warning("previous needed to be PRINT_ATOM");
+			do_warning_event(event, "previous needed to be PRINT_ATOM");
 			goto out_free;
 		}
 
 		item_arg = alloc_arg();
 		if (!item_arg) {
-			do_warning("%s: not enough memory!", __func__);
+			do_warning_event(event, "%s: not enough memory!",
+					 __func__);
 			goto out_free;
 		}
 
@@ -2721,21 +2734,24 @@
 	for (i = 0; i < func->nr_args; i++) {
 		farg = alloc_arg();
 		if (!farg) {
-			do_warning("%s: not enough memory!", __func__);
+			do_warning_event(event, "%s: not enough memory!",
+					 __func__);
 			return EVENT_ERROR;
 		}
 
 		type = process_arg(event, farg, &token);
 		if (i < (func->nr_args - 1)) {
 			if (type != EVENT_DELIM || strcmp(token, ",") != 0) {
-				warning("Error: function '%s()' expects %d arguments but event %s only uses %d",
+				do_warning_event(event,
+					"Error: function '%s()' expects %d arguments but event %s only uses %d",
 					func->name, func->nr_args,
 					event->name, i + 1);
 				goto err;
 			}
 		} else {
 			if (type != EVENT_DELIM || strcmp(token, ")") != 0) {
-				warning("Error: function '%s()' only expects %d arguments but event %s has more",
+				do_warning_event(event,
+					"Error: function '%s()' only expects %d arguments but event %s has more",
 					func->name, func->nr_args, event->name);
 				goto err;
 			}
@@ -2792,7 +2808,7 @@
 		return process_func_handler(event, func, arg, tok);
 	}
 
-	do_warning("function %s not defined", token);
+	do_warning_event(event, "function %s not defined", token);
 	free_token(token);
 	return EVENT_ERROR;
 }
@@ -2878,7 +2894,7 @@
 
 	case EVENT_ERROR ... EVENT_NEWLINE:
 	default:
-		do_warning("unexpected type %d", type);
+		do_warning_event(event, "unexpected type %d", type);
 		return EVENT_ERROR;
 	}
 	*tok = token;
@@ -2901,7 +2917,8 @@
 
 		arg = alloc_arg();
 		if (!arg) {
-			do_warning("%s: not enough memory!", __func__);
+			do_warning_event(event, "%s: not enough memory!",
+					 __func__);
 			return -1;
 		}
 
@@ -3481,11 +3498,12 @@
 	return val;
 
 out_warning_op:
-	do_warning("%s: unknown op '%s'", __func__, arg->op.op);
+	do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op);
 	return 0;
 
 out_warning_field:
-	do_warning("%s: field %s not found", __func__, arg->field.name);
+	do_warning_event(event, "%s: field %s not found",
+			 __func__, arg->field.name);
 	return 0;
 }
 
@@ -3591,7 +3609,8 @@
 		}
 		str = malloc(len + 1);
 		if (!str) {
-			do_warning("%s: not enough memory!", __func__);
+			do_warning_event(event, "%s: not enough memory!",
+					 __func__);
 			return;
 		}
 		memcpy(str, data + field->offset, len);
@@ -3697,7 +3716,8 @@
 	return;
 
 out_warning_field:
-	do_warning("%s: field %s not found", __func__, arg->field.name);
+	do_warning_event(event, "%s: field %s not found",
+			 __func__, arg->field.name);
 }
 
 static unsigned long long
@@ -3742,14 +3762,16 @@
 			trace_seq_terminate(&str);
 			string = malloc(sizeof(*string));
 			if (!string) {
-				do_warning("%s(%d): malloc str", __func__, __LINE__);
+				do_warning_event(event, "%s(%d): malloc str",
+						 __func__, __LINE__);
 				goto out_free;
 			}
 			string->next = strings;
 			string->str = strdup(str.buffer);
 			if (!string->str) {
 				free(string);
-				do_warning("%s(%d): malloc str", __func__, __LINE__);
+				do_warning_event(event, "%s(%d): malloc str",
+						 __func__, __LINE__);
 				goto out_free;
 			}
 			args[i] = (uintptr_t)string->str;
@@ -3761,7 +3783,7 @@
 			 * Something went totally wrong, this is not
 			 * an input error, something in this code broke.
 			 */
-			do_warning("Unexpected end of arguments\n");
+			do_warning_event(event, "Unexpected end of arguments\n");
 			goto out_free;
 		}
 		farg = farg->next;
@@ -3811,12 +3833,12 @@
 	if (!field) {
 		field = pevent_find_field(event, "buf");
 		if (!field) {
-			do_warning("can't find buffer field for binary printk");
+			do_warning_event(event, "can't find buffer field for binary printk");
 			return NULL;
 		}
 		ip_field = pevent_find_field(event, "ip");
 		if (!ip_field) {
-			do_warning("can't find ip field for binary printk");
+			do_warning_event(event, "can't find ip field for binary printk");
 			return NULL;
 		}
 		pevent->bprint_buf_field = field;
@@ -3830,7 +3852,8 @@
 	 */
 	args = alloc_arg();
 	if (!args) {
-		do_warning("%s(%d): not enough memory!", __func__, __LINE__);
+		do_warning_event(event, "%s(%d): not enough memory!",
+				 __func__, __LINE__);
 		return NULL;
 	}
 	arg = args;
@@ -3896,7 +3919,7 @@
 				bptr += vsize;
 				arg = alloc_arg();
 				if (!arg) {
-					do_warning("%s(%d): not enough memory!",
+					do_warning_event(event, "%s(%d): not enough memory!",
 						   __func__, __LINE__);
 					goto out_free;
 				}
@@ -3919,7 +3942,7 @@
 			case 's':
 				arg = alloc_arg();
 				if (!arg) {
-					do_warning("%s(%d): not enough memory!",
+					do_warning_event(event, "%s(%d): not enough memory!",
 						   __func__, __LINE__);
 					goto out_free;
 				}
@@ -3959,7 +3982,7 @@
 	if (!field) {
 		field = pevent_find_field(event, "fmt");
 		if (!field) {
-			do_warning("can't find format field for binary printk");
+			do_warning_event(event, "can't find format field for binary printk");
 			return NULL;
 		}
 		pevent->bprint_fmt_field = field;
@@ -4003,8 +4026,8 @@
 		arg->field.field =
 			pevent_find_any_field(event, arg->field.name);
 		if (!arg->field.field) {
-			do_warning("%s: field %s not found",
-				   __func__, arg->field.name);
+			do_warning_event(event, "%s: field %s not found",
+					 __func__, arg->field.name);
 			return;
 		}
 	}
@@ -4176,7 +4199,7 @@
 			case '*':
 				/* The argument is the length. */
 				if (!arg) {
-					do_warning("no argument match");
+					do_warning_event(event, "no argument match");
 					event->flags |= EVENT_FL_FAILED;
 					goto out_failed;
 				}
@@ -4213,7 +4236,7 @@
 			case 'X':
 			case 'u':
 				if (!arg) {
-					do_warning("no argument match");
+					do_warning_event(event, "no argument match");
 					event->flags |= EVENT_FL_FAILED;
 					goto out_failed;
 				}
@@ -4223,7 +4246,7 @@
 
 				/* should never happen */
 				if (len > 31) {
-					do_warning("bad format!");
+					do_warning_event(event, "bad format!");
 					event->flags |= EVENT_FL_FAILED;
 					len = 31;
 				}
@@ -4290,13 +4313,13 @@
 						trace_seq_printf(s, format, (long long)val);
 					break;
 				default:
-					do_warning("bad count (%d)", ls);
+					do_warning_event(event, "bad count (%d)", ls);
 					event->flags |= EVENT_FL_FAILED;
 				}
 				break;
 			case 's':
 				if (!arg) {
-					do_warning("no matching argument");
+					do_warning_event(event, "no matching argument");
 					event->flags |= EVENT_FL_FAILED;
 					goto out_failed;
 				}
@@ -4306,7 +4329,7 @@
 
 				/* should never happen */
 				if (len > 31) {
-					do_warning("bad format!");
+					do_warning_event(event, "bad format!");
 					event->flags |= EVENT_FL_FAILED;
 					len = 31;
 				}
diff --git a/tools/net/bpf_exp.l b/tools/net/bpf_exp.l
index bf7be77..833a966 100644
--- a/tools/net/bpf_exp.l
+++ b/tools/net/bpf_exp.l
@@ -92,6 +92,7 @@
 "#"?("cpu")	{ return K_CPU; }
 "#"?("vlan_tci") { return K_VLANT; }
 "#"?("vlan_pr")	{ return K_VLANP; }
+"#"?("rand")	{ return K_RAND; }
 
 ":"		{ return ':'; }
 ","		{ return ','; }
diff --git a/tools/net/bpf_exp.y b/tools/net/bpf_exp.y
index d15efc9..e6306c5 100644
--- a/tools/net/bpf_exp.y
+++ b/tools/net/bpf_exp.y
@@ -56,7 +56,7 @@
 %token OP_LDXI
 
 %token K_PKT_LEN K_PROTO K_TYPE K_NLATTR K_NLATTR_NEST K_MARK K_QUEUE K_HATYPE
-%token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP K_POFF
+%token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP K_POFF K_RAND
 
 %token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#' '%'
 
@@ -164,6 +164,9 @@
 	| OP_LDB K_POFF {
 		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
 				   SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
+	| OP_LDB K_RAND {
+		bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
+				   SKF_AD_OFF + SKF_AD_RANDOM); }
 	;
 
 ldh
@@ -212,6 +215,9 @@
 	| OP_LDH K_POFF {
 		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
 				   SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
+	| OP_LDH K_RAND {
+		bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
+				   SKF_AD_OFF + SKF_AD_RANDOM); }
 	;
 
 ldi
@@ -265,6 +271,9 @@
 	| OP_LD K_POFF {
 		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
 				   SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
+	| OP_LD K_RAND {
+		bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
+				   SKF_AD_OFF + SKF_AD_RANDOM); }
 	| OP_LD 'M' '[' number ']' {
 		bpf_set_curr_instr(BPF_LD | BPF_MEM, 0, 0, $4); }
 	| OP_LD '[' 'x' '+' number ']' {
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index 7065cd6..4464ad7 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -48,6 +48,12 @@
 'mem'::
 	Memory access performance.
 
+'numa'::
+	NUMA scheduling and MM benchmarks.
+
+'futex'::
+	Futex stressing benchmarks.
+
 'all'::
 	All benchmark subsystems.
 
@@ -187,6 +193,22 @@
 --no-prefault::
 Show only the result without page faults before memset.
 
+SUITES FOR 'numa'
+~~~~~~~~~~~~~~~~~
+*mem*::
+Suite for evaluating NUMA workloads.
+
+SUITES FOR 'futex'
+~~~~~~~~~~~~~~~~~~
+*hash*::
+Suite for evaluating hash tables.
+
+*wake*::
+Suite for evaluating wake calls.
+
+*requeue*::
+Suite for evaluating requeue calls.
+
 SEE ALSO
 --------
 linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index cdd8d49..976b00c 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -87,7 +87,6 @@
 --realtime=<priority>::
 	Collect data with this RT SCHED_FIFO priority.
 
--s <symbol>::
 --sym-annotate=<symbol>::
         Annotate this symbol.
 
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 50d875d..e969233 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -192,13 +192,13 @@
 export PERL_PATH
 
 $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
-	$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
+	$(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l
 
 $(OUTPUT)util/parse-events-bison.c: util/parse-events.y
 	$(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
 
 $(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
-	$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
+	$(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l
 
 $(OUTPUT)util/pmu-bison.c: util/pmu.y
 	$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 97d86d8..ebfa163 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -1593,6 +1593,10 @@
 	p->data_rand_walk		= true;
 	p->nr_loops			= -1;
 	p->init_random			= true;
+	p->mb_global_str		= "1";
+	p->nr_proc			= 1;
+	p->nr_threads			= 1;
+	p->nr_secs			= 5;
 	p->run_all			= argc == 1;
 }
 
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8b0e1c9..65a151e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -174,13 +174,20 @@
 
 static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
 {
-	memset(evsel->priv, 0, sizeof(struct perf_stat));
+	int i;
+	struct perf_stat *ps = evsel->priv;
+
+	for (i = 0; i < 3; i++)
+		init_stats(&ps->res_stats[i]);
 }
 
 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
 {
 	evsel->priv = zalloc(sizeof(struct perf_stat));
-	return evsel->priv == NULL ? -ENOMEM : 0;
+	if (evsel == NULL)
+		return -ENOMEM;
+	perf_evsel__reset_stat_priv(evsel);
+	return 0;
 }
 
 static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index c234182..ee21fa9 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -65,10 +65,9 @@
   ifdef LIBDW_DIR
     LIBDW_CFLAGS  := -I$(LIBDW_DIR)/include
     LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
-
-    FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
-    FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
   endif
+  FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
+  FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
 endif
 
 # include ARCH specific config
@@ -278,6 +277,8 @@
       NO_LIBELF := 1
       NO_DWARF := 1
       NO_DEMANGLE := 1
+      NO_LIBUNWIND := 1
+      NO_LIBDW_DWARF_UNWIND := 1
     else
       msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
     endif
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 653a8fe..bfb1869 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -504,6 +504,7 @@
 		if (ret < 0) {
 			if (!excl_kernel) {
 				excl_kernel = true;
+				perf_evlist__set_maps(evlist, NULL, NULL);
 				perf_evlist__delete(evlist);
 				evlist = NULL;
 				continue;
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index df02386..5627621 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -985,7 +985,7 @@
 
 #if _ELFUTILS_PREREQ(0, 142)
 	/* Get the call frame information from this dwarf */
-	pf->cfi = dwarf_getcfi(dbg->dbg);
+	pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg));
 #endif
 
 	off = 0;
@@ -1441,13 +1441,15 @@
 			      void *data)
 {
 	struct line_finder *lf = data;
+	int err;
 
 	if ((strtailcmp(fname, lf->fname) != 0) ||
 	    (lf->lno_s > lineno || lf->lno_e < lineno))
 		return 0;
 
-	if (line_range_add_line(fname, lineno, lf->lr) < 0)
-		return -EINVAL;
+	err = line_range_add_line(fname, lineno, lf->lr);
+	if (err < 0 && err != -EEXIST)
+		return err;
 
 	return 0;
 }
@@ -1473,14 +1475,15 @@
 
 static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
 {
-	find_line_range_by_line(in_die, data);
+	int ret = find_line_range_by_line(in_die, data);
 
 	/*
 	 * We have to check all instances of inlined function, because
 	 * some execution paths can be optimized out depends on the
-	 * function argument of instances
+	 * function argument of instances. However, if an error occurs,
+	 * it should be handled by the caller.
 	 */
-	return 0;
+	return ret < 0 ? ret : 0;
 }
 
 /* Search function definition from function name */